xia的小窩

一起來coding和碼字吧

0%

GUI頁面處理及簡單易懂的入門--使用wxpython

初識GUI

  • GUI是Graphical User Interface(圖形用戶介面的縮寫)
  • 程序有3個,輸入、處理、輸出

常用框架

wxpython,PyQt、Tkinter等

安裝wxpython

1
pip install -U wxpython

安裝成功

建立應用程式

  • 使用wxpython之前,先了解程序對象及頂級窗口

  • 主循環事件是wxpython程式的動力,如果沒有對象,將不能運行

  • 是用於管理最重要的數據,控制並呈現給客戶

建立一個wx.App的子類

這是一個沒有任何功能的子類

  1. 定義這個子類
  2. 在定義的程式裡寫一個OnInit的初始化函數
  3. 在程式的主要部份建立這個類的一個實例
  4. 調用應用程式的MainLoop()函數,將這個程式的控制權轉交給wxpython

範例

1
2
3
4
5
6
7
8
9
10
11
12
import wx

class App(wx.App):

def OnInit(self):
frame = wx.Frame(parent = None, title = "Hello wxPython")
frame.Show()
return True

if __name__ == "__main__":
app = App()
app.MainLoop()

結果

直接使用wx.App

如果只有一個窗口,就直接使用吧~~

1
2
3
4
5
6
import wx

app = App()
frame = wx.Frame(parent = None, title = "Hello wxPython")
frame.Show()
app.MainLoop()

使用wx.Frame框架

在wxpython中,wxFrame是所有框架的父類,當用戶創建wx.Frame子類時,子類應該調用其父類的構造器wx.Frame.init()。
語法如下

1
2
3
4
wx.Frame(parent, id = -1, title = "", 
pos = wx.DefaultPosition, size = wx.DefaultSize,
style = wx.DEFAULT_FRAME_STYLE,
name = "frame")

範例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import wx

class MyFrame(wx.Frame):

def __init__(self, parent, id):
wx.Frame.__init__(self,
parent,
id,
title = "Hello wxPython",
pos = (100, 100),
size = (300, 300)
)


if __name__ == "__main__":
app = wx.App()
frame = MyFrame(parent = None, id = -1)
frame.Show()
app.MainLoop()

結果

StaticText文本類

對於所有UI工具來說,最基本的任務就是在螢幕上印出純文本,語法如下

1
2
3
4
5
6
wx.StaticText(parent, id, label, 
pos = wx.DefaultPosition,
size = wx.DefaultSize,
style = 0,
name = "StaticText"
)

範例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import wx

class MyFrame(wx.Frame):

def __init__(self, parent, id):
wx.Frame.__init__(self,
parent,
id,
title = "Hello wxPython",
pos = (100, 100),
size = (600, 400)
)

panel = wx.Panel(self)
title = wx.StaticText(panel, label = "測試用", pos = (100, 20))
font = wx.Font(16, wx.DEFAULT, wx.FONTSTYLE_NORMAL, wx.NORMAL)
title.SetFont(font)

wx.StaticText(panel, label = "2021/8/10", pos = (50, 50))


if __name__ == "__main__":
app = wx.App()
frame = MyFrame(parent = None, id = -1)
frame.Show()
app.MainLoop()

結果

上述程式碼中,使用panel = wx.Panel(self)來建立面板,並將Panel當作父類,然後將組件放入窗體……

1
wx.Font(PointSize, family, style, weight, underline = False, faceName = "", encoding = wx.FONTENCODING_DEFAULT)

輸入文字

需要的是wx.TextCtrl類

1
wx.TextCtrl(parent, id, value = "", pos, size, style = 0, validator = wx.DefaultValidator, name = wx.)

範例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import wx

class MyFrame(wx.Frame):

def __init__(self, parent, id):
wx.Frame.__init__(self,
parent,
id,
title = "Hello wxPython",
size = (400, 300)
)

panel = wx.Panel(self)
self.title = wx.StaticText(panel, label = "輸入資料及密碼", pos = (140, 20))
self.label_user = wx.StaticText(panel, label = "用戶名", pos = (50, 50))
self.text_user = wx.TextCtrl(panel, pos = (100, 50), size = (235, 25), style = wx.TE_LEFT)
self.label_pwd = wx.StaticText(panel, label = "密碼", pos = (50, 90))
self.text_password = wx.TextCtrl(panel, pos = (100, 90), size = (235, 25), style = wx.TE_PASSWORD)



