Skip to content

Commit 49c4429

Browse files
author
danheeks
committed
I got HeeksPython to do "import autoexec" on start up.
I added functions to add menus and windows to HeeksPython. I added an example autoexec.py
1 parent c284c66 commit 49c4429

File tree

5 files changed

+241
-12
lines changed

5 files changed

+241
-12
lines changed

autoexec.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import HeeksPython as cad
2+
test_menu = cad.addmenu('test menu')
3+
cad.add_menu_item(test_menu, 'item 1', 'import HeeksPython as cad; cad.addtext("item 1")', 'test')
4+
cad.add_menu_item(test_menu, 'item 2', 'import platform\nif platform.system() == "Windows":\n execfile("test2.py")\nelse:\n execfile("linuxtest.py")', 'test')
5+
cad.add_menu_item(test_menu, 'item 2', 'import HeeksPython as cad; cad.addtext("item 1")', 'test')
6+
7+
import wx
8+
9+
class CAMWindow(wx.ScrolledWindow):
10+
def __init__(self, parent):
11+
wx.ScrolledWindow.__init__(self, parent, name = 'CAM')
12+
tree = wx.TreeCtrl(self)
13+
tree.SetSize(wx.Size(200, 300))
14+
program = tree.AddRoot("Program")
15+
16+
# Use some sizers to see layout options
17+
self.sizer = wx.BoxSizer(wx.VERTICAL)
18+
self.sizer.Add(tree, 1, wx.EXPAND)
19+
20+
#Layout sizers
21+
self.SetSizer(self.sizer)
22+
self.SetAutoLayout(1)
23+
self.sizer.Fit(self)
24+
self.Show()
25+
26+
hwnd = cad.get_frame_hwnd()
27+
frame = wx.Window_FromHWND(None, hwnd)
28+
window = CAMWindow(frame)
29+
cad.add_window(window.GetHandle())
30+
31+
from PyQt4 import QtGui
32+
33+
app = QtGui.QApplication([])
34+
widget = QtGui.QWidget()
35+
widget.setWindowTitle('CAM2')
36+
tree = QtGui.QTreeWidget(widget)
37+
tree_item = QtGui.QTreeWidgetItem(tree)
38+
tree_item.setText(0, "Program")
39+
tree.addTopLevelItem(tree_item)
40+
cad.add_window(widget.winId())
41+
widget.show()
42+

bitmaps/test.png

5.2 KB
Loading

