Reputation: 117
I made a small ugly GUI, following some tutorials and reading what I understood on basic WxPython I am working on python 2.6 currently. I managed to get most things to display but I want to basically get the filepath on the filepicker button when I click on the check button but when I attempted to make the bind I get an error saying the object does not have the attribute.
It is more of a basic python issue than Wxpython itself in my opinion I don't know how it wants me to perform the call for the event
Also I would like to eventually change the passed text to green or something or an event but if I try to do anything outside of basicGUI with the elements I fail to properly reference them(things like the panel, etc) so any ideas on how to implement changes to GUI elements would be helpful on top of the button event.
I tried copying an example of someone else using the button event, but it does not work in my implementation because the way I defined the class I think... I need to figure out how to adapt that line of code so it references the object properly.
import wx
import ctypes
try:
ctypes.windll.shcore.SetProcessDpiAwareness(True)
except:
pass
class windowClass(wx.Frame):
def __init__(self,*args,**kwargs):
super(windowClass,self).__init__(*args,**kwargs)
self.basicGUI()
#GUI elements
def basicGUI(self):
panel=wx.Panel(self)
menu_bar=wx.MenuBar()
box_sizer=wx.BoxSizer()
box_sizer.Add(panel, 1, wx.ALL | wx.EXPAND)
button_text=wx.StaticText(panel, label="Select a file")
file_button=wx.FilePickerCtrl(panel)
check_button=wx.Button(panel, label='Check')
#self.Bind(wx.EVT_BUTTON, OnCheckButton(self), check_button)
a_text=wx.StaticText(panel, label="a file status")
b_text=wx.StaticText(panel, label="b file status")
c_text=wx.StaticText(panel, label="c file status")
passed_text=wx.StaticText(panel, label="passed")
#set items on the grid
sizer = wx.GridBagSizer(5, 5)
sizer.Add(button_text, (0, 0))
sizer.Add(file_button, (0, 2))
sizer.Add(check_button,(1, 2))
sizer.Add(a_text, (2, 0))
sizer.Add(b_text, (3, 0))
sizer.Add(c_text, (4, 0))
sizer.Add(passed_text, (2, 1))
#make border
border = wx.BoxSizer()
border.Add(sizer, 1, wx.ALL | wx.EXPAND, 5)
#use sizers
panel.SetSizerAndFit(border)
self.SetSizerAndFit(box_sizer)
#show GUI
self.SetTitle('file check')
self.Centre()
self.Show(True)
def OnCheckButton(self,event):
print("perform check") #debug line
#file_button.GetPath(self) this probably won't work either as is,
#don't know how to pass the button info
app=wx.App()
windowClass(None)
print("passed")
app.MainLoop()
at this early stage I expect to click the button and be able to print or do other things... but since it says it is not defined it is sort of an odd error.
self.Bind(wx.EVT_BUTTON, self.OnCheckButton(self), check_button)
AttributeError: 'windowClass' object has no attribute 'OnCheckButton'
Upvotes: 0
Views: 492
Reputation: 142641
First: you have wrong indentations and OnCheckButton
is not method in class windowClass
but normal function inside basicGUI
so it can't find method OnCheckButton
in class windowClass
and you get error 'windowClass' object has no attribute 'OnCheckButton'
Second: probably in all GUI frameworks (probably in all languages) Button
needs "callback" - it means function's name without ()
and arguments. When you click button then system will run this function by adding ()
self.Bind(wx.EVT_BUTTON, self.OnCheckButton, check_button)
Third: use self.
in self.file_button
to have access to this variable in metehod OnCheckButton
and get path of selected file.
Full code:
import wx
import ctypes
try:
ctypes.windll.shcore.SetProcessDpiAwareness(True)
except:
pass
class WindowClass(wx.Frame):
def __init__(self, *args, **kwargs):
super(WindowClass,self).__init__(*args, **kwargs)
self.basicGUI()
#GUI elements
def basicGUI(self):
panel = wx.Panel(self)
menu_bar = wx.MenuBar()
box_sizer = wx.BoxSizer()
box_sizer.Add(panel, 1, wx.ALL|wx.EXPAND)
button_text = wx.StaticText(panel, label="Select a .cpf file")
self.file_button = wx.FilePickerCtrl(panel)
check_button = wx.Button(panel, label='Check')
self.Bind(wx.EVT_BUTTON, self.OnCheckButton, check_button)
a_text = wx.StaticText(panel, label="a file status")
b_text = wx.StaticText(panel, label="b file status")
c_text = wx.StaticText(panel, label="c file status")
passed_text = wx.StaticText(panel, label="passed")
#set items on the grid
sizer = wx.GridBagSizer(5, 5)
sizer.Add(button_text, (0, 0))
sizer.Add(self.file_button, (0, 2))
sizer.Add(check_button,(1, 2))
sizer.Add(a_text, (2, 0))
sizer.Add(b_text, (3, 0))
sizer.Add(c_text, (4, 0))
sizer.Add(passed_text, (2, 1))
#make border
border = wx.BoxSizer()
border.Add(sizer, 1, wx.ALL|wx.EXPAND, 5)
#use sizers
panel.SetSizerAndFit(border)
self.SetSizerAndFit(box_sizer)
#show GUI
self.SetTitle('file check')
self.Centre()
self.Show(True)
# indentations are very important in Python
def OnCheckButton(self, event):
print("perform check") #debug line
print(self.file_button.GetPath())
app = wx.App()
WindowClass(None)
print("passed")
app.MainLoop()
BTW: read PEP 8 -- Style Guide for Python Code. It suggests how to format code in Python and many people and tools respect these rules.
Upvotes: 1