if __name__ == "__main__":
app = wx.App()
frame = MyFrame(parent = None, id = -1)
frame.Show()
app.MainLoop()

結果

Button,做按鈕

語法如下

1
wx.Button(parent, id, label, pos, size, style = 0, validator, name = "button")

範例

1
2
self.bt_confirm = wx.Button(panel, label = "確定", pos = (105, 130))
self.bt_cancel = wx.Button(panel, label = "取消", pos = (195, 130))

結果

BoxSizer布局

wxpython提供了5種sizer => (BoxSizer, GridSizer, FlexGridSizer, GridBagSizer, StaticBoxSizer)

範例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class MyFrame(wx.Frame):

def __init__(self, parent, id):
wx.Frame.__init__(self,
parent,
id,
"用戶登入",
size = (400, 300)
)

panel = wx.Panel(self)
self.title = wx.StaticText(panel, label = "請輸入用戶名及密碼")

vsizer = wx.BoxSizer(wx.VERTICAL)
vsizer.Add(self.title, proportion = 0, flag = wx.BOTTOM|wx.TOP|wx.ALIGN_CENTER, border = 15)
panel.SetSizer(vsizer)

結果

將前面的融合之後…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import wx

class MyFrame(wx.Frame):

def __init__(self, parent, id):
wx.Frame.__init__(self,
parent,
id,
title = "用戶登入",
size = (400, 300)
)

panel = wx.Panel(self)

self.bt_confirm = wx.Button(panel, label = "確定")
self.bt_cancel = wx.Button(panel, label = "取消")

self.title = wx.StaticText(panel, label = "輸入資料及密碼")
self.label_user = wx.StaticText(panel, label = "用戶名")
self.text_user = wx.TextCtrl(panel, style = wx.TE_LEFT)
self.label_pwd = wx.StaticText(panel, label = "密碼")
self.text_password = wx.TextCtrl(panel, style = wx.TE_PASSWORD)




hsizer_user = wx.BoxSizer(wx.HORIZONTAL)
hsizer_user.Add(self.label_user, proportion = 0, flag = wx.ALL, border = 5)
hsizer_user.Add(self.text_user, proportion = 1, flag = wx.ALL, border = 5)

hsizer_pwd = wx.BoxSizer(wx.HORIZONTAL)
hsizer_pwd.Add(self.label_pwd, proportion = 0, flag = wx.ALL, border = 10)
hsizer_pwd.Add(self.text_password, proportion = 1, flag = wx.ALL, border = 5)

hsizer_button = wx.BoxSizer(wx.HORIZONTAL)
hsizer_button.Add(self.bt_confirm, proportion = 0, flag = wx.ALIGN_CENTER, border = 5)
hsizer_button.Add(self.bt_cancel, proportion = 0, flag = wx.ALIGN_CENTER, border = 5)


vsizer_all = wx.BoxSizer(wx.VERTICAL)
vsizer_all.Add(self.title, proportion = 0, flag = wx.BOTTOM|wx.TOP|wx.ALIGN_CENTER, border = 15)

vsizer_all.Add(hsizer_user, proportion = 0, flag = wx.EXPAND|wx.LEFT|wx.RIGHT, border = 45)

vsizer_all.Add(hsizer_pwd, proportion = 0, flag = wx.EXPAND|wx.LEFT|wx.RIGHT, border = 45)

vsizer_all.Add(hsizer_button, proportion = 0, flag = wx.ALIGN_CENTER|wx.TOP, border = 15)

panel.SetSizer(vsizer_all)


if __name__ == "__main__":
app = wx.App()
frame = MyFrame(parent = None, id = -1)
frame.Show()
app.MainLoop()

結果

事件處理

事件就是單純的event,比如點擊一個按鈕,就會觸發……

使用監控Bind()函數,語法如下 :point_down:

1
bt_confirm.Bind(wx.EVT_BUTTOM, OnclickSubmit)

範例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
## 上面的__init__()裡面
self.bt_confirm = wx.Button(panel, label = "確定")
self.bt_confirm.Bind(wx.EVT_BUTTON, self.ONclickSubmit)
self.bt_cancel = wx.Button(panel, label = "取消")
self.bt_cancel.Bind(wx.EVT_BUTTON, self.ONclickCancel)

## 寫在外面
def ONclickSubmit(self, event):
message = ""
username = self.text_user.GetValue()
password = self.text_password.GetValue()
if username == "zhan":
message = "登入成功"
wx.MessageBox(message)

def ONclickCancel(self, event):
self.text_user.SetValue("")
self.text_password.SetValue("")

結果