###### tags: `python`
# wxPython 視窗程式
## 視窗結構
**視窗結構圖(註1)**
![視窗結構圖](https://i.imgur.com/EDpGEKU.png)
---
A. **Frame**(框架: 視窗的最底層) 註:3
1. **MenuBar (選單列):** 下拉式選單
2. **ToolBar (工具列):** 把所有功能以圖示的方式呈現在選單列下方
3. **StatusBar (狀態列):** 顯示應用程式的狀態訊息,位於視窗最下方
4. **Panel (面版):** 用來放置各種 Controls(控制項)及視窗內容的地方
a. **Button (按鈕)**
b. **TextCtrl (文字方塊控制項)**
c. **CheckBox (核取方塊控制項)**
d. **StaticText (靜態文字控制項)**
e. **ListBox (清單控制項)**
f. **RadioBox (選取按鈕控制項)**
---
wxPython習慣稱整個視窗為frame,其中文為畫面或畫板的意思
## 安裝 wxPython
pip install wxpython
---
## 範例一
```python=
# -*- coding:utf-8 -*-
import wx
app = wx.App()
frame = wx.Frame(parent=None, title="猜數字", size=(250, 200))
frame.Show()
app.MainLoop()
```
## 範例二
```python=
# -*- coding:utf-8 -*-
import wx
if __name__ == '__main__':
app = wx.App()
frame = wx.Frame(parent=None, title="猜數字", size=(250, 200))
frame.Show()
app.MainLoop()
```
## 範例三
```python=
# -*- coding:utf-8 -*-
import wx
app = wx.App()
frame = wx.Frame(parent=None, title="猜數字", size=(250, 200))
panel = wx.Panel(frame)
wx.StaticText(parent=panel, label="請猜1-100的數字", pos=(10,10))
frame.answer = wx.TextCtrl(parent=panel, pos=(120,10))
frame.btn = wx.Button(parent=panel, label="大或小", pos=(120,50))
frame.message = wx.StaticText(parent=panel,pos=(10,100))
frame.Show()
app.MainLoop()
```
## 範例四
```python=
# -*- coding:utf-8 -*-
import random, wx
class MySalgar(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, parent=None, title="猜數字", size=(270,200))
panel = wx.Panel(self)
#配置視窗元件
wx.StaticText(parent=panel, label="請猜1-100的數字", pos=(10,10))
self.answer = wx.TextCtrl(parent=panel, pos=(120,10))
self.btn = wx.Button(parent=panel, label="大或小", pos=(120,50))
self.message = wx.StaticText(parent=panel,pos=(10,100))
#新增 BtnClick 事件
self.Bind(wx.EVT_BUTTON, self.BtnClick, self.btn)
#撰寫 BtnClick 事件函式
def BtnClick(self, event):
answer = eval(self.answer.GetValue())
if answer > num:
messageStr ="太大了"
elif answer < num:
messageStr = "太小了"
else:
messageStr = "猜中了"
self.message.SetLabel(messageStr)
if __name__ == '__main__':
num = random.randint(1, 100)
app = wx.App()
frame = MySalgar()
frame.Show()
app.MainLoop()
```
## 範例五
```python=
# -*- coding:utf-8 -*-
import random, wx
class Game(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, parent=None, title="猜數字", size=(270,200))
panel = wx.Panel(self)
# 配置視窗元件
wx.StaticText(parent=panel, label="請猜1-100的數字", pos=(10,10))
self.answer = wx.TextCtrl(parent=panel, pos=(120,10))
self.btn = wx.Button(parent=panel, label="大或小", pos=(120,50))
self.message = wx.StaticText(parent=panel,pos=(10,100))
# 新增 BtnCheck 事件
self.Bind(wx.EVT_BUTTON, self.BtnCheck, self.btn)
# 配置選單元件
menubar = wx.MenuBar()
fileMenu = wx.Menu()
fitem = fileMenu.Append(wx.ID_EXIT, '結束', '結束軟體')
menubar.Append(fileMenu, '&檔案')
self.SetMenuBar(menubar)
# 新增 MenuQuit 事件
self.Bind(wx.EVT_MENU, self.MenuQuit, fitem)
# 撰寫 BtnCheck 事件函式
def BtnCheck(self, event):
answer = eval(self.answer.GetValue())
if answer > num:
messageStr ="太大了"
elif answer < num:
messageStr = "太小了"
else:
messageStr = "猜中了"
self.message.SetLabel(messageStr)
# 撰寫 MenuQuit 事件函式
def MenuQuit(self, e):
self.Close()
if __name__ == '__main__':
num = random.randint(1, 100)
answer = -1
app = wx.App()
frame = Game()
frame.Show()
app.MainLoop()
```
---
## 使用
1. 點「Component Palette/Froms」產生一個From
2. 在右側「Object Properties」修改這個From的相關屬性
A. Frames:
* name:
* title:
* style:
* extra_style:
* center:
* xrc_skipe_sizer:
* event_handler:
* aui_managed:
* aui_manager_style:
B. wxWindow:
* id:
* pos: 視窗位置
* size: 視窗大小
* minimum_size: 最小視窗大小
* maximum_size: 最大視窗大小
* font: 字型
* fg: 前景顏色
* bg: 背景顏色
* window_name:
* window_style:
* window_extra_style:
* tooltip:
* context_menu:
* context_help:
* hidden: 是否隱藏
* subclass:
3. 在右側「Events」可以設定觸發事件時要執行哪個函數
---
## 註解
* 註1, 註2: [使用wxPython 模組去記錄視窗程式設計-第三篇](http://stanley2910.pixnet.net/blog/category/777541/ )
* 註3: [wxPython基礎視窗程式](https://www.openfoundry.org/en/tech-column/106)
---
## 參考資料
* [wxPython tutorial](http://zetcode.com/wxpython/)
* [使用wxPython 模組視窗程式設計-第二篇(位置篇)](http://stanley2910.pixnet.net/blog/post/145008563-%E4%BD%BF%E7%94%A8wxpython%C2%A0%E6%A8%A1%E7%B5%84%E5%8E%BB%E8%A8%98%E9%8C%84%E8%A6%96%E7%AA%97%E7%A8%8B%E5%BC%8F%E8%A8%AD%E8%A8%88-%E7%AC%AC%E4%BA%8C%E7%AF%87)
* [Menus and toolbars](http://zetcode.com/wxpython/menustoolbars/)
* [wxPython Recipes: A Problem - Solution Approach](https://www.tenlong.com.tw/products/9781484232361)
## GUI designer
* [wxGlade](http://wxglade.sourceforge.net/)
* [wxFormBuilder](https://github.com/wxFormBuilder/wxFormBuilder)
* [dialogblocks](http://www.dialogblocks.com)