如何使用python图形化界面wxPython
GUI库主要有三类:tkinter,wxPython和PyQt5,下面主要是针对wxPython的使用说明。
下面的操作均在win10 + pycharm上进行
-
wxPython的安装:
pip install wxPython
同时还安装了两个依赖包:six和pillow
-
简单使用:
变量app就是我们的程序。其次一定要注意大小写,尤其是Show的S
import wx app = wx.App() frame = wx.Frame(None, title = "Hello,world!") frame.Show() app.MainLoop()
运行后的界面如下所示:
-
进一步,我们可以添加一个按钮:
通过定义一个MyFrame类来实现,这个类继承自wx.Frame类。import wx class MyFrame(wx.Frame): def __init__(self, *args, **kw): wx.Frame.__init__(self, *args, **kw) self.button = wx.Button(self, label = "hello") app = wx.App() frame = MyFrame(None, title = "Hello,world!") frame.Show() app.MainLoop()
运行后的界面如下所示:
-
但有一个问题,这个按钮太大了,布满了整个界面,所以我们可以进一步设置按钮的大小和布局:
import wx class MyFrame(wx.Frame): def __init__(self, *args, **kw): wx.Frame.__init__(self, *args, **kw) self.btn1 = wx.Button(self, label="hello1", pos=(10, 50), size=(100, 50)) self.btn2 = wx.Button(self, label="hello2", pos=(120, 50), size=(100, 50)) app = wx.App() frame = MyFrame(None, title="Hello,world!") frame.Show() app.MainLoop()
其中,pos是位置参数,第一个表示与左边界的为距离,第二个表示与上边界的距离;size是按钮的大小参数,第一个表示宽度,第二个表示高度。
有一点需要注意,这个按钮是绝对布局下的按钮,也就是说无论你把窗口变多大多小,按钮都不会随着窗口的大小变化
-
我们虽然有按钮了,此时还需要加入焦点:
import wx class MyFrame(wx.Frame): def __init__(self, *args, **kw): wx.Frame.__init__(self, *args, **kw) panel = wx.Panel(self) self.btn1 = wx.Button(panel, label="hello1", pos=(10, 50), size=(100, 50)) self.btn2 = wx.Button(panel, label="hello2", pos=(120, 50), size=(100, 50)) app = wx.App() frame = MyFrame(None, title="Hello,world!") frame.Show() app.MainLoop()
运行后的界面如下所示:
我们通过加入了wx.Panel从而可以使用鼠标点击对应按钮,或者使用Tab键来移动到下一个按钮。 -
现在点击也可以了,但是没有反应还不行,所以我们将按钮和对应的事件进行绑定,也就是响应按钮事件:
import wx class MyFrame(wx.Frame): def __init__(self, *args, **kw): wx.Frame.__init__(self, *args, **kw) panel = wx.Panel(self) self.btn1 = wx.Button(panel, label="hello1", pos=(10, 50), size=(100, 50)) self.btn2 = wx.Button(panel, label="hello2", pos=(120, 50), size=(100, 50)) self.Bind(wx.EVT_BUTTON, self.OnButton1, self.btn1) self.Bind(wx.EVT_BUTTON, self.OnButton2, self.btn2) def OnButton1(self, event): print("Hello,world!") def OnButton2(self, event): print("Hello,world!Hello,world!") app = wx.App() frame = MyFrame(None, title="Hello,world!") frame.Show() app.MainLoop()
运行后的界面如下所示:
-
下面介绍一些控件的使用:
import wx class MyFrame(wx.Frame): def __init__(self, *args, **kw): wx.Frame.__init__(self, *args, **kw) panel = wx.Panel(self) self.static_text = wx.StaticText(panel, label="静态文本", pos=(10, 10)) self.text_1 = wx.TextCtrl(panel, value="文本框", pos=(10, 40)) self.text_2 = wx.TextCtrl(panel, value="密码框", style=wx.TE_PASSWORD, pos=(10, 70)) self.text_3 = wx.TextCtrl(panel, value="只读文本框", style=wx.TE_READONLY, pos=(10, 100)) self.text_4 = wx.TextCtrl(panel, value="多行\n文本框", style=wx.TE_MULTILINE, pos=(10, 130)) self.btn1 = wx.Button(panel, label="修改窗口标题", pos=(200, 10)) self.btn2 = wx.Button(panel, label="修改静态文本内容", pos=(200, 40)) self.btn3 = wx.Button(panel, label="修改文本框内容", pos=(200, 70)) self.btn4 = wx.Button(panel, label="修改只读文本框内容", pos=(200, 100)) self.Bind(wx.EVT_BUTTON, self.OnButton1, self.btn1) self.Bind(wx.EVT_BUTTON, self.OnButton2, self.btn2) self.Bind(wx.EVT_BUTTON, self.OnButton3, self.btn3) self.Bind(wx.EVT_BUTTON, self.OnText1, self.btn4) def OnButton1(self, event): self.Title += 'Hello' def OnButton2(self, event): self.static_text.Label += 'Hi' def OnButton3(self, event): self.text_1.Value = 'Good' self.text_2.Value = 'GOOD' self.text_3.Value = 'Good\nbetter\nbest' self.text_4.Value = 'GOOD\nBetter\nBest' def OnText1(self, event): self.text_3.Value = self.text_1.Value app = wx.App() frame = MyFrame(None, title="Multi_Text", size=(500, 300)) frame.Show() app.MainLoop()
运行后的界面如下所示:
-
接下来我们看一下加入图片控件的使用:
import wx class MyFrame(wx.Frame): def __init__(self, *args, **kw): wx.Frame.__init__(self, *args, **kw) self.bitmap = wx.StaticBitmap(self, pos=(10, 10)) self.btn1 = wx.Button(self, label="001", pos=(300, 10)) self.btn2 = wx.Button(self, label='002', pos=(300, 40)) self.Bind(wx.EVT_BUTTON, self.OnButton1, self.btn1) self.Bind(wx.EVT_BUTTON, self.OnButton2, self.btn2) def OnButton1(self, event): self.bitmap.Bitmap = wx.Bitmap('002.jpeg') def OnButton2(self, event): self.bitmap.Bitmap = wx.Bitmap('001.jpg') app = wx.App() frame = MyFrame(None, title="Images", size=(500, 290)) frame.Show() app.MainLoop()
运行后的界面如下所示:
-
接下来我们解决相对布局的问题,首先可以使用BoxSizer来使缩小窗口时不会遮挡按钮:
import wx class MyFrame(wx.Frame): def __init__(self, *args, **kw): wx.Frame.__init__(self, *args, **kw) sizer = wx.BoxSizer(wx.HORIZONTAL) self.bitmap = wx.StaticBitmap(self, bitmap=wx.Bitmap('001.jpg')) self.btn1 = wx.Button(self, label="001") self.btn2 = wx.Button(self, label='002') self.Bind(wx.EVT_BUTTON, self.OnButton1, self.btn1) self.Bind(wx.EVT_BUTTON, self.OnButton2, self.btn2) sizer.Add(self.btn1) sizer.Add(self.btn2) sizer.Add(self.bitmap) self.SetSizerAndFit(sizer) def OnButton1(self, event): self.bitmap.Bitmap = wx.Bitmap('002.jpeg') def OnButton2(self, event): self.bitmap.Bitmap = wx.Bitmap('001.jpg') app = wx.App() frame = MyFrame(None, title="Images", size=(500, 290)) frame.Show() app.MainLoop()
运行后的界面如下所示:
-
当拉动窗口时,按钮将一直保持相同比例跟随其变化:
import wx class MyFrame(wx.Frame): def __init__(self, *args, **kw): wx.Frame.__init__(self, *args, **kw) self.btn1 = wx.Button(self, label="button1") self.btn2 = wx.Button(self, label='button2') sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.btn1, 1) sizer.Add(self.btn2, 3) self.SetSizerAndFit(sizer) app = wx.App() frame = MyFrame(None, title="vertical") frame.Show() app.MainLoop()
运行后的界面如下所示:
-
当然,也可以添加位置信息:
sizer.Add(self.btn1, 1, wx.ALIGN_LEFT) sizer.Add(self.btn3, 2, wx.TEXT_ALIGNMENT_LEFT) sizer.Add(self.btn2, 3, wx.EXPAND)
-
也可以加边框距离:
sizer.Add(self.btn1, 1, wx.ALIGN_LEFT|wx.ALL, 10) sizer.Add(self.btn3, 2, wx.TEXT_ALIGNMENT_LEFT|wx.LEFT|wx.RIGHT, 300) sizer.Add(self.btn2, 3, wx.EXPAND)
-
也可以Add一个块来进行占位:
sizer.Add((50, 60))
-
还可以设置比例:
sizer.Add(self.btn1, 1, wx.ALL, 30) sizer.Add(self.btn3, 1, wx.ALL, 30) sizer.Add(self.btn2, 1, wx.ALL, 30) sizer.Add((50, 60), 3)
运行后的界面如下所示:
-
最后来看一个嵌套布局:
import wx class MyFrame(wx.Frame): def __init__(self, *args, **kw): wx.Frame.__init__(self, *args, **kw) self.btn1 = wx.Button(self, label="button1") self.btn2 = wx.Button(self, label='button2') self.btn3 = wx.Button(self, label='button3') self.btn4 = wx.Button(self, label="button4") self.btn5 = wx.Button(self, label="button5") hsizer1 = wx.BoxSizer(wx.HORIZONTAL) hsizer1.Add(self.btn1, 0, wx.ALL, 5) hsizer1.Add(self.btn2, 0, wx.ALL, 5) hsizer2 = wx.BoxSizer(wx.HORIZONTAL) hsizer2.Add(self.btn3, 1, wx.ALL, 5) hsizer2.Add(self.btn4, 1, wx.ALL, 5) vsizer1 = wx.BoxSizer(wx.VERTICAL) vsizer1.Add(hsizer1, 0, wx.ALIGN_RIGHT) vsizer1.Add(hsizer2, 0, wx.EXPAND) vsizer1.Add(self.btn5, 1, wx.EXPAND) self.SetSizerAndFit(vsizer1) app = wx.App() frame = MyFrame(None, title="嵌套BoxSizer") frame.Show() app.MainLoop()
然后来看运行效果: