Re: How to access wxglade generated widgets from generic python code.
"Brendan Simon (eTRIX)" <[email protected]>
| Newsgroups | gmane.comp.python.wxglade |
|---|---|
| Organization | eTRIX pty ltd |
| Message-ID | <[email protected]> |
Hi Dennis,
This might help for part or your question.
In my projects I try to avoid modifying the wxGlade generated code at
all (I'm just paranoid about it being nuked). It also keeps the logic
separate from the GUI (to some extent).
I derive my own classes from the wxGlade generated classes. All my
processing and actions take place in my own derived classes, and leave
the wxGlade generated classes to basically do the layout and render things.
Any widget you want to access (set or get via methods or properties)
need to have the "attribute" checkbox checked in wxGlade, so that it is
exposed.
For event handling, you either have to:
(a) expose the widget as an attribute and do the binding yourself in
your derived class.
or
(b) specify on event handler in wxGlade (e.g. `on_my_button_click` for a
button called `my_button`). wxGlade will generate a default handler
which prints something to stdout. You just define your own method (with
same name as the handler. e.g. `on_my_button_click()` in your own
derived class that will override the default handler.
I prefer option (b) as there is less boiler plate to write.
Brendan.
------------------------------------------------------------------------
On 9/4/19 9:35 am, Dennis DeBerry via wxGlade-general wrote:
> I am writing a program to add records to a sqlite database. I know I
> could use something like sqlAlchemy, but I want to write this myself
> just to get some practice.
> I have used wxglade to construct the GUI elements of the program and
> saved the code generated to a python file.
> I then did some command line python programming and added to access a
> sqlite database file ( no network programming. The database will
> always be on the user`s local hard drive)and added it to the code
> generated by wxglade.
> The problem is that I am trying to access the wxglade generated
> listbox from my command line code and I cannot figure out how. The
> wxglade docs says NOT to edit any code between the "# begin wxGlade"
> and "# end wxGlade" comments. That way if you want to go back to
> wxglade and change the way a widget looks or acts or add something to
> it wxglade will only affect program lines between those comment.
>
> I am not AT ALL finished with this program within wxglade so I DO NOT
> want to edit the glade generated code, BUT I am having a real problem
> getting the listbox to be populated with the string list that is
> generated in my command line code. That list is in the variable
> "tablenames" in the code below. For some reason python will not let me
> access that widget and as I said I do not want to change the wxglade
> generated code just yet.
>
> Here is the code that I have used.
>
>
> import wx
> import wx.grid
> import os,sys
> import sqlite3 as sq
> from sqlite3 import Error
>
> filetypewildcard = "Sqlite Database (*.db)|*.db|""sqz
> files(*.sqz)|*.sqz|""sqlfiles(*.sql)|*.sql"
> currentDirectory = os.getcwd()
>
> def create_connection(db_file):
> """ create a database connection to a SQLite database """
> # First string in a sqlite database file. This identies the file
> # as a sqlite database file "SQLite format 3"
> choice = 0
> tablenames = []
> databasefileheader = "SQLite format 3"
> foreignkeyexist = "PRAGMA foreign_key_list"
> foreignkeyon = "PRAGMA foreign_key = 'ON'"
> try:
> conn = sq.connect(db_file)
> c = conn.cursor()
> conn.text_factory = bytes
> c.execute(foreignkeyon)
> print(sq.version)
> # get the tables in the database
> tables = c.execute('SELECT name FROM sqlite_master WHERE type
> = "table"')
> row = c.execute("SELECT name FROM sqlite_master WHERE type =
> 'table'")
>
> for line in row:
> #How to get the table name into the listbox and dynamically adjust
> #the number of items in the listbox.
>
> choice +=1
> print(str(choice) + ")" + " " + line[0])
> tablenames += [line[0]]
> list1 = TableList(None,wx.ID_ANY,choices = tablenames)
> list1.setchoicelist(tablenames)
> displaytables = TableChoice(None,wx.ID_ANY)
> #TableList.chocies = tablenames
> displaytables.Show(True)
> # listtables.setchoicelist(tablenames)
> #tablechoice = raw_input("Enter the number of the table that
> you want to edit ")
> #tableindex = int(tablechoice)
> #chosentable = tablenames[tableindex-1]
> # print chosentable
>
> # Determine if table has foreign key or BLOB column and exclude them
> from listing
> # of columns to be displayed
> tablestmt = "PRAGMA table_info(" + chosentable + ")"
> tablecolumns = c.execute(tablestmt )
> for index in tablecolumns:
> if not index[5]:
> if "BLOB" not in index[2]:
> print index
>
> except Error as e:
> print(e)
> finally:
> conn.close()
>
>
>
> # begin wxGlade: dependencies
> # end wxGlade
>
> # begin wxGlade: extracode
> # end wxGlade
>
>
> # begin wxGlade: dependencies
> # end wxGlade
>
> # begin wxGlade: extracode
> # end wxGlade
>
>
> class ActorList(wx.Frame):
> def __init__(self, *args, **kwds):
> # begin wxGlade: ActorList.__init__
> kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
> wx.Frame.__init__(self, *args, **kwds)
> self.SetSize((800, 600))
>
> # Menu Bar
> self.ActiorListMenu = wx.MenuBar()
> wxglade_tmp_menu = wx.Menu()
> item = wxglade_tmp_menu.Append(wx.ID_ANY, "Open Database
> File", "")
> self.Bind(wx.EVT_MENU, self.OpenFile, id=item.GetId())
> wxglade_tmp_menu.Append(wx.ID_ANY, "Save Database", "")
> wxglade_tmp_menu.Append(wx.ID_ANY, "Close Database", "")
> item = wxglade_tmp_menu.Append(wx.ID_ANY, "Exit", "")
> self.Bind(wx.EVT_MENU, self.Quit, id=item.GetId())
> self.ActiorListMenu.Append(wxglade_tmp_menu, "File")
> wxglade_tmp_menu = wx.Menu()
> item = wxglade_tmp_menu.Append(wx.ID_ANY, "Help", "")
> self.Bind(wx.EVT_MENU, self.DisplayHelpFrame, id=item.GetId())
> item = wxglade_tmp_menu.Append(wx.ID_ANY, "About", "")
> self.Bind(wx.EVT_MENU, self.DisplauSplashScreen, id=item.GetId())
> self.ActiorListMenu.Append(wxglade_tmp_menu, "Help")
> self.SetMenuBar(self.ActiorListMenu)
> # Menu Bar end
> self.frame_statusbar = self.CreateStatusBar(2)
> self.panel_1 = wx.Panel(self, wx.ID_ANY)
> self.panel_2 = wx.ScrolledWindow(self.panel_1, wx.ID_ANY,
> style=wx.BORDER_RAISED)
> self.displaygrid = wx.grid.Grid(self.panel_2, wx.ID_ANY,
> size=(1, 1))
> self.button_3 = wx.Button(self.panel_1, wx.ID_ANY, "CLEAR")
> self.button_1 = wx.Button(self.panel_1, wx.ID_ANY, "ADD")
> self.button_2 = wx.Button(self.panel_1, wx.ID_ANY, "OPEN")
>
> self.__set_properties()
> self.__do_layout()
>
> self.Bind(wx.EVT_BUTTON, self.ClearForm, self.button_3)
> self.Bind(wx.EVT_BUTTON, self.AddData, self.button_1)
> self.Bind(wx.EVT_BUTTON, self.OpenFile, self.button_2)
> # end wxGlade
>
> def __set_properties(self):
> # begin wxGlade: ActorList.__set_properties
> self.SetTitle("frame")
> self.frame_statusbar.SetStatusWidths([-1, 0])
>
> # statusbar fields
> frame_statusbar_fields = ["frame_statusbar", ""]
> for i in range(len(frame_statusbar_fields)):
>
> self.frame_statusbar.SetStatusText(frame_statusbar_fields[i], i)
> self.displaygrid.CreateGrid(2, 1)
> self.displaygrid.SetFocus()
> self.panel_2.SetScrollRate(10, 10)
> self.button_1.SetToolTipString("Add data to table")
> self.button_2.SetToolTipString("Open a database table")
> # end wxGlade
>
> def __do_layout(self):
> # begin wxGlade: ActorList.__do_layout
> sizer_1 = wx.BoxSizer(wx.VERTICAL)
> sizer_2 = wx.BoxSizer(wx.VERTICAL)
> sizer_3 = wx.BoxSizer(wx.HORIZONTAL)
> sizer_4 = wx.BoxSizer(wx.VERTICAL)
> sizer_4.Add(self.displaygrid, 1, wx.ALIGN_CENTER | wx.EXPAND, 0)
> self.panel_2.SetSizer(sizer_4)
> sizer_2.Add(self.panel_2, 1, wx.EXPAND, 0)
> sizer_3.Add(self.button_3, 1, wx.EXPAND, 0)
> sizer_3.Add(self.button_1, 1, wx.EXPAND, 0)
> sizer_3.Add(self.button_2, 1, wx.EXPAND, 0)
> sizer_2.Add(sizer_3, 1, wx.ALIGN_BOTTOM | wx.ALL | wx.EXPAND |
> wx.FIXED_MINSIZE | wx.SHAPED, 10)
> self.panel_1.SetSizer(sizer_2)
> sizer_1.Add(self.panel_1, 3, wx.ALL | wx.EXPAND, 0)
> self.SetSizer(sizer_1)
> self.Layout()
> # end wxGlade
>
> def OpenFile(self, event): # wxGlade: ActorList.<event_handler>
> dlg = wx.FileDialog(self, message="Choose a file",
> defaultDir=currentDirectory, defaultFile="",
> wildcard=filetypewildcard, style=wx.OPEN | wx.FD_CHANGE_DIR)
> if dlg.ShowModal() == wx.ID_OK:
> filename = dlg.GetPath()
> self.frame_statusbar.SetStatusText(filename)
> create_connection(filename)
> # for path in db_file:
> # print path
> dlg.Destroy()
> #print("Event handler 'OpenFile' not implemented!")
> #event.Skip()
>
>
> def Quit(self, event): # wxGlade: ActorList.<event_handler>
> print("Event handler 'Quit' not implemented!")
> event.Skip()
>
> def DisplayHelpFrame(self, event): # wxGlade:
> ActorList.<event_handler>
> print("Event handler 'DisplayHelpFrame' not implemented!")
> event.Skip()
>
> def DisplauSplashScreen(self, event): # wxGlade:
> ActorList.<event_handler>
> print("Event handler 'DisplauSplashScreen' not implemented!")
> event.Skip()
>
> def ClearForm(self, event): # wxGlade: ActorList.<event_handler>
> print("Event handler 'ClearForm' not implemented!")
> event.Skip()
>
> def AddData(self, event): # wxGlade: ActorList.<event_handler>
> print("Event handler 'AddData' not implemented!")
> event.Skip()
>
> # end of class ActorList
>
> class OpenDialog(wx.Dialog):
> def __init__(self, *args, **kwds):
> # Content of this block not found. Did you rename this class?
> pass
>
> def __set_properties(self):
> # Content of this block not found. Did you rename this class?
> pass
>
> def __do_layout(self):
> # Content of this block not found. Did you rename this class?
> pass
>
> # end of class OpenDialog
>
> class SaveDialog(wx.Dialog):
> def __init__(self, *args, **kwds):
> # Content of this block not found. Did you rename this class?
> pass
>
> def __set_properties(self):
> # Content of this block not found. Did you rename this class?
> pass
>
> def __do_layout(self):
> # Content of this block not found. Did you rename this class?
> pass
>
> # end of class SaveDialog
>
> class MyDialog(wx.Dialog):
> def __init__(self, *args, **kwds):
> # Content of this block not found. Did you rename this class?
> pass
>
> def __set_properties(self):
> # Content of this block not found. Did you rename this class?
> pass
>
> def __do_layout(self):
> # Content of this block not found. Did you rename this class?
> pass
>
> # end of class MyDialog
>
>
> class TableChoice(wx.Dialog):
> def __init__(self, *args, **kwds):
> # begin wxGlade: TableChoice.__init__
> kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_DIALOG_STYLE
> | wx.MAXIMIZE_BOX | wx.MINIMIZE_BOX | wx.RESIZE_BORDER
> wx.Dialog.__init__(self, *args, **kwds)
> self.panel_3 = wx.Panel(self, wx.ID_ANY)
> self.listtables = TableList(self.panel_3, wx.ID_ANY,
> choices=[""], style=wx.LB_NEEDED_SB | wx.LB_SINGLE | wx.LB_SORT)
>
> self.__set_properties()
> self.__do_layout()
>
> self.Bind(wx.EVT_LISTBOX, self.get_selecte_table, self.listtables)
> # end wxGlade
>
> def __set_properties(self):
> # begin wxGlade: TableChoice.__set_properties
> self.SetTitle("TableChoice")
> # end wxGlade
>
> def __do_layout(self):
> # begin wxGlade: TableChoice.__do_layout
> fsizer = wx.BoxSizer(wx.VERTICAL)
> mainsizer = wx.BoxSizer(wx.VERTICAL)
> widgetsizer = wx.BoxSizer(wx.VERTICAL)
> label_1 = wx.StaticText(self.panel_3, wx.ID_ANY, "Chooe which
> table you would like to add data to", style=wx.ALIGN_CENTER)
> label_1.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD, 0, ""))
> widgetsizer.Add(label_1, 0, wx.ALIGN_RIGHT | wx.EXPAND, 0)
> widgetsizer.Add(self.listtables, 1, wx.EXPAND, 0)
> mainsizer.Add(widgetsizer, 1, wx.EXPAND, 0)
> self.panel_3.SetSizer(mainsizer)
> fsizer.Add(self.panel_3, 1, wx.EXPAND, 0)
> self.SetSizer(fsizer)
> fsizer.Fit(self)
> self.Layout()
> self.Centre()
> # end wxGlade
>
> def get_selecte_table(self, event): # wxGlade:
> TableChoice.<event_handler>
> print("Event handler 'get_selecte_table' not implemented!")
> event.Skip()
> # end of class TableChoice
>
> class TableList(wx.ListBox):
> def __init__(self, parent, id=wx.ID_ANY, size="", choices=[],
> style=wx.LB_NEEDED_SB | wx.LB_SINGLE, name=""):
> wx.ListBox.__init__(self,parent,id)
>
> def setchoicelist(self,choicelist):
> self.choices = choicelist
>
> class MyApp(wx.App):
> def OnInit(self):
> #image = wx.Image("bope-logo.png", wx.BITMAP_TYPE_PNG)
> #bmp = image.ConvertToBitmap()
> #wx.SplashScreen(bmp, wx.SPLASH_CENTRE_ON_PARENT |
> wx.SPLASH_TIMEOUT, 5000, None, -1)
> #wx.Yield()
> self.frame = ActorList(None, wx.ID_ANY, "")
> self.SetTopWindow(self.frame)
> self.frame.Show()
> return True
>
> # end of class MyApp
>
> if __name__ == "__main__":
> app = MyApp(0)
> app.MainLoop()
>
>
> Here is the error that I am getting:
>
> Traceback (most recent call last):
> File "c:\Users\<My Name>\Desktop\My Projects\Sqlite
> Docs\testdataentry6b.py", line 158, in OpenFile
> create_connection(filename)
> File "c:\Users\<My Name>\Desktop\My Projects\Sqlite
> Docs\testdataentry6b.py", line 36, in create_connection
> list1 = TableList(None,wx.ID_ANY,choices = tablenames)
> File "c:\Users\<My Name>\Desktop\My Projects\Sqlite
> Docs\testdataentry6b.py", line 278, in __init__
> wx.ListBox.__init__(self,parent,id)
> File
> "C:\Python27\lib\site-packages\wx-2.8-msw-ansi\wx\_controls.py", line
> 1290, in __init__
> _controls_.ListBox_swiginit(self,_controls_.new_ListBox(*args,
> **kwargs))
> wx._core.PyAssertionError: C++ assertion "parent" failed at
> ..\..\src\common\ctrlcmn.cpp(79) in wxControlBase::CreateControl():
> all controls must have parents
> Here is a link to the wxg file
> https://drive.google.com/open?id=1rH5BFxhmk_bFQCO5ImWv6DSo8-jQbRjT
> Here is a link to the source code
> https://drive.google.com/open?id=1EQrtuebQUxRephQ8tqcVvcacOEsYeBws
>
> Here is a link to a sample sqlite database that you can use to test
> out the code.
> https://drive.google.com/open?id=1CKKFC1q121aPZZT6wEwN81RdjdejfT20
>
> Thanks in advance.
>
_______________________________________________
wxGlade-general mailing list
wxGlade-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/wxglade-general