src/HeeksPython.cpp

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// HeeksCNC.cpp
1+
// HeeksPython.cpp
22
/*
33
* Copyright (c) 2009, Dan Heeks
44
* This program is released under the BSD license. See the file COPYING for
@@ -15,6 +15,18 @@
1515
#include "ConsoleCanvas.h"
1616
#include "PythonConfig.h"
1717

18+
19+
#ifdef _DEBUG
20+
#undef _DEBUG
21+
#include <Python.h>
22+
#include <wx/wxPython/wxPython.h>
23+
#define _DEBUG
24+
#else
25+
#include <Python.h>
26+
#include <wx/wxPython/wxPython.h>
27+
#endif
28+
29+
1830
CHeeksCADInterface* heeksCAD = NULL;
1931

2032
CHeeksPythonApp *theApp;
@@ -56,6 +68,30 @@ void OnUpdateConsole( wxUpdateUIEvent& event )
5668
event.Check(aui_manager->GetPane(theApp->m_console).IsShown());
5769
}
5870

71+
void RunAutoExecPyFile()
72+
{
73+
// As always, first grab the GIL
74+
wxPyBlock_t blocked = wxPyBeginBlockThreads();
75+
76+
// Now make a dictionary to serve as the global namespace when the code is
77+
// executed. Put a reference to the builtins module in it. (Yes, the
78+
// names are supposed to be different, I don't know why...)
79+
PyObject* globals = PyDict_New();
80+
PyObject* builtins = PyImport_ImportModule("__builtin__");
81+
PyDict_SetItemString(globals, "__builtins__", builtins);
82+
Py_DECREF(builtins);
83+
84+
// Execute the code "import autoexec"
85+
PyObject* result = PyRun_String("import autoexec", Py_file_input, globals, globals);
86+
87+
// Release the python objects we still have
88+
if (result)Py_DECREF(result);
89+
else PyErr_Print();
90+
Py_DECREF(globals);
91+
92+
// Finally, after all Python stuff is done, release the GIL
93+
wxPyEndBlockThreads(blocked);
94+
}
5995

6096
void CHeeksPythonApp::OnStartUp(CHeeksCADInterface* h, const wxString& dll_path)
6197
{
@@ -75,7 +111,6 @@ void CHeeksPythonApp::OnStartUp(CHeeksCADInterface* h, const wxString& dll_path)
75111
m_console->InitP();
76112
aui_manager->AddPane(m_console, wxAuiPaneInfo().Name(_T("Console")).Caption(_T("Console")).Bottom().BestSize(wxSize(600, 200)));
77113

78-
79114
bool console_visible;
80115
PythonConfig config;
81116

@@ -88,12 +123,13 @@ void CHeeksPythonApp::OnStartUp(CHeeksCADInterface* h, const wxString& dll_path)
88123
heeksCAD->AddMenuItem(view_menu, _T("Console"), wxBitmap(), OnConsole, OnUpdateConsole,0,true);
89124
heeksCAD->RegisterHideableWindow(m_console);
90125

91-
// add object reading functions
92-
//? heeksCAD->RegisterReadXMLfunction("Program", CProgram::ReadFromXMLElement);
126+
// run autoexec.py
127+
RunAutoExecPyFile();
93128

94129
heeksCAD->SetDefaultLayout(wxString(_T("layout2|name=ToolBar;caption=General Tools;state=2108156;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=279;besth=31;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=GeomBar;caption=Geometry Tools;state=2108156;dir=1;layer=10;row=0;pos=290;prop=100000;bestw=248;besth=31;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=SolidBar;caption=Solid Tools;state=2108156;dir=1;layer=10;row=1;pos=0;prop=100000;bestw=341;besth=31;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=970;floaty=297;floatw=296;floath=57|name=ViewingBar;caption=Viewing Tools;state=2108156;dir=1;layer=10;row=1;pos=352;prop=100000;bestw=248;besth=31;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=TransformBar;caption=Transformation Tools;state=2108156;dir=1;layer=10;row=1;pos=611;prop=100000;bestw=217;besth=31;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=Graphics;caption=Graphics;state=768;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=800;besth=600;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=Objects;caption=Objects;state=2099196;dir=4;layer=1;row=0;pos=0;prop=100000;bestw=300;besth=400;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=Options;caption=Options;state=2099196;dir=4;layer=1;row=0;pos=1;prop=100000;bestw=300;besth=200;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=Input;caption=Input;state=2099196;dir=4;layer=1;row=0;pos=2;prop=100000;bestw=300;besth=200;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=Properties;caption=Properties;state=2099196;dir=4;layer=1;row=0;pos=3;prop=100000;bestw=300;besth=200;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=MachiningBar;caption=Machining tools;state=2108156;dir=1;layer=10;row=0;pos=549;prop=100000;bestw=279;besth=31;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=Program;caption=Program;state=2099196;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=600;besth=200;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=Output;caption=Output;state=2099196;dir=3;layer=0;row=0;pos=1;prop=100000;bestw=600;besth=200;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(5,0,0)=504|dock_size(4,1,0)=234|dock_size(1,10,0)=33|dock_size(1,10,1)=33|dock_size(3,0,0)=219|")));
95130
}
96131

132+
97133
void CHeeksPythonApp::OnNewOrOpen(bool open, int res)
98134
{
99135

src/HeeksPython.vcproj

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
2121
IntermediateDirectory="$(ConfigurationName)"
2222
ConfigurationType="2"
23-
CharacterSet="2"
23+
CharacterSet="1"
2424
>
2525
<Tool
2626
Name="VCPreBuildEventTool"
@@ -40,7 +40,7 @@
4040
<Tool
4141
Name="VCCLCompilerTool"
4242
Optimization="0"
43-
AdditionalIncludeDirectories="..\..\;&quot;$(PYTHON_INCLUDE)&quot;;$(HEEKSCADPATH);&quot;$(WXWIN)\lib\vc_dll\mswud&quot;;&quot;$(WXWIN)\include&quot;;&quot;$(WXWIN)\wxPython\include&quot;"
43+
AdditionalIncludeDirectories=".\;&quot;$(PYTHON25_INCLUDE)&quot;;$(HEEKSCADPATH);&quot;$(WXWIN)\lib\vc_dll\mswud&quot;;&quot;$(WXWIN)\include&quot;;&quot;$(WXWIN)\wxPython\include&quot;"
4444
PreprocessorDefinitions="WIN32;_DEBUG;__WXMSW__;__WXDEBUG__;_WINDOWS;_UNICODE;UNICODE;NOPCH;WNT;_CRT_SECURE_NO_WARNINGS;WXUSINGDLL;HEEKSCAD;STRICT"
4545
MinimalRebuild="true"
4646
BasicRuntimeChecks="3"
@@ -59,8 +59,8 @@
5959
/>
6060
<Tool
6161
Name="VCLinkerTool"
62-
AdditionalDependencies="wxbase28ud.lib wxmsw28ud_core.lib wxmsw28ud_aui.lib wxmsw28ud_gl.lib $(PYTHON_LIB)"
63-
OutputFile="$(OutDir)\$(ProjectName).pyd"
62+
AdditionalDependencies="wxbase28ud.lib wxmsw28ud_core.lib wxmsw28ud_aui.lib wxmsw28ud_gl.lib $(PYTHON25_LIB)"
63+
OutputFile="..\$(ProjectName).pyd"
6464
AdditionalLibraryDirectories="&quot;$(WXWIN)\lib\vc_dll&quot;"
6565
GenerateDebugInformation="true"
6666
TargetMachine="1"
@@ -114,7 +114,7 @@
114114
Name="VCCLCompilerTool"
115115
Optimization="2"
116116
EnableIntrinsicFunctions="true"
117-
AdditionalIncludeDirectories="..\..\;&quot;$(PYTHON_INCLUDE)&quot;;&quot;$(HEEKSCADPATH)&quot;;&quot;$(WXWIN)\lib\vc_dll\mswu&quot;;&quot;$(WXWIN)\include&quot;;&quot;$(WXWIN)\wxPython\include&quot;"
117+
AdditionalIncludeDirectories=".\;&quot;$(PYTHON_INCLUDE)&quot;;&quot;$(HEEKSCADPATH)&quot;;&quot;$(WXWIN)\lib\vc_dll\mswu&quot;;&quot;$(WXWIN)\include&quot;;&quot;$(WXWIN)\wxPython\include&quot;"
118118
PreprocessorDefinitions="WIN32;__WXMSW__;_WINDOWS;_UNICODE;UNICODE;NOPCH;WNT;_CRT_SECURE_NO_WARNINGS;WXUSINGDLL;HEEKSCAD;STRICT"
119119
RuntimeLibrary="2"
120120
EnableFunctionLevelLinking="true"
@@ -187,6 +187,10 @@
187187
RelativePath=".\PythonInterface.cpp"
188188
>
189189
</File>
190+
<File
191+
RelativePath="..\..\HeeksCAD\interface\ToolImage.cpp"
192+
>
193+
</File>
190194
</Filter>
191195
<Filter
192196
Name="Header Files"
@@ -217,6 +221,10 @@
217221
RelativePath=".\stdafx.h"
218222
>
219223
</File>
224+
<File
225+
RelativePath="..\..\HeeksCAD\interface\ToolImage.h"
226+
>
227+
</File>
220228
</Filter>
221229
<Filter
222230
Name="Resource Files"

src/PythonInterface.cpp

Lines changed: 146 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// HeeksPython.cpp
2-
#include <Python.h>
32
#include "stdafx.h"
43

54
#ifdef WIN32
@@ -10,16 +9,24 @@
109
#include "Interface.h"
1110
#include "interface/HeeksCADInterface.h"
1211
#include "interface/HeeksObj.h"
12+
#include "interface/ToolImage.h"
1313
#include "ConsoleCanvas.h"
14+
#include "PythonConfig.h"
1415

1516

1617

1718
//#include "src/PointDrawing.h"
1819
#include <set>
1920

20-
21-
21+
#ifdef _DEBUG
22+
#undef _DEBUG
23+
#include <Python.h>
24+
#include <wx/wxPython/wxPython.h>
25+
#define _DEBUG
26+
#else
27+
#include <Python.h>
2228
#include <wx/wxPython/wxPython.h>
29+
#endif
2330

2431
extern CHeeksCADInterface *heeksCAD;
2532
extern CHeeksPythonApp *theApp;
@@ -733,7 +740,139 @@ static PyObject* NewText(PyObject* self, PyObject* args)
733740
}
734741

735742

743+
static PyObject* AddMenu(PyObject* self, PyObject* args)
744+
{
745+
const char *menu_name;
746+
if (!PyArg_ParseTuple(args, "s", &menu_name)) return NULL;
747+
748+
wxFrame* frame = heeksCAD->GetMainFrame();
749+
wxMenu *newMenu = new wxMenu;
750+
frame->GetMenuBar()->Append(newMenu, _U(menu_name));
751+
752+
return PyInt_FromSize_t((unsigned int)newMenu);
753+
}
754+
755+
static PyObject* GetFrameHwnd(PyObject* self, PyObject* args)
756+
{
757+
wxFrame* frame = heeksCAD->GetMainFrame();
758+
return PyInt_FromSize_t((unsigned int)(frame->GetHWND()));
759+
}
760+
761+
std::map<int, wxString> menu_item_map;
762+
763+
void OnMenuItem(wxCommandEvent &event)
764+
{
765+
std::map<int, wxString>::iterator FindIt = menu_item_map.find(event.GetId());
766+
if(FindIt != menu_item_map.end())
767+
{
768+
// As always, first grab the GIL
769+
wxPyBlock_t blocked = wxPyBeginBlockThreads();
770+
771+
// Now make a dictionary to serve as the global namespace when the code is
772+
// executed. Put a reference to the builtins module in it. (Yes, the
773+
// names are supposed to be different, I don't know why...)
774+
PyObject* globals = PyDict_New();
775+
PyObject* builtins = PyImport_ImportModule("__builtin__");
776+
PyDict_SetItemString(globals, "__builtins__", builtins);
777+
Py_DECREF(builtins);
778+
779+
// Execute the python code
780+
std::string _str((const char *) FindIt->second.mb_str(wxConvUTF8));
781+
PyObject* result = PyRun_String(_str.c_str(), Py_file_input, globals, globals);
782+
783+
// Release the python objects we still have
784+
if (result)Py_DECREF(result);
785+
else PyErr_Print();
786+
Py_DECREF(globals);
787+
788+
// Finally, after all Python stuff is done, release the GIL
789+
wxPyEndBlockThreads(blocked);
790+
}
791+
}
792+
793+
static PyObject* AddMenuItem(PyObject* self, PyObject* args)
794+
{
795+
long int_menu;
796+
const char *title;
797+
const char *python_script;
798+
const char *bitmap_path;
799+
if (!PyArg_ParseTuple(args, "lsss", &int_menu, &title, &python_script, &bitmap_path)) return NULL;
800+
801+
wxMenu *menu = (wxMenu*)int_menu;
802+
803+
int id = heeksCAD->AddMenuItem(menu, wxString(_U(title)), ToolImage(_U(bitmap_path)), OnMenuItem, NULL);
804+
805+
menu_item_map.insert(std::make_pair(id, wxString(_U(python_script))));
806+
807+
PyObject *pValue = Py_None;
808+
Py_INCREF(pValue);
809+
return pValue;
810+
}
811+
812+
static std::list<wxWindow*> new_windows;
813+
814+
std::map<int, wxWindow*> window_map;
815+
816+
void OnWindow( wxCommandEvent& event )
817+
{
818+
std::map<int, wxWindow*>::iterator FindIt = window_map.find(event.GetId());
819+
if(FindIt != window_map.end())
820+
{
821+
wxWindow* window = FindIt->second;
822+
wxAuiManager* aui_manager = heeksCAD->GetAuiManager();
823+
wxAuiPaneInfo& pane_info = aui_manager->GetPane(window);
824+
if(pane_info.IsOk()){
825+
pane_info.Show(event.IsChecked());
826+
aui_manager->Update();
827+
}
828+
}
829+
}
830+
831+
void OnUpdateWindow( wxUpdateUIEvent& event )
832+
{
833+
std::map<int, wxWindow*>::iterator FindIt = window_map.find(event.GetId());
834+
if(FindIt != window_map.end())
835+
{
836+
wxWindow* window = FindIt->second;
837+
wxAuiManager* aui_manager = heeksCAD->GetAuiManager();
838+
event.Check(aui_manager->GetPane(window).IsShown());
839+
}
840+
}
841+
842+
static PyObject* AddWindow(PyObject* self, PyObject* args)
843+
{
844+
long int_window;
845+
if (!PyArg_ParseTuple(args, "l", &int_window)) return NULL;
846+
847+
wxFrame* frame = heeksCAD->GetMainFrame();
848+
wxAuiManager* aui_manager = heeksCAD->GetAuiManager();
849+
850+
wxWindow * new_window = new wxWindow();
851+
new_window->SetHWND((WXHWND)int_window);
852+
new_window->AdoptAttributesFromHWND();
853+
new_window->Reparent(frame);
854+
855+
wxString label = new_window->GetLabel();
856+
857+
new_windows.push_back(new_window);
858+
859+
aui_manager->AddPane(new_window, wxAuiPaneInfo().Name(label).Caption(label).Bottom().BestSize(wxSize(600, 200)));
860+
861+
bool window_visible;
862+
wxString config_name = label + wxString(_T("Visible"));
863+
PythonConfig config;
864+
865+
config.Read(config_name, &window_visible);
866+
867+
aui_manager->GetPane(new_window).Show(window_visible);
868+
869+
wxMenu* view_menu = heeksCAD->GetWindowMenu();
870+
int id = heeksCAD->AddMenuItem(view_menu, label, wxBitmap(), OnWindow, OnUpdateWindow,0,true);
871+
heeksCAD->RegisterHideableWindow(new_window);
872+
window_map.insert(std::make_pair(id, new_window));
736873

874+
return PyInt_FromLong(new_window->GetId());
875+
}
737876

738877
static PyObject* DXFImport(PyObject* self, PyObject* args)
739878
{
@@ -788,6 +927,10 @@ static PyMethodDef HeeksPythonMethods[] = {
788927
{"getpoint" , GetPoint3d, METH_VARARGS, "getpoint()"},
789928
{"addtext", NewText, METH_VARARGS , "addtext('string')"},
790929
{"importdxf", DXFImport, METH_VARARGS , "importdxf('/filepath/filename.dxf')"},
930+
{"addmenu", AddMenu, METH_VARARGS , "menu = addmenu('string')"},
931+
{"add_menu_item", AddMenuItem, METH_VARARGS , "add_menu_item(menu, 'string', 'python_script')"},
932+
{"add_window", AddWindow, METH_VARARGS , "add_window(hwnd)"},
933+
{"get_frame_hwnd", GetFrameHwnd, METH_VARARGS , "hwnd = get_frame_hwnd()"},
791934
{NULL, NULL, 0, NULL}
792935
};
793936

0 commit comments

Comments
 (0)