I built a script that find a book by pertinence (output) given a quote (input). Now I want to create the GUI of this script and I decided to use wxPython. I would like a basic GUI, where the user can write the phrase in a text bar, then push a button storing the string he entered in a variable. In this way, I can use the variable as input for the algorithm that find the book associated with the entered phrase, showing the title and author as output in a second window.
I built the code that allows me to create the GUI and to store the phrase in the variable var
. Now I don't know how to proceed, because I can't access var
outside the class. Here the code and the image of the GUI:
class MyFrame(wx.Frame):
def __init__(self, *args, **kw):
super(MyFrame, self).__init__(*args, **kw)
panel = wx.Panel(self)
my_sizer = wx.BoxSizer(wx.VERTICAL)
my_sizer.AddStretchSpacer()
hbox = wx.BoxSizer(wx.HORIZONTAL)
manual = wx.StaticText(panel, label='1) Inserisci la citazione --> ')
font_manual = wx.Font(10, wx.SCRIPT, wx.NORMAL, wx.NORMAL)
manual.SetFont(font_manual)
hbox.Add(manual)
manual2 = wx.StaticText(panel, label='2) Clicca sul logo Bibliovago --> ')
font_manual2 = wx.Font(10, wx.SCRIPT, wx.NORMAL, wx.NORMAL)
manual2.SetFont(font_manual2)
hbox.Add(manual2)
manual3 = wx.StaticText(panel, label='3) Buona lettura')
font_manual3 = wx.Font(10, wx.SCRIPT, wx.NORMAL, wx.NORMAL)
manual3.SetFont(font_manual3)
hbox.Add(manual3)
my_sizer.Add(hbox,0, wx.ALIGN_CENTER)
my_sizer.AddStretchSpacer()
istr = wx.StaticText(panel, label='Inserisci una citazione')
font_istr = wx.Font(14, wx.MODERN, wx.NORMAL, wx.NORMAL)
istr.SetFont(font_istr)
my_sizer.Add(istr, 0, wx.ALL | wx.CENTER, 5)
self.text_ctrl = wx.TextCtrl(panel)
my_sizer.Add(self.text_ctrl, 0, wx.ALL | wx.EXPAND, 5)
logo_button = wx.Bitmap('LOGO.png')
self.my_btn = wx.BitmapButton(panel,-1,logo_button)
self.Bind(wx.EVT_BUTTON, self.SavePhrase, self.my_btn)
my_sizer.Add(self.my_btn, 0, wx.ALL | wx.CENTER, 5)
panel.SetSizer(my_sizer)
my_sizer.AddStretchSpacer()
def SavePhrase(self, event):
var = self.text_ctrl.GetValue()
if __name__ == '__main__':
app = wx.App()
frm = MyFrame(None, title='BiblioZam', size = (600,400))
frm.Show()
app.MainLoop()
Should I use my algorithm inside the class as a function? Or there is another way?
Thank you.
When you use classes and you need to access something across methods inside a class, then you need to create the variable by prepending it with self
. So in SavePhrase
, you need to create var
as self.var
if other parts of the class need access to it
If you want to show the results in a separate window, then I would create a new wx.Frame
instance inside of SavePhrase
and pass it your var
. Then you don't need to call it self.var
unless something else in MyFrame
itself needs to access var
.
Here is an example:
import wx
class OtherFrame(wx.Frame):
"""
Class used for creating frames other than the main one
"""
def __init__(self, var, title='Other Frame', parent=None):
wx.Frame.__init__(self, parent=parent, title=title)
self.var = var
print('var = {}'.format(var))
self.Show()
class MyFrame(wx.Frame):
def __init__(self, *args, **kw):
super(MyFrame, self).__init__(*args, **kw)
panel = wx.Panel(self)
my_sizer = wx.BoxSizer(wx.VERTICAL)
my_sizer.AddStretchSpacer()
hbox = wx.BoxSizer(wx.HORIZONTAL)
manual = wx.StaticText(panel, label='1) Inserisci la citazione --> ')
font_manual = wx.Font(10, wx.SCRIPT, wx.NORMAL, wx.NORMAL)
manual.SetFont(font_manual)
hbox.Add(manual)
manual2 = wx.StaticText(panel, label='2) Clicca sul logo Bibliovago --> ')
font_manual2 = wx.Font(10, wx.SCRIPT, wx.NORMAL, wx.NORMAL)
manual2.SetFont(font_manual2)
hbox.Add(manual2)
manual3 = wx.StaticText(panel, label='3) Buona lettura')
font_manual3 = wx.Font(10, wx.SCRIPT, wx.NORMAL, wx.NORMAL)
manual3.SetFont(font_manual3)
hbox.Add(manual3)
my_sizer.Add(hbox,0, wx.ALIGN_CENTER)
my_sizer.AddStretchSpacer()
istr = wx.StaticText(panel, label='Inserisci una citazione')
font_istr = wx.Font(14, wx.MODERN, wx.NORMAL, wx.NORMAL)
istr.SetFont(font_istr)
my_sizer.Add(istr, 0, wx.ALL | wx.CENTER, 5)
self.text_ctrl = wx.TextCtrl(panel)
my_sizer.Add(self.text_ctrl, 0, wx.ALL | wx.EXPAND, 5)
logo_button = wx.Bitmap('LOGO.png')
self.my_btn = wx.BitmapButton(panel,-1,logo_button)
self.Bind(wx.EVT_BUTTON, self.SavePhrase, self.my_btn)
my_sizer.Add(self.my_btn, 0, wx.ALL | wx.CENTER, 5)
panel.SetSizer(my_sizer)
my_sizer.AddStretchSpacer()
def SavePhrase(self, event):
var = self.text_ctrl.GetValue()
frame = OtherFrame(var=var)
if __name__ == '__main__':
app = wx.App()
frm = MyFrame(None, title='BiblioZam', size = (600,400))
frm.Show()
app.MainLoop()
Now your other frame can use var
as needed to generate the result. Note that if generating the result takes a long time, you might want to move that generation step into a thread so it doesn't block your GUI's main loop and cause it to appear to hang.
You might also find this article of mine helpful - http://www.blog.pythonlibrary.org/2018/10/19/wxpython-how-to-open-a-second-window-frame/