Python 小白从零开始 PyQt5 项目实战(8)汇总篇(完整例程)
本系列面向 Python 小白,從零開始實戰解說應用 QtDesigner 進行 PyQt5 的項目實戰。不跳過一個細節,不漏掉一行代碼,不省略一個例圖。
本系列從軟件安裝、環境配置開始,介紹了基本應用:菜單和工具欄、基本控件,核心機制:信號與槽連接、高級應用:布局管理、窗口切換和折疊側邊欄,并通過項目實戰案例介紹各種應用的詳細操作過程。本文匯總相關內容,并給出項目實戰的完整例程。
文章目錄
- @[toc]
- 1. PyQt5 和 PyDesigner 的安裝與環境配置
- 1.1 安裝 PyQt5 和QtTools
- 1.2 QtDesigner 和 PyUIC 的環境配置
- 1.2.1 在 PyCharm 添加 Create Tools
- 1.2.2 添加 PyUIC 工具
- 2. 菜單和工具欄
- 2.1 創建主窗口
- 2.2 建立菜單欄
- 2.3 建立工具欄
- 3. 信號與槽(Signals and slots)的連接
- 3.1 信號與槽的原理
- 3.2 信號發送者與槽的接收者
- 3.3 QtDesigner 建立信號與槽的連接
- 4. PyQt5 的基本控件
- 4.1 PyQt5 的控件簡介
- 4.2 編輯控件的屬性
- 4.3 PyQt5 的控件類型
- 5. PyQt5 的基本布局管理
- 5.1 什么是布局管理
- 5.2 水平布局(Horizontal Layout)
- 5.3 垂直布局(Vertical Layout)
- 5.4 嵌套布局
- 5.5 容器布局
- 6. 多窗口切換的堆疊布局
- 6.1 什么是堆疊布局(Stacked Layout)
- 6.2 創建多窗口切換的堆疊布局
- 6.3 堆疊布局的主程序設計
- 6.3.1 多頁面切換的方法
- 6.3.2 建立信號/槽連接
- 6.3.3 頁面控制程序
- 6.3.4 堆疊布局中的控件操作
- 7. 折疊側邊欄的實現
- 7.1 什么是折疊側邊欄
- 7.2 目錄結構的折疊側邊欄
- 7.3 垂直菜單結構折疊側邊欄
- 8. 項目實戰完整例程
- 8.1 項目圖形界面效果
- 8.2 UI程序(uiDemo11.py)
- 8.3 main程序(GUIdemo11.py)
- @[toc]
- 1.1 安裝 PyQt5 和QtTools
- 1.2 QtDesigner 和 PyUIC 的環境配置
- 1.2.1 在 PyCharm 添加 Create Tools
- 1.2.2 添加 PyUIC 工具
- 2.1 創建主窗口
- 2.2 建立菜單欄
- 2.3 建立工具欄
- 3.1 信號與槽的原理
- 3.2 信號發送者與槽的接收者
- 3.3 QtDesigner 建立信號與槽的連接
- 4.1 PyQt5 的控件簡介
- 4.2 編輯控件的屬性
- 4.3 PyQt5 的控件類型
- 5.1 什么是布局管理
- 5.2 水平布局(Horizontal Layout)
- 5.3 垂直布局(Vertical Layout)
- 5.4 嵌套布局
- 5.5 容器布局
- 6.1 什么是堆疊布局(Stacked Layout)
- 6.2 創建多窗口切換的堆疊布局
- 6.3 堆疊布局的主程序設計
- 6.3.1 多頁面切換的方法
- 6.3.2 建立信號/槽連接
- 6.3.3 頁面控制程序
- 6.3.4 堆疊布局中的控件操作
- 7.1 什么是折疊側邊欄
- 7.2 目錄結構的折疊側邊欄
- 7.3 垂直菜單結構折疊側邊欄
- 8.1 項目圖形界面效果
- 8.2 UI程序(uiDemo11.py)
- 8.3 main程序(GUIdemo11.py)
1. PyQt5 和 PyDesigner 的安裝與環境配置
關于PyQt5 及PyDesigner 工具的安裝與環境配置,具體請詳見:Python 小白從零開始 PyQt5 項目實戰(1)安裝與環境配置。
1.1 安裝 PyQt5 和QtTools
QT 是最強大的 GUI 庫之一,PyQt5 是 Python 綁定 QT5 應用的框架,具有簡單好用,功能強大, 跨平臺支持,文檔齊全,穩定性高,生態支持,開源免費的優點。
Qt Designer 通過人機交互的排版方式進行界面設計,非常方便、直觀。
pip 安裝 PyQt5:
pip install pyqt5 -i https://mirrors.aliuyun.com/pypi/simplepip 安裝 QtTools:
Qt Tools 包含:
-
圖形界面設計工具 Qt Designer,用于設計圖形界面,生成 .ui文件,以 xml 格式存儲界面和控件的屬性;
-
UI 文件轉換工具 PyUic,用于將 .ui 文件解析為 .py 文件的工具。
Qt Tools 可以使用 pip 方式安裝:
pip install pyqt5-tools -i https://mirrors.aliuyun.com/pypi/simple1.2 QtDesigner 和 PyUIC 的環境配置
使用 PyCharm 集成開發工具的小白,在安裝 QtTools 庫以后,還要對 QtDesigner 和 PyUIC 進行環境配置,將其集成到 PyCharm 中。
1.2.1 在 PyCharm 添加 Create Tools
運行 PyCharm;
- 從頂部菜單欄選擇:File -> Settings,彈出 Seetings 窗口;
- 從左側菜單欄中選擇:Tools -> ExternalTools,在右側點擊 “+” 彈出 CreateTool 窗口;
在 CreateTool 窗口依次填寫:
- Name:填寫 “QtDesigner”
- Program:填寫 designer.exe 的路徑
注意:此處填寫剛才 pip 安裝的 pyqt5-tools 工具包的路徑。如果小白的 Python 或 Anaconda3 安裝在其他路徑下,則從對應的目錄找到 “qt5_applications\Qt\bin\designer.exe”,或者在資源管理器中搜索 “designer.exe” 文件找到安裝路徑。
- Arguments:不用填寫
- Working directory:填寫生成 UI 文件的保存路徑
例如,要將 .ui 文件保存在當前 Project 的路徑下,則填寫 “$ProjectFileDir$”;要將 .ui 文件保存在當前 Project 路徑下的 \program 子目錄中,則填寫 “$ProjectFileDir$\program”。
填好 CreateTool 窗口后,點擊 “OK” 即可完成 QtDesigner 工具的添加。
1.2.2 添加 PyUIC 工具
在 CreateTool 窗口依次填寫:
- Name:填寫 “PyUIC”
- Program:填寫 python.exe 的路徑
注意:此處填寫 IDE 使用的 Python Interpreter的路徑。如果小白的 Python 或 Anaconda3 安裝在其他路徑下,或者選擇其它路徑中的 python.exe 作為 Python Interpreter,可以從 Pycharm -> Settings -> Project -> Python Interpreter 打開配置窗口,從右側上方 “Python Interpreter:” 選項框找到 python.exe 的路徑。
- Arguments:填寫"-m PyQt5.uic.pyuic $FileName$ -o $FileNameWithoutExtension$.py”
- Working directory:填寫將 .ui 文件轉換為 .py 文件的保存路徑
例如,要將 .py 文件保存在當前 Project 的路徑下,則填寫 “$ProjectFileDir$”;要將 .py 文件保存在當前 Project 路徑下的 \program 子目錄中,則填寫 “$ProjectFileDir$\program”。
填好 CreateTool 窗口后,點擊 “OK” 即可完成 QtDesigner 工具的添加。
安裝和環境配置完成。
2. 菜單和工具欄
關于菜單與工具欄的操作,具體內容請詳見:Python 小白從零開始 PyQt5 項目實戰(2)菜單和工具欄。
2.1 創建主窗口
新建應用程序窗口,通常可以選擇 MainWindow 創建主窗口的圖形界面。
QtDesigner 創建的 “MainWindow” 是一個空白的圖形窗口,包括 centralwidget、menubar、statusbar 三個基本控件,可以在右側上方 “對象查看器” 查看這些控件及結構。
在 QtDesigner 中用鼠標選中主窗口,或者在右側的 “對象查看器” 中選中對象 “MainWindow”,此時右側中部的 “屬性編輯器” 將顯示對象 “MainWindow” 的屬性。在 “屬性編輯器” 內可以對對象的屬性進行編輯和修改。
在 QtDesigner 菜單中選擇:窗體 -> 預覽,就可以預覽設計的圖形界面,還可以選擇預覽不同操作系統的顯示效果。這使我們不需要編寫主程序就可以預覽圖形界面的顯示效果,以便進行修改。
2.2 建立菜單欄
創建一級菜單:
QtDesigner 創建的 “MainWindow” 圖形窗口,自動生成了頂部菜單欄 menubar,在圖形窗口左上角顯示有文本輸入框 “在這里輸入”。
輸入菜單對象(menu)的標題(title):
- 鼠標點擊文本輸入框 “在這里輸入”,再雙擊選中的控件,出現激活的文本輸入框;
- 輸入菜單標題后回車結束,就建立了一個一級菜單,例如:將菜單標題設為 “文件”。
輸入菜單對象的標題,以及修改菜單對象的屬性,更通用的方法是:
- 在 QtDesigner 右側的 “對象查看器” 中選中對象 “menu”,此時右側中部的 “屬性編輯器” 將顯示對象 “menu” 的屬性。
- 在 “屬性編輯器” 內選擇 “title” 屬性,將其修改為菜單標題:“文件”。
創建二級菜單:
QtDesigner 創建二級菜單,實際上是將動作(action)添加到一級菜單。
- 鼠標點擊一級菜單對象 “文件”,從下拉菜單選項選中 “在這里輸入”,輸入二級菜單的標題。
- 編輯動作 actionOpen 的屬性,可以將屬性 “text” 由 “Open” 修改為中文 “打開”。這時再點擊菜單 “文件”,下拉菜單中的動作 actionOpen 就顯示為中文 “打開”。
- 點擊二級菜單/動作 “打開”,在其右側有個 “+” 按鈕,點擊后可以創建新的下一級菜單。
2.3 建立工具欄
工具欄/工具條是圖形界面中的常用組件,將一組按鈕控件排成一行放在圖形窗口的頂部。
添加工具欄
- 單擊鼠標右鍵,選擇 “添加工具欄”。
- 也可以選擇 “Add Toolbar to Other Area”,將工具欄添加到窗口的左側、右側或底部。
添加和編輯動作對象
添加/編輯動作對象步驟為:
- 點擊 “動作編輯器” 子窗口工具欄的第一個圖標按鈕 “新建”,則彈出 “新建動作” 對話框;
- 雙擊 “動作編輯器” 中的動作對象,則彈出 “編輯動作” 對話框,可以編輯已有動作對象的屬性;
“新建動作” 與 “編輯動作” 對話框的結構是相同的,對照已有動作對象的屬性更容易理解 “新建動作” 對話框中屬性選項的含義:
- “文本” 指動作的標題,是控件的顯示內容,可以是中文或英文,例如 “打開(Open)”;
- “對象名稱” 指動作的名稱,是程序中調用對象的名稱,只能是英文,例如 “actionOpen”;
- “圖標” 指工具欄中所顯示的動作圖標,點擊 “▽\triangledown▽” 按鈕,選擇 “選擇文件” 選項,可以從文件夾中選擇圖標文件。
3. 信號與槽(Signals and slots)的連接
關于信號與槽的操作,具體內容請詳見:Python 小白從零開始 PyQt5 項目實戰(3)信號與槽的連接。
信號與槽機制是 PyQt 的核心機制,用于對象之間的通信,也就是實現函數之間的自動調用。
3.1 信號與槽的原理
簡單地說,將信號與槽函數連接后,當信號被觸發時,槽函數將被自動調用。
分析這個過程,涉及到幾個基本概念和關系:
- 信號:信號可以是一個動作,也可以是對象的一種狀態,用于觸發所連接的槽。
- 槽:槽就是一個函數,可以由連接的信號觸發。
- 發射信號:信號被發射時,自動調用信號連接的槽函數。通常,在對象的狀態改變時發射信號。
- 信號可以帶有參數,但必須與槽函數的參數相對應。
- 一個信號可以連接多個槽函數,多個信號也可以連接到一個槽函數。
- 一個信號可以連接到另一個信號上。
- 很多窗口部件(控件)內置了一下信號和槽,可以直接調用。也可以按需求自定義信號和槽。
3.2 信號發送者與槽的接收者
信號的發送者通常是一個控件對象,在控件對象的狀態發生變化時發送信號。常見的發送者是圖形窗口中的各種控件對象,但也可以是動作對象。
槽的接收者通常也是控件對象。槽函數是一個自定義的槽函數,或控件內置的槽函數。一般地,槽函數也有一個對象作為主體,即對于接受者這個控件對象執行函數定義的操作。例如槽函數執行的功能是關閉,哪么究竟是關閉那個控件呢?關閉對象就是接受者。
為了方便講解信號與槽的連接,我們用 QtDesigner 在上節設計的圖形窗口 uiDemo3.ui 的基礎上,增加幾個按鈕對象和文本行編輯對象:
-
打開 PyCharm,從 Tools -> ExternalTools -> QtDesigner 打開 QtDesigner,打開 uiDemo3.ui 文件。
-
鼠標點擊選中 QtDesigner 左側控件欄 Buttons 中的 PushButton,按住鼠標不放,將其拖動到中間的圖形界面后松開鼠標,就在圖形界面中創建了一個 PushButton 控件。
-
鼠標點擊選中 QtDesigner 左側控件欄 InputWidget 中的 LineEdit,按住鼠標不放,將其拖動到中間的圖形界面后松開鼠標,就在圖形界面中創建了一個 LineEdit 控件。
-
重復以上步驟,再建立幾個 PushButton 控件和 LineEdit 控件。
- 注意在 QtDesigner 右側 “對象查看器” 中所顯示的控件名稱和屬性,多個 PushButton、LineEdit 被自動賦予不同的命名(objectName),如:LineEdit_1、LineEdit_2、LineEdit_3,這就如同桌子有幾個抽屜分別標記為 “抽屜1”、“抽屜2”、“抽屜3” 以便識別。
- 控件的名稱和其它屬性都可以在 “屬性編輯器” 中編輯修改。
-
鼠標選中在圖形界面中創建的 PushButton 控件或 LineEdit 控件,可以拖動控件調整位置。
-
鼠標雙擊 PushButton 按鈕,可以編輯按鈕控件的標簽即按鈕上的顯示內容。
為了便于講解,本例將各 PushButton 控件的顯示內容(text 屬性)修改為:“1# 按鈕”~“4# 按鈕”,將各 LineEdit 控件的顯示內容(text 屬性)修改為:“文本編輯行-1”~“文本編輯行-3”。
3.3 QtDesigner 建立信號與槽的連接
信號與槽的連接有幾種不同情況:
- 不同的發送者與接收者,槽函數為控件的內置函數;
- 不同的發送者與接收者,槽函數為自定義函數;
- 相同的發送者與接收者,槽函數為控件的內置函數;
- 發送者是動作對象。
4. PyQt5 的基本控件
關于基本控件的操作,具體內容請詳見:Python 小白從零開始 PyQt5 項目實戰(4)基本控件。
4.1 PyQt5 的控件簡介
控件也稱控件對象,是 Qt用戶界面上最基本的組件類型,也是構成用戶界面的基本結構。用戶界面上顯示的所有內容都是控件,例如按鈕、標簽、文本框,又如菜單欄、工具欄、狀態欄,甚至整個窗口本身也是控件。
QWidget 類是 PyQt5 的基類,也是所有控件的父類。所有的 Qt 控件都是 QWidget 類的子類,因此都繼承了 QWidget 類的特性,可以接收用戶的輸入事件,如鼠標和鍵盤輸入,并可以在用戶界面上顯示控件內容,還可以存放其它控件。
4.2 編輯控件的屬性
控件具有屬性。不同類型的控件具有部分相同的屬性,也具有一些不同的專有屬性。
控件的相同屬性包括:名字,形狀,位置,大小,設置格式。控件的專用屬性包括:展示內容,接受輸入,用戶交互,日期,框架,等等。
所有的 Qt 控件都是 QWidget 類的子類,繼承了 QWidget 類的屬性。因此,我們學習控件可以按類進行學習,先學習其繼承的父類的通用屬性,再學習控件所特有的專有屬性。對于控件的學習就是一個類的繼承關系的結構圖。
我們以圖形界面 uiDemo5.ui 為例,介紹控件的通用屬性,并對控件的屬性進行編輯修改。
如前所述,QtDesigner 右側上方的 “對象查看器” 顯示了界面中的控件名稱和結構,下方的 “屬性編輯器” 顯示了選中的控件對象的各種屬性。在圖形界面中選擇某個控件,或者在 “對象查看器” 中選擇某個控件,在"屬性編輯器" 就會顯示該控件對象的屬性。
不論是窗口對象 MainWindow、菜單欄 menubar、工具欄 toolBar,還是按鈕 pushButton、編輯行 lineEdit,都有一些相同的屬性,例如:
- objectName:控件名,非常重要。準確的說是控件的 ID,Python 程序中訪問控件、控件交互都是使用 objectName。所有控件都必須具有唯一的 objectName,不能重名。不能使用中文字符。
- geometry:控件的大小和位置。
- 控件的寬度和高度可以修改,對于 MainWindow 來說控件的寬度/高度就是圖形界面程序窗口的寬度/高度。
- 控件位置 (X, Y) 是控件在窗口控件的坐標值,MainWindow 的控件位置不能修改,其它控件的位置 (X, Y) 可以根據需要修改。
- minimumSize、maximumSize 是主窗口大小拉伸后,控件對象的最小尺寸、最大尺寸。
- font:控件顯示的字體選擇,包括字體、字號、風格、效果等選項。
4.3 PyQt5 的控件類型
要了解 QtWidgets 類的子類,可以使用 “subclasses()” 將所有的子類打印出來,共有約 30個子類。
import PyQt5print(QtWidgets.QWidget.__subclasses__())這些控件類型,總體上可以分類如下:
-
輸入控件:
- 按鈕:QPushButton(按鍵按鈕),QToolButton(工具按鈕),QRadioButton(單選框),QCheckButton(多選框),QCommandLinkButton(連接命令的按鈕)
- 鍵盤輸入控件:QlineEdit(單行輸入),QTextEdit(多行輸入),QPlainTextEdit(普通多行輸入),QkeySequenceEdit(快捷鍵輸入)
- 調節輸入控件:QAbstractSpinBox(步長調節輸入),QDateEdit(日期輸入),QTimeEdit(時間輸入),QDateTimeEdit(日期和時間輸入)
- 數字調節框控件:QSpinBox(整型數字調節框),QDoubleSpinBox(浮點數字調節框)
- 滑動輸入控件:QDial(旋轉拖滑輸入),QSlider(直線拖動輸入),QScrollBar(滾動條),QRubberBand(橡皮筋拖拽)
- 下拉輸入控件:QComboBox(組合框下拉選項),QSlider(直線拖動輸入),QScrollBar(滾動條),QRubberBand(橡皮筋拖拽)
- 對話框輸入控件:QDialog(對話框),QColorDialog(顏色對話框),QFileDialog(文件對話框),QFontDialog(字體對話框),QInputDialog(輸入對話框)
- 日歷控件:QCalendarWidget(日期選擇部件)
-
顯示控件:
- 內容顯示控件:QLabel(顯示框),QLCDNumber(液晶顯示器),QProgressBar(進度條)
- 對話框顯示控件:QMessageBox(信息提示框),QErrorMessage(錯誤提示框),QProgressDialog(進度提示框)
-
高級控件:
- 容器控件:QToolBox,QDialogButtonBox,QGroupBox,QMdiSubWindow
- 結構控件:QMainWindow,QTabwidget,QStackedWidget,QSplitter,QDockWidget
- 滾動控件:QTextBrowser,QScrollArea,QAbstractItemView,QMdiarea,QGraphicsView
- 輔助控件:QFocusFrame,QSizeGrip,QDesktopWidget
- 其它控件
在 QtDesigner 左側的 “WidgetBox” 工具欄中,將常用的控件按類別進行分組。用鼠標將工具欄中的控件圖標拖拽到 QtDesigner 中間的圖形界面編輯窗口,就在圖像界面創建了一個所選擇的控件。
5. PyQt5 的基本布局管理
關于 PyQt5 的布局管理,具體內容請詳見:Python 小白從零開始 PyQt5 項目實戰(5)布局管理。
5.1 什么是布局管理
布局管理就是管理圖形窗口中各個部件的位置和排列。
網站、報紙要對發布的文章設置欄目、布局管理,使頁面整齊有序、美觀大方。圖形窗口中的大量部件也需要通過布局管理,對部件進行整理分組、排列定位,才能使界面友好。
圖形窗口中部件的位置有兩種模式來管理:絕對定位和局部類。
絕對定位就是指定部件相當于窗口的位置坐標 (X,Y) 和部件的高度、寬度。我們在此前文章中的例程,都是直接設置控件的位置和大小來管理的。
布局類則是使用各種布局方案進行布局管理。
PyQt5 提供了四種布局管理器:水平布局、垂直布局、柵格布局和表單布局。
在 QtDesigner 左側工具欄中,第一組工具 “Layout” 就是布局管理器,分別提供了 4種布局管理的工具按鈕:垂直布局(Vertical Layout)、水平布局(Horizontal Layout)、柵格布局(Grid Layout)和表單布局(Form Layout)。
5.2 水平布局(Horizontal Layout)
水平布局將多個控件在水平方向排列,控件之間的間隔相同。
QtDesigner 創建水平布局有兩種使用方法:方法一是先創建水平布局中的各個控件,然后將控件加入水平布局;方法二是先創建一個水平布局,再在該水平布局內依次創建各個控件。
以方法一為例創建水平布局:
- 先在窗口中創建幾個按鈕控件,控件位置可以任意布置,圖形窗口顯示與上圖絕對定位時類似;
- 點擊鼠標左鍵并拖拽拉伸,全部選中創建的幾個按鈕控件,此時每個按鈕控件周圍都出現定位小方塊,這些按鈕控件都處于選中狀態;
- 點擊鼠標右鍵,喚出下拉菜單,選擇 “布局” -> “水平布局” 選項;或者直接按 “Ctrl+1” 快捷鍵,就為選中的控件創建了一個水平布局。
添加到水平布局框中的控件,其大小和位置是由水平布局框自動設置的。布局框中控件的大小和位置屬性,不能在 “屬性編輯器” 中直接進行編輯修改。
如果自動布局的按鈕位置不合適,可以在布局框中添加間隔控制器 “Horizontal Spacer”,以調整按鈕控件的間隔。
如下圖所示,在上方的水平布局框中,多個按鈕控件在水平方向排列,控件之間的間隔相同。在下方的水平布局框的頂部和底部分別添加了一個間隔控制器,將按鈕控件調整到所需的位置。
5.3 垂直布局(Vertical Layout)
垂直布局將多個控件在垂直方向排列,控件之間的間隔相同。
與水平布局類似,QtDesigner 創建垂直布局有兩種使用方法:方法一是先創建垂直布局中的各個控件,然后將控件加入垂直布局;方法二是先創建一個垂直布局,再在該垂直布局內依次創建各個控件。
以方法二為例創建垂直布局:
- 在 QtDesigner 左側工具欄的 “Layout” 類中,鼠標點擊選擇垂直布局按鈕 “Vertical Layout” 后,將其拖動至中間的圖形窗口內;
- 此時在圖形窗口中出現一個紅色直線矩形框,表示所創建的垂直布局框。鼠標選中垂直布局框,在控件邊界處出現幾個藍色的小方塊,拖動藍色方塊可以調整布局框大小;
- 從 QtDesigner 左側工具欄中,選擇按鈕控件或其它控件,并拖動到圖形窗口中的垂直布局框區域內,就將創建的控件添加到垂直布局框。
添加到垂直布局框中的控件,其大小和位置是由垂直布局框自動設置的。布局框中控件的大小和位置屬性,不能在 “屬性編輯器” 中編輯修改。
如果自動布局的按鈕位置不合適,可以在布局框中添加間隔控制器 “Vertical Spacer”,以調整按鈕控件的間隔。
如下圖所示,在左側的垂直布局框中,多個按鈕控件在垂直方向排列,控件之間的間隔相同。在右側的垂直布局框的頂部和底部分別添加了一個間隔控制器,將按鈕控件調整到所需的位置。
5.4 嵌套布局
嵌套布局是指在一個布局內嵌套其它布局,可以實現在一個窗口中綜合應用多種布局。
例如,整個窗口采用水平布局,分為左右兩部分,左側采用垂直布局,右側采用柵格布局。但如下圖所示,布局效果不盡人意。窗口水平布局雖然分為左右兩部分,但水平布局器自動設置為等幅面、等間隔。即使使用間隔器進行調整,也難以達到滿意的效果。
5.5 容器布局
容器布局將容器控件(Container)與布局管理器結合,先用容器控件將窗口分為若干區域,再在每個區域內加入布局管理器。
建立容器控件后,可以直接將其它控件加入容器控件內;也可以在容器控件加入布局管理器,再向布局管理器加入多個控件,使多個控件按布局要求放在容器中。
- 首先在 QtDesigner 左側工具欄的 “Containers” 類中,選擇 “Frame” 控件或 “Widget” 控件將其拖動至中間的圖形窗口中,創建容器控件。
- 對圖形窗口中的容器控件 “Frame” 或 “Widget”,可以選中后用鼠標拖動、拉伸來調整控件的位置和大小,或者在 “屬性編輯器” 中設置 (X, Y)、寬度、高度屬性。
- 對于需要進行布局管理的容器控件,從在 QtDesigner 左側工具欄的 “Laytout” 類中選擇所需的布局管理器控件,將其拖動至容器控件中,創建容器控件的布局管理器。
容器布局就像網站、報刊中的欄目、子版,可以按照編輯的要求便捷、自由地進行布局。例如,我們要將程序窗口按照十字分割方案分為上下和左右四個部分,就在窗口先創建四個 “Frame” 容器控件,并調整其位置和大小,然后向一個或幾個 “Frame” 容器控件加入所需的布局管理控件。如下圖所示,可以實現對程序窗口的自由分割和布局。
進一步地,對每個 “Frame” 容器控件,依次添加輸入輸出控件。對于設置布局管理的容器,添加的控件按照布局設置自動排列在容器的空間內。
6. 多窗口切換的堆疊布局
關于 PyQt5 的布局管理,具體內容請詳見:Python 小白從零開始 PyQt5 項目實戰(6)窗口切換的堆疊布局。
6.1 什么是堆疊布局(Stacked Layout)
布局管理就是管理圖形窗口中各個部件的位置和排列。圖形窗口中的大量部件也需要通過布局管理,對部件進行整理分組、排列定位,才能使界面友好。上一篇文中我們介紹了基本的水平布局、垂直布局、柵格布局、表格布局和進階的嵌套布局和容器布局。
在容器布局中,通過容器控件(Containers)與布局管理器(Layouts)的結合,可以實現對程序窗口的分割和布局,就可以自由設計各種豐富的圖形界面。
在實際的軟件項目中,通常需要多種/多個不同的圖形界面,以適應不同的任務場景。如何實現多窗口圖形界面的需求呢?大致來說有幾種思路:
-
使用彈出窗口。主窗口提供基本界面,通過彈出窗口實現子任務界面,子任務結束后關閉彈出窗口回到主窗口。
這是一種可行的,也比較簡單的處理方案,很多應用程序中都設有彈出窗口。但是頻繁彈出和關閉窗口的用戶體驗不好,而且在窗口之間的切換不方便。 -
重建圖形界面。當調用新的圖形界面時,關閉后刪除現有界面上的所有控件,再新建需要的各種控件。
這種方案雖然可行,但是編程復雜、浪費資源、容易出錯,難以適應多窗口相互切換的要求,因此很少使用。在 QtDesigner 中也不支持這種方案的操作。 -
通過堆疊布局實現多窗口切換。堆疊布局是在窗口的整體或局部區域設置多組圖形界面,根據需要使用指定的圖形界面。
打個比方,這就好比戲劇或拍照中準備了多種背景幕布,需要什么場景,就展開所需的場景幕布,而把其它幕布收起來。
QStackedLayout 類提供了多頁面切換的堆疊布局。
- 選項卡控件(QTackedWidget)提供了選項卡對話框,外觀類似于瀏覽器頁面打開多個標簽頁。選項卡控件允許創建多個對話框頁面,每個頁面帶有自己的標簽。使用時點擊標簽行進行選擇,就打開對應的對話框頁面,不需要另外編程。
- 堆疊窗口控件(QStackedWidget)提供了更加通用和靈活的多窗口、多頁面切換的解決方案。QStackedWidget 控件可以添加在整個窗口或窗口中的任意區域,允許在堆疊窗口區域內設計多個頁面,在程序控制使用指定的窗口界面。
- 堆疊窗口控件(QStackedWidget)需要在主程序中通過編程來控制顯示的圖形界面,相對于選項卡控件(QTackedWidget) 來說比較復雜,但因此也更加靈活。
6.2 創建多窗口切換的堆疊布局
- (1)以上文 uiDemo6.ui 為基礎:圖形窗口的左側上部為垂直布局的按鈕控件區域 leftLayout_1,設有多個按鈕控件,用于選擇不同的業務;左側下部為垂直布局的文本區域 leftLayout_2,設有文本顯示框。
- (2)將圖形窗口右側的主體區域設計為堆疊窗口,用于設計多個圖形界面,以適應不同的業務場景:
- 在 QtDesigner 左側工具欄 “Containers” 類中,選擇 “Stacked Widget” 控件,將其拖動至設計的圖形窗口中,創建堆疊布局的容器控件。
- 對窗口中的堆疊容器 “Stacked Widget”,選中后可以用鼠標拖動、拉伸來調整控件的位置和大小,或者在 “屬性編輯器” 中設置 (X, Y)、寬度、高度屬性。
- 堆疊容器 “Stacked Widget” 自動建立了 2個頁面。鼠標位于堆疊容器 “Stacked Widget” ,右鍵喚出下拉菜單,選擇 "插入頁"可以插入新的頁面,選擇 “改變頁順序” 可以調整各頁面的順序。
- 在控件的右上角顯示有一對黑色三角符號,可以在多個頁面之間切換,也可以在 “對象查看器” 中選擇要編輯的頁面。
- (3)堆疊容器 “Stacked Widget” 中各頁面的設計,具體設計內容是根據業務需要確定的。
- page_0 的設計:標簽控件 label_1 用于顯示封面圖片,按鈕控件 pushButton_6~8 用于控制翻頁;
- page_1 的設計:水平布局的標簽控件 label_2、label_3 用于顯示原始圖片和處理圖片,控件用于控制處理方法和參數,按鈕控件 pushButton_9~11 用于控制翻頁;
- page_2 的設計:表格控件 tableWidget 控件用于顯示表格數據,按鈕控件用于控制。
6.3 堆疊布局的主程序設計
使用堆疊窗口控件(QStackedWidget)建立的堆疊布局界面,要在主程序中通過編程控制顯示哪一個圖形界面。
6.3.1 多頁面切換的方法
QStackedWidget 類繼承自 QFrame類。QStackedWidget 類提供了多頁面切換的布局,一次只能看到一個界面。
使用如下程序可以設置 page_0 為當前顯示的頁面:
pageNo = 0 # 設置 page_0 為索引頁(第一頁面)self.stackedWidget.setCurrentIndex(pageNo) # 設置使用 pageNo=0 作為當前顯示頁面需要注意的是,不論我們為每個頁面控件設置的名稱(objectName)是什么,在 QStackedWidget 類中定義的頁面索引 index 都是一個從 0 開始計數,即:第一頁面的索引值 index=0,第二頁面的索引值 index=1,…。
因此,為了避免混淆,建議將 StackedWidge 控件的第一頁面命名為 objectName: page_0,第二頁面命名為 objectName: page_1,…
6.3.2 建立信號/槽連接
建立信號/槽連接,既可以在 QtDesigner 中設置,也可以在主程序中通過程序實現。
6.3.3 頁面控制程序
通過編程控制堆疊窗口控件的顯示頁面,就是說當前顯示哪一個圖形界面。
一種簡單的方法是,在任務場景的子程序中,直接使用 setCurrentIndex() 設置選擇堆疊控件的顯示頁面。通俗的說就是,任務需要使用哪個場景時,就在程序中編寫頁面設置語句進行選擇。例如:
def click_pushButton_1(self): # 點擊 pushButton_1 觸發self.textEdit.append("當前動作:click_pushButton_1")self.textEdit.append("選擇堆疊布局頁面:page_0")self.stackedWidget.setCurrentIndex(0) # 打開 stackedWidget > page_0self.label_1.setPixmap(QtGui.QPixmap("../image/fractal01.png"))return6.3.4 堆疊布局中的控件操作
控件操作包括控件發出信號和在槽函數中進行操作。
在用戶編寫的程序中,需要接收控件信號、或在槽函數中對控件進行操作,都要通過控件的 objectName 來實現。
例如,點擊按鈕 “第一章”(pushButton_1),就選擇堆疊布局頁面 “page_0”;要在標簽控件 “label_1” 顯示圖片 “…/image/fractal01.png”,就使用以下的程序:
self.label_1.setPixmap(QtGui.QPixmap("../image/fractal01.png"))而對于堆疊布局頁面 “page_0” 中的按鈕控件 “上一張”、“下一張”、“返回”,要實現點擊按鈕時執行相應的任務,則應以控件的 objectName 建立觸發信號與槽函數的連接。
7. 折疊側邊欄的實現
關于折疊側邊欄的實現,具體請詳見:Python 小白從零開始 PyQt5 項目實戰(7)折疊側邊欄的實現。
7.1 什么是折疊側邊欄
折疊側邊欄在實際項目中也非常實用,可以實現軟件功能或目錄的導航。
折疊側邊欄,是指可折疊的多級菜單式狀態欄,位于于窗口的左右側邊。
折疊側邊欄也稱為垂直多級菜單,因此其外觀、功能與操作與菜單欄基本相似。
折疊側邊欄通常只展開第一級目錄(根目錄)的內容,可以顯示文本、圖標和按鍵,點擊上一級目錄可以展開或折疊下一級的目錄。點擊最底層目錄可以完成指定的操作,如執行所連接的槽函數。
折疊側邊欄的形式多樣,如網站導航、資源管理器的目錄形式,或手風琴形式、滑動菜單形式、按鍵列表形式。
QtDesigner 提供了多種部件,可以實現不同形式的折疊側邊欄。
樹結構部件 Tree View 和 Tree Widget 可以建立目錄樹結構的側邊欄,二者分別基于模型(Model)和項目(Item), Tree Widget 是 Tree View 的子類。
抽屜結構部件 ToolBox 是一種容器布局控件,可以建立菜單形式或按鍵列表形式的側邊欄。
7.2 目錄結構的折疊側邊欄
目錄結構的折疊側邊欄的外觀和使用類似于資源管理器中的目錄管理。
使用 QtDesigner 建立目錄結構的折疊側邊欄的步驟如下:
- (1)以上文 uiDemo8.ui 為基礎,在圖形窗口的左側創建一個垂直布局器 leftLayout,在圖形窗口的中間和右側創建一個堆疊布局器 stackedWidget。堆疊布局的頁面布局和設計詳見上文,本文不作贅述。
- (2)在 QtDesigner 左側工具欄 “ItemWidgets” 類中,選擇樹窗口部件 “Tree Widget”,將其拖動至垂直布局器 leftLayout 中,就創建一個樹窗口部件,將部件名(objectName)設為 “treeWidget”。
- (3)樹窗口部件 “treeWidget” 的屬性編輯:
- 樹窗口部件 “treeWidget” 的大小、位置屬性編輯與其它控件類似,選中后可以用鼠標拖動拉伸,或在屬性編輯器中修改;
- 鼠標選中樹結構控件 “treeWidget”,右鍵喚出下拉菜單,選擇 “編輯項目”,彈出 “編輯樹窗口部件” 對話框;
- 對話框中 “列?” 選項:“treeWidget” 可以設置一列或多列,本例中只需要設置一列,編輯列名,如:“章節目錄”;
- 對話框中 “項目(I)” 選項:通過對話框左下方的按鈕添加具體的目錄信息,其中 “+” 用于添加項目,"-" 用于刪除項目,“L+” 用于建立并添加下一級的目錄信息。編輯完成后點擊 “OK” 保存。
通常我們希望用戶在點擊側邊欄的目錄項目時,應用程序能自動執行該項目的操作,這就需要通過編程實現信號/槽的連接。
對樹窗口部件 “treeWidget”,可以將鼠標單擊或雙擊作為觸發信號連接到槽函數。例如,點擊樹窗口部件的目錄項 item 時觸發信號 itemClicked,執行自定義的槽函數 click_treeWidget()。
但是,樹窗口部件 “treeWidget” 是以其整體作為一個控件,不能將目錄中每一個項目(item)的鼠標單擊或雙擊作為觸發信號連接到一個槽函數,進而執行每個項目各自定義的功能操作。因此,需要在槽函數中判別鼠標所點擊的當前項 currentItem,然后再分別執行對應的操作。
相關例程可參見:Python 小白從零開始 PyQt5 項目實戰(7)折疊側邊欄的實現。
7.3 垂直菜單結構折疊側邊欄
垂直菜單結構的折疊側邊欄類似于多級菜單管理,可以實現手風琴、滑動菜單、按鍵列表形式的側邊欄。
使用 QtDesigner 建立垂直菜單結構的折疊側邊欄的步驟如下:
- (1)以上文 uiDemo8.ui 為基礎,在圖形窗口的左側創建垂直菜單結構的折疊側邊欄,在圖形窗口的中間和右側創建一個堆疊布局器 stackedWidget。堆疊布局的頁面布局和設計詳見上文,本文不作贅述。
- (2)在 QtDesigner 左側工具欄 “Containers” 類中,選擇抽屜部件 “Tool Box”,將其拖動至圖形窗口的左側的適當位置,就創建一個垂直菜單部件,將部件名(objectName)設為 “toolBox”。
- 新建的垂直菜單部件 “toolBox” 中建立了兩個菜單形狀的頁面,顯示為 “Page 1”、“Page 2”,相當于一級菜單的顯示內容;
- 添加菜單頁面:鼠標選中垂直菜單部件 “toolBox”,右鍵喚出下拉菜單,選擇 “插入頁” ->“在當前頁之后/前”,可以插入菜單頁面;
- 整理菜單頁面:鼠標選中垂直菜單部件 “toolBox”,右鍵喚出下拉菜單,選擇 “頁 *” 可以刪除菜單頁面,選擇 “改變頁次序” 可以喚出對話框改變各頁面的順序;
- 切換當前菜單項:在編輯或使用狀態下,都可以點擊每個菜單項而將其切換為當前項。當前項的下方有一塊空白區域可以插入下級菜單或控件,而非當前項的菜單欄是折疊的。
- (3)垂直菜單部件 “toolBox” 的屬性編輯:
- 垂直菜單部件 “toolBox” 的大小、位置屬性編輯與其它控件類似,選中后可以用鼠標拖動拉伸,或在屬性編輯器中修改;
- 鼠標選中垂直菜單部件 “toolBox”,點擊 “Page 1” 后從 QtDesigner 右側的 “屬性編輯器” 中找到 QToolBox -> currentItemName 可以修改當前項 “Page 1” 的 objectName(該屬性不是所顯示的文本內容,不支持中文)、QToolBox -> currentItemText 修改當前項 “Page 1” 的顯示內容(支持中文);
- 類似地,鼠標選中垂直菜單部件 “toolBox”,點擊 “Page 2”、… 后可以在 QtDesigner 右側的 “屬性編輯器” 中修改當前項 “Page 2”、… 的 objectName 及顯示內容 “currentItemText”;
- (4)創建下級菜單控件:
- 垂直菜單部件 “toolBox” 只建立一級菜單(根目錄),并不建立下級菜單;
- 建立下級菜單控件:點擊 “toolBox” 中的菜單項將其切換為當前項,當前項的下方出現一塊空白區域,在該空白區域內可以自由添加布局、容器或控件。
- 本例中向 “toolBox” 中的每個菜單項添加一個垂直布局器(Vertical Layout),再向該垂直布局器中插入一個或多個按鍵控件(Push Button)作為二級菜單。
上述的創建垂直菜單部件和二級菜單控件的步驟如下圖所示:
上節所建立垂直菜單結構的折疊側邊欄,可折疊的一級菜單是由抽屜部件 “Tool Box” 實現的,而二級菜單是由一組按鍵控件 “Push Button” 實現的。
如同堆疊布局各頁面中的每個按鍵控件是相互獨立的不同的控件,垂直菜單結構中的二級菜單按鍵控件也都是相互獨立的不同的控件。這些控件必須具有唯一的 objectName,但可以具有相同的顯示內容 “Button Text”。換句話說,在不同的一級菜單項下可能會出現相同顯示內容的按鍵控件,但將被定義為不同 objectName 的按鍵控件。
由于這種垂直菜單結構的二級菜單都是獨立的按鍵控件,因此建立信號/槽連接的方法,與圖形界面中的普通控件的操作是相同的。
對二級菜單按鍵控件建立了信號/槽連接,就可以在相應的槽函數執行所需的各種操作,而不需要任何判別或控制程序。
8. 項目實戰完整例程
8.1 項目圖形界面效果
8.2 UI程序(uiDemo11.py)
# Form implementation generated from reading ui file 'uiDemo11.ui' # # Created by: PyQt5 UI code generator 5.15.4 # # WARNING: Any manual changes made to this file will be lost when pyuic5 is # run again. Do not edit this file unless you know what you are doing. # Copyright 2021 youcans, XUPTfrom PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_MainWindow(object):def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")MainWindow.resize(1080, 768)MainWindow.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))icon = QtGui.QIcon()icon.addPixmap(QtGui.QPixmap("C:/Users/David/.designer/image/youcans.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)MainWindow.setWindowIcon(icon)self.centralwidget = QtWidgets.QWidget(MainWindow)self.centralwidget.setObjectName("centralwidget")self.line = QtWidgets.QFrame(self.centralwidget)self.line.setGeometry(QtCore.QRect(150, 0, 20, 680))self.line.setFrameShape(QtWidgets.QFrame.VLine)self.line.setFrameShadow(QtWidgets.QFrame.Sunken)self.line.setObjectName("line")self.stackedWidget = QtWidgets.QStackedWidget(self.centralwidget)self.stackedWidget.setGeometry(QtCore.QRect(170, 0, 900, 680))self.stackedWidget.setObjectName("stackedWidget")self.page_0 = QtWidgets.QWidget()self.page_0.setObjectName("page_0")self.label_1 = QtWidgets.QLabel(self.page_0)self.label_1.setGeometry(QtCore.QRect(50, 0, 800, 600))self.label_1.setText("")self.label_1.setPixmap(QtGui.QPixmap("../image/iconJpeg.png"))self.label_1.setAlignment(QtCore.Qt.AlignCenter)self.label_1.setObjectName("label_1")self.stackedWidget.addWidget(self.page_0)self.page_1 = QtWidgets.QWidget()self.page_1.setObjectName("page_1")self.label_2 = QtWidgets.QLabel(self.page_1)self.label_2.setGeometry(QtCore.QRect(20, 20, 400, 300))self.label_2.setText("")self.label_2.setPixmap(QtGui.QPixmap("../image/iconPng.png"))self.label_2.setAlignment(QtCore.Qt.AlignCenter)self.label_2.setObjectName("label_2")self.label_3 = QtWidgets.QLabel(self.page_1)self.label_3.setGeometry(QtCore.QRect(450, 20, 400, 300))self.label_3.setText("")self.label_3.setPixmap(QtGui.QPixmap("../image/iconPng.png"))self.label_3.setAlignment(QtCore.Qt.AlignCenter)self.label_3.setObjectName("label_3")self.formLayoutWidget = QtWidgets.QWidget(self.page_1)self.formLayoutWidget.setGeometry(QtCore.QRect(90, 430, 271, 131))self.formLayoutWidget.setObjectName("formLayoutWidget")self.formLayout_1 = QtWidgets.QFormLayout(self.formLayoutWidget)self.formLayout_1.setContentsMargins(0, 0, 0, 0)self.formLayout_1.setObjectName("formLayout_1")self.label_11 = QtWidgets.QLabel(self.formLayoutWidget)self.label_11.setMinimumSize(QtCore.QSize(100, 35))font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(11)self.label_11.setFont(font)self.label_11.setObjectName("label_11")self.formLayout_1.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label_11)self.spinBox = QtWidgets.QSpinBox(self.formLayoutWidget)self.spinBox.setMinimumSize(QtCore.QSize(0, 35))self.spinBox.setObjectName("spinBox")self.formLayout_1.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.spinBox)self.label_12 = QtWidgets.QLabel(self.formLayoutWidget)self.label_12.setMinimumSize(QtCore.QSize(100, 35))font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(11)self.label_12.setFont(font)self.label_12.setObjectName("label_12")self.formLayout_1.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label_12)self.spinBox_2 = QtWidgets.QSpinBox(self.formLayoutWidget)self.spinBox_2.setMinimumSize(QtCore.QSize(0, 35))self.spinBox_2.setObjectName("spinBox_2")self.formLayout_1.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.spinBox_2)self.label_13 = QtWidgets.QLabel(self.formLayoutWidget)self.label_13.setMinimumSize(QtCore.QSize(100, 35))font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(11)self.label_13.setFont(font)self.label_13.setObjectName("label_13")self.formLayout_1.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_13)self.spinBox_3 = QtWidgets.QSpinBox(self.formLayoutWidget)self.spinBox_3.setMinimumSize(QtCore.QSize(0, 35))self.spinBox_3.setObjectName("spinBox_3")self.formLayout_1.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.spinBox_3)self.formLayoutWidget_2 = QtWidgets.QWidget(self.page_1)self.formLayoutWidget_2.setGeometry(QtCore.QRect(470, 430, 271, 131))self.formLayoutWidget_2.setObjectName("formLayoutWidget_2")self.formLayout_2 = QtWidgets.QFormLayout(self.formLayoutWidget_2)self.formLayout_2.setContentsMargins(0, 0, 0, 0)self.formLayout_2.setObjectName("formLayout_2")self.label_14 = QtWidgets.QLabel(self.formLayoutWidget_2)self.label_14.setMinimumSize(QtCore.QSize(100, 35))font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(11)self.label_14.setFont(font)self.label_14.setObjectName("label_14")self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label_14)self.spinBox_4 = QtWidgets.QSpinBox(self.formLayoutWidget_2)self.spinBox_4.setMinimumSize(QtCore.QSize(0, 35))self.spinBox_4.setObjectName("spinBox_4")self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.spinBox_4)self.label_15 = QtWidgets.QLabel(self.formLayoutWidget_2)self.label_15.setMinimumSize(QtCore.QSize(100, 35))font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(11)self.label_15.setFont(font)self.label_15.setObjectName("label_15")self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label_15)self.spinBox_5 = QtWidgets.QSpinBox(self.formLayoutWidget_2)self.spinBox_5.setMinimumSize(QtCore.QSize(0, 35))self.spinBox_5.setObjectName("spinBox_5")self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.spinBox_5)self.label_16 = QtWidgets.QLabel(self.formLayoutWidget_2)self.label_16.setMinimumSize(QtCore.QSize(100, 35))font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(11)self.label_16.setFont(font)self.label_16.setObjectName("label_16")self.formLayout_2.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_16)self.spinBox_6 = QtWidgets.QSpinBox(self.formLayoutWidget_2)self.spinBox_6.setMinimumSize(QtCore.QSize(0, 35))self.spinBox_6.setObjectName("spinBox_6")self.formLayout_2.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.spinBox_6)self.stackedWidget.addWidget(self.page_1)self.page_2 = QtWidgets.QWidget()self.page_2.setObjectName("page_2")self.label_4 = QtWidgets.QLabel(self.page_2)self.label_4.setGeometry(QtCore.QRect(20, 20, 400, 300))self.label_4.setText("")self.label_4.setPixmap(QtGui.QPixmap("../image/iconPng.png"))self.label_4.setAlignment(QtCore.Qt.AlignCenter)self.label_4.setObjectName("label_4")self.label_5 = QtWidgets.QLabel(self.page_2)self.label_5.setGeometry(QtCore.QRect(450, 20, 400, 300))self.label_5.setText("")self.label_5.setPixmap(QtGui.QPixmap("../image/iconPng.png"))self.label_5.setAlignment(QtCore.Qt.AlignCenter)self.label_5.setObjectName("label_5")self.label_6 = QtWidgets.QLabel(self.page_2)self.label_6.setGeometry(QtCore.QRect(20, 350, 400, 300))self.label_6.setText("")self.label_6.setPixmap(QtGui.QPixmap("../image/iconPng.png"))self.label_6.setAlignment(QtCore.Qt.AlignCenter)self.label_6.setObjectName("label_6")self.label_7 = QtWidgets.QLabel(self.page_2)self.label_7.setGeometry(QtCore.QRect(450, 350, 400, 300))self.label_7.setText("")self.label_7.setPixmap(QtGui.QPixmap("../image/iconPng.png"))self.label_7.setAlignment(QtCore.Qt.AlignCenter)self.label_7.setObjectName("label_7")self.stackedWidget.addWidget(self.page_2)self.toolBox = QtWidgets.QToolBox(self.centralwidget)self.toolBox.setGeometry(QtCore.QRect(10, 10, 141, 351))self.toolBox.setMinimumSize(QtCore.QSize(0, 351))self.toolBox.setStyleSheet("font: 10pt \"Arial\";")self.toolBox.setLineWidth(8)self.toolBox.setObjectName("toolBox")self.page_T1 = QtWidgets.QWidget()self.page_T1.setGeometry(QtCore.QRect(0, 0, 141, 171))self.page_T1.setMinimumSize(QtCore.QSize(0, 30))self.page_T1.setObjectName("page_T1")self.verticalLayoutWidget_4 = QtWidgets.QWidget(self.page_T1)self.verticalLayoutWidget_4.setGeometry(QtCore.QRect(0, 0, 131, 140))self.verticalLayoutWidget_4.setObjectName("verticalLayoutWidget_4")self.layout_T1 = QtWidgets.QVBoxLayout(self.verticalLayoutWidget_4)self.layout_T1.setContentsMargins(0, 0, 0, 0)self.layout_T1.setObjectName("layout_T1")self.pushButton_01 = QtWidgets.QPushButton(self.verticalLayoutWidget_4)sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)sizePolicy.setHorizontalStretch(0)sizePolicy.setVerticalStretch(0)sizePolicy.setHeightForWidth(self.pushButton_01.sizePolicy().hasHeightForWidth())self.pushButton_01.setSizePolicy(sizePolicy)self.pushButton_01.setMinimumSize(QtCore.QSize(60, 25))self.pushButton_01.setMaximumSize(QtCore.QSize(160, 60))self.pushButton_01.setObjectName("pushButton_01")self.layout_T1.addWidget(self.pushButton_01)self.pushButton_02 = QtWidgets.QPushButton(self.verticalLayoutWidget_4)sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)sizePolicy.setHorizontalStretch(0)sizePolicy.setVerticalStretch(0)sizePolicy.setHeightForWidth(self.pushButton_02.sizePolicy().hasHeightForWidth())self.pushButton_02.setSizePolicy(sizePolicy)self.pushButton_02.setMinimumSize(QtCore.QSize(60, 25))self.pushButton_02.setMaximumSize(QtCore.QSize(160, 60))self.pushButton_02.setObjectName("pushButton_02")self.layout_T1.addWidget(self.pushButton_02)self.pushButton_03 = QtWidgets.QPushButton(self.verticalLayoutWidget_4)sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)sizePolicy.setHorizontalStretch(0)sizePolicy.setVerticalStretch(0)sizePolicy.setHeightForWidth(self.pushButton_03.sizePolicy().hasHeightForWidth())self.pushButton_03.setSizePolicy(sizePolicy)self.pushButton_03.setMinimumSize(QtCore.QSize(60, 25))self.pushButton_03.setMaximumSize(QtCore.QSize(160, 60))self.pushButton_03.setObjectName("pushButton_03")self.layout_T1.addWidget(self.pushButton_03)self.pushButton_04 = QtWidgets.QPushButton(self.verticalLayoutWidget_4)sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)sizePolicy.setHorizontalStretch(0)sizePolicy.setVerticalStretch(0)sizePolicy.setHeightForWidth(self.pushButton_04.sizePolicy().hasHeightForWidth())self.pushButton_04.setSizePolicy(sizePolicy)self.pushButton_04.setMinimumSize(QtCore.QSize(60, 25))self.pushButton_04.setMaximumSize(QtCore.QSize(160, 60))self.pushButton_04.setObjectName("pushButton_04")self.layout_T1.addWidget(self.pushButton_04)self.toolBox.addItem(self.page_T1, "")self.page_T2 = QtWidgets.QWidget()self.page_T2.setGeometry(QtCore.QRect(0, 0, 141, 171))self.page_T2.setObjectName("page_T2")self.verticalLayoutWidget_2 = QtWidgets.QWidget(self.page_T2)self.verticalLayoutWidget_2.setGeometry(QtCore.QRect(0, 0, 131, 140))self.verticalLayoutWidget_2.setObjectName("verticalLayoutWidget_2")self.layout_T2 = QtWidgets.QVBoxLayout(self.verticalLayoutWidget_2)self.layout_T2.setContentsMargins(0, 0, 0, 0)self.layout_T2.setObjectName("layout_T2")self.pushButton_05 = QtWidgets.QPushButton(self.verticalLayoutWidget_2)sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)sizePolicy.setHorizontalStretch(0)sizePolicy.setVerticalStretch(0)sizePolicy.setHeightForWidth(self.pushButton_05.sizePolicy().hasHeightForWidth())self.pushButton_05.setSizePolicy(sizePolicy)self.pushButton_05.setMinimumSize(QtCore.QSize(60, 25))self.pushButton_05.setMaximumSize(QtCore.QSize(160, 60))self.pushButton_05.setObjectName("pushButton_05")self.layout_T2.addWidget(self.pushButton_05)self.pushButton_06 = QtWidgets.QPushButton(self.verticalLayoutWidget_2)sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)sizePolicy.setHorizontalStretch(0)sizePolicy.setVerticalStretch(0)sizePolicy.setHeightForWidth(self.pushButton_06.sizePolicy().hasHeightForWidth())self.pushButton_06.setSizePolicy(sizePolicy)self.pushButton_06.setMinimumSize(QtCore.QSize(60, 25))self.pushButton_06.setMaximumSize(QtCore.QSize(160, 60))self.pushButton_06.setObjectName("pushButton_06")self.layout_T2.addWidget(self.pushButton_06)self.pushButton_08 = QtWidgets.QPushButton(self.verticalLayoutWidget_2)sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)sizePolicy.setHorizontalStretch(0)sizePolicy.setVerticalStretch(0)sizePolicy.setHeightForWidth(self.pushButton_08.sizePolicy().hasHeightForWidth())self.pushButton_08.setSizePolicy(sizePolicy)self.pushButton_08.setMinimumSize(QtCore.QSize(60, 25))self.pushButton_08.setMaximumSize(QtCore.QSize(160, 60))self.pushButton_08.setObjectName("pushButton_08")self.layout_T2.addWidget(self.pushButton_08)self.pushButton_07 = QtWidgets.QPushButton(self.verticalLayoutWidget_2)sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)sizePolicy.setHorizontalStretch(0)sizePolicy.setVerticalStretch(0)sizePolicy.setHeightForWidth(self.pushButton_07.sizePolicy().hasHeightForWidth())self.pushButton_07.setSizePolicy(sizePolicy)self.pushButton_07.setMinimumSize(QtCore.QSize(60, 25))self.pushButton_07.setMaximumSize(QtCore.QSize(160, 60))self.pushButton_07.setObjectName("pushButton_07")self.layout_T2.addWidget(self.pushButton_07)self.toolBox.addItem(self.page_T2, "")self.page_T3 = QtWidgets.QWidget()self.page_T3.setGeometry(QtCore.QRect(0, 0, 141, 171))self.page_T3.setObjectName("page_T3")self.verticalLayoutWidget_5 = QtWidgets.QWidget(self.page_T3)self.verticalLayoutWidget_5.setGeometry(QtCore.QRect(0, 0, 131, 140))self.verticalLayoutWidget_5.setObjectName("verticalLayoutWidget_5")self.layout_T3 = QtWidgets.QVBoxLayout(self.verticalLayoutWidget_5)self.layout_T3.setContentsMargins(0, 0, 0, 0)self.layout_T3.setObjectName("layout_T3")self.pushButton_09 = QtWidgets.QPushButton(self.verticalLayoutWidget_5)sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)sizePolicy.setHorizontalStretch(0)sizePolicy.setVerticalStretch(0)sizePolicy.setHeightForWidth(self.pushButton_09.sizePolicy().hasHeightForWidth())self.pushButton_09.setSizePolicy(sizePolicy)self.pushButton_09.setMinimumSize(QtCore.QSize(60, 25))self.pushButton_09.setMaximumSize(QtCore.QSize(160, 60))self.pushButton_09.setObjectName("pushButton_09")self.layout_T3.addWidget(self.pushButton_09)self.pushButton_10 = QtWidgets.QPushButton(self.verticalLayoutWidget_5)sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)sizePolicy.setHorizontalStretch(0)sizePolicy.setVerticalStretch(0)sizePolicy.setHeightForWidth(self.pushButton_10.sizePolicy().hasHeightForWidth())self.pushButton_10.setSizePolicy(sizePolicy)self.pushButton_10.setMinimumSize(QtCore.QSize(60, 25))self.pushButton_10.setMaximumSize(QtCore.QSize(160, 60))self.pushButton_10.setObjectName("pushButton_10")self.layout_T3.addWidget(self.pushButton_10)self.pushButton_11 = QtWidgets.QPushButton(self.verticalLayoutWidget_5)sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)sizePolicy.setHorizontalStretch(0)sizePolicy.setVerticalStretch(0)sizePolicy.setHeightForWidth(self.pushButton_11.sizePolicy().hasHeightForWidth())self.pushButton_11.setSizePolicy(sizePolicy)self.pushButton_11.setMinimumSize(QtCore.QSize(60, 25))self.pushButton_11.setMaximumSize(QtCore.QSize(160, 60))self.pushButton_11.setObjectName("pushButton_11")self.layout_T3.addWidget(self.pushButton_11)self.pushButton_12 = QtWidgets.QPushButton(self.verticalLayoutWidget_5)sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)sizePolicy.setHorizontalStretch(0)sizePolicy.setVerticalStretch(0)sizePolicy.setHeightForWidth(self.pushButton_12.sizePolicy().hasHeightForWidth())self.pushButton_12.setSizePolicy(sizePolicy)self.pushButton_12.setMinimumSize(QtCore.QSize(60, 25))self.pushButton_12.setMaximumSize(QtCore.QSize(160, 60))self.pushButton_12.setObjectName("pushButton_12")self.layout_T3.addWidget(self.pushButton_12)self.toolBox.addItem(self.page_T3, "")self.page_T4 = QtWidgets.QWidget()self.page_T4.setGeometry(QtCore.QRect(0, 0, 141, 171))self.page_T4.setObjectName("page_T4")self.verticalLayoutWidget_6 = QtWidgets.QWidget(self.page_T4)self.verticalLayoutWidget_6.setGeometry(QtCore.QRect(0, 0, 131, 101))self.verticalLayoutWidget_6.setObjectName("verticalLayoutWidget_6")self.layout_T4 = QtWidgets.QVBoxLayout(self.verticalLayoutWidget_6)self.layout_T4.setContentsMargins(0, 0, 0, 0)self.layout_T4.setObjectName("layout_T4")self.pushButton_13 = QtWidgets.QPushButton(self.verticalLayoutWidget_6)sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)sizePolicy.setHorizontalStretch(0)sizePolicy.setVerticalStretch(0)sizePolicy.setHeightForWidth(self.pushButton_13.sizePolicy().hasHeightForWidth())self.pushButton_13.setSizePolicy(sizePolicy)self.pushButton_13.setMinimumSize(QtCore.QSize(60, 25))self.pushButton_13.setMaximumSize(QtCore.QSize(160, 60))self.pushButton_13.setObjectName("pushButton_13")self.layout_T4.addWidget(self.pushButton_13)self.pushButton_14 = QtWidgets.QPushButton(self.verticalLayoutWidget_6)sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)sizePolicy.setHorizontalStretch(0)sizePolicy.setVerticalStretch(0)sizePolicy.setHeightForWidth(self.pushButton_14.sizePolicy().hasHeightForWidth())self.pushButton_14.setSizePolicy(sizePolicy)self.pushButton_14.setMinimumSize(QtCore.QSize(60, 25))self.pushButton_14.setMaximumSize(QtCore.QSize(160, 60))self.pushButton_14.setObjectName("pushButton_14")self.layout_T4.addWidget(self.pushButton_14)self.pushButton_15 = QtWidgets.QPushButton(self.verticalLayoutWidget_6)sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)sizePolicy.setHorizontalStretch(0)sizePolicy.setVerticalStretch(0)sizePolicy.setHeightForWidth(self.pushButton_15.sizePolicy().hasHeightForWidth())self.pushButton_15.setSizePolicy(sizePolicy)self.pushButton_15.setMinimumSize(QtCore.QSize(60, 25))self.pushButton_15.setMaximumSize(QtCore.QSize(160, 60))self.pushButton_15.setObjectName("pushButton_15")self.layout_T4.addWidget(self.pushButton_15)self.toolBox.addItem(self.page_T4, "")self.page_T5 = QtWidgets.QWidget()self.page_T5.setGeometry(QtCore.QRect(0, 0, 141, 171))self.page_T5.setObjectName("page_T5")self.toolBox.addItem(self.page_T5, "")self.page_T7 = QtWidgets.QWidget()self.page_T7.setGeometry(QtCore.QRect(0, 0, 141, 171))self.page_T7.setObjectName("page_T7")self.toolBox.addItem(self.page_T7, "")self.verticalLayoutWidget_3 = QtWidgets.QWidget(self.centralwidget)self.verticalLayoutWidget_3.setGeometry(QtCore.QRect(10, 380, 141, 291))self.verticalLayoutWidget_3.setObjectName("verticalLayoutWidget_3")self.leftFrame_2 = QtWidgets.QVBoxLayout(self.verticalLayoutWidget_3)self.leftFrame_2.setContentsMargins(0, 0, 0, 0)self.leftFrame_2.setObjectName("leftFrame_2")self.lineEdit = QtWidgets.QLineEdit(self.verticalLayoutWidget_3)self.lineEdit.setMinimumSize(QtCore.QSize(0, 30))self.lineEdit.setObjectName("lineEdit")self.leftFrame_2.addWidget(self.lineEdit)self.plainTextEdit = QtWidgets.QPlainTextEdit(self.verticalLayoutWidget_3)self.plainTextEdit.setObjectName("plainTextEdit")self.leftFrame_2.addWidget(self.plainTextEdit)MainWindow.setCentralWidget(self.centralwidget)self.menubar = QtWidgets.QMenuBar(MainWindow)self.menubar.setGeometry(QtCore.QRect(0, 0, 1080, 23))self.menubar.setObjectName("menubar")self.menuFile = QtWidgets.QMenu(self.menubar)self.menuFile.setObjectName("menuFile")self.menuQuit = QtWidgets.QMenu(self.menubar)self.menuQuit.setObjectName("menuQuit")MainWindow.setMenuBar(self.menubar)self.statusbar = QtWidgets.QStatusBar(MainWindow)self.statusbar.setObjectName("statusbar")MainWindow.setStatusBar(self.statusbar)self.toolBar = QtWidgets.QToolBar(MainWindow)self.toolBar.setObjectName("toolBar")MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)self.actionOpen = QtWidgets.QAction(MainWindow)icon1 = QtGui.QIcon()icon1.addPixmap(QtGui.QPixmap("../image/iconOpen.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)self.actionOpen.setIcon(icon1)self.actionOpen.setObjectName("actionOpen")self.actionSave = QtWidgets.QAction(MainWindow)icon2 = QtGui.QIcon()icon2.addPixmap(QtGui.QPixmap("../image/iconSave.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)self.actionSave.setIcon(icon2)self.actionSave.setObjectName("actionSave")self.actionClose = QtWidgets.QAction(MainWindow)icon3 = QtGui.QIcon()icon3.addPixmap(QtGui.QPixmap("../image/iconClose.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)self.actionClose.setIcon(icon3)self.actionClose.setObjectName("actionClose")self.actionQuit = QtWidgets.QAction(MainWindow)icon4 = QtGui.QIcon()icon4.addPixmap(QtGui.QPixmap("../image/iconQuit.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)self.actionQuit.setIcon(icon4)self.actionQuit.setObjectName("actionQuit")self.actionSetup = QtWidgets.QAction(MainWindow)icon5 = QtGui.QIcon()icon5.addPixmap(QtGui.QPixmap("../image/iconSetup.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)self.actionSetup.setIcon(icon5)self.actionSetup.setObjectName("actionSetup")self.actionHelp = QtWidgets.QAction(MainWindow)icon6 = QtGui.QIcon()icon6.addPixmap(QtGui.QPixmap("../image/iconHelp.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)self.actionHelp.setIcon(icon6)self.actionHelp.setObjectName("actionHelp")self.menuFile.addAction(self.actionOpen)self.menuFile.addAction(self.actionSave)self.menuFile.addAction(self.actionClose)self.menuQuit.addAction(self.actionQuit)self.menubar.addAction(self.menuFile.menuAction())self.menubar.addAction(self.menuQuit.menuAction())self.toolBar.addAction(self.actionOpen)self.toolBar.addAction(self.actionClose)self.toolBar.addAction(self.actionSave)self.toolBar.addAction(self.actionSetup)self.toolBar.addAction(self.actionHelp)self.toolBar.addAction(self.actionQuit)self.retranslateUi(MainWindow)self.stackedWidget.setCurrentIndex(0)self.toolBox.setCurrentIndex(0)self.actionQuit.triggered.connect(MainWindow.close)self.actionHelp.triggered.connect(MainWindow.trigger_actHelp)self.pushButton_01.clicked.connect(MainWindow.click_pushButton_01)self.pushButton_02.clicked.connect(MainWindow.click_pushButton_02)self.pushButton_03.clicked.connect(MainWindow.click_pushButton_03)self.pushButton_04.clicked.connect(MainWindow.click_pushButton_04)self.pushButton_05.clicked.connect(MainWindow.click_pushButton_05)self.pushButton_06.clicked.connect(MainWindow.click_pushButton_06)self.pushButton_07.clicked.connect(MainWindow.click_pushButton_07)self.pushButton_08.clicked.connect(MainWindow.click_pushButton_08)self.pushButton_09.clicked.connect(MainWindow.click_pushButton_09)self.pushButton_10.clicked.connect(MainWindow.click_pushButton_10)QtCore.QMetaObject.connectSlotsByName(MainWindow)def retranslateUi(self, MainWindow): # Copyright 2021 youcans, XUPT_translate = QtCore.QCoreApplication.translateMainWindow.setWindowTitle(_translate("MainWindow", "圖形圖像處理"))self.label_11.setText(_translate("MainWindow", "曝光:"))self.label_12.setText(_translate("MainWindow", "亮度:"))self.label_13.setText(_translate("MainWindow", "對比度:"))self.label_14.setText(_translate("MainWindow", "銳化:"))self.label_15.setText(_translate("MainWindow", "模糊:"))self.label_16.setText(_translate("MainWindow", "雜點:"))self.pushButton_01.setText(_translate("MainWindow", "圖像平移"))self.pushButton_02.setText(_translate("MainWindow", "圖像縮放"))self.pushButton_03.setText(_translate("MainWindow", "圖像轉置"))self.pushButton_04.setText(_translate("MainWindow", "圖像旋轉"))self.toolBox.setItemText(self.toolBox.indexOf(self.page_T1), _translate("MainWindow", "1. 幾何變換"))self.pushButton_05.setText(_translate("MainWindow", "灰度變換"))self.pushButton_06.setText(_translate("MainWindow", "直方圖修正"))self.pushButton_08.setText(_translate("MainWindow", "圖像平滑"))self.pushButton_07.setText(_translate("MainWindow", "圖像銳化"))self.toolBox.setItemText(self.toolBox.indexOf(self.page_T2), _translate("MainWindow", "2. 圖像增強"))self.pushButton_09.setText(_translate("MainWindow", "傅立葉變換"))self.pushButton_10.setText(_translate("MainWindow", "離散余弦"))self.pushButton_11.setText(_translate("MainWindow", "頻域濾波"))self.pushButton_12.setText(_translate("MainWindow", "小波變換"))self.toolBox.setItemText(self.toolBox.indexOf(self.page_T3), _translate("MainWindow", "3. 頻域處理"))self.pushButton_13.setText(_translate("MainWindow", "閾值分割"))self.pushButton_14.setText(_translate("MainWindow", "邊緣檢測"))self.pushButton_15.setText(_translate("MainWindow", "輪廓跟蹤"))self.toolBox.setItemText(self.toolBox.indexOf(self.page_T4), _translate("MainWindow", "4. 圖像分割"))self.toolBox.setItemText(self.toolBox.indexOf(self.page_T5), _translate("MainWindow", "5. 圖像壓縮"))self.toolBox.setItemText(self.toolBox.indexOf(self.page_T7), _translate("MainWindow", "返回"))self.menuFile.setTitle(_translate("MainWindow", "文件"))self.menuQuit.setTitle(_translate("MainWindow", "退出"))self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))self.actionOpen.setText(_translate("MainWindow", "打開"))self.actionSave.setText(_translate("MainWindow", "保存"))self.actionClose.setText(_translate("MainWindow", "關閉"))self.actionQuit.setText(_translate("MainWindow", "Quit"))self.actionSetup.setText(_translate("MainWindow", "設置"))self.actionHelp.setText(_translate("MainWindow", "幫助"))8.3 main程序(GUIdemo11.py)
# GUIdemo11.py # Demo11 of GUI by PyQt5 # Copyright 2021 youcans, XUPT # Crated:2021-10-20import sys, math, sipfrom PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox from uiDemo11 import Ui_MainWindow # 導入 uiDemo9.py 中的 Ui_MainWindow 界面類class MyMainWindow(QMainWindow, Ui_MainWindow): # 繼承 QMainWindow 類和 Ui_MainWindow 界面類def __init__(self, parent=None):super(MyMainWindow, self).__init__(parent) # 初始化父類self.setupUi(self) # 繼承 Ui_MainWindow 界面類def click_pushButton_01(self): # 點擊 pushButton_01 觸發self.lineEdit.setText("1. 幾何變換")self.plainTextEdit.appendPlainText("1.1 圖像平移")self.stackedWidget.setCurrentIndex(0) # 打開 stackedWidget > page_0returndef click_pushButton_02(self): # 點擊 pushButton_02 觸發self.lineEdit.setText("1. 幾何變換")self.plainTextEdit.appendPlainText("1.2 圖像縮放")self.stackedWidget.setCurrentIndex(0) # 打開 stackedWidget > page_0self.label_1.setPixmap(QtGui.QPixmap("../image/fractal02.png"))returndef click_pushButton_03(self): # 點擊 pushButton_03 觸發self.lineEdit.setText("1. 幾何變換")self.plainTextEdit.appendPlainText("1.3 圖像轉置縮放")self.label_1.setPixmap(QtGui.QPixmap("../image/fractal03.png"))returndef click_pushButton_04(self): # 點擊 pushButton_04 觸發self.lineEdit.setText("1. 幾何變換")self.plainTextEdit.appendPlainText("1.4 圖像旋轉")self.label_1.setPixmap(QtGui.QPixmap("../image/fractal04.png"))returndef click_pushButton_05(self): # 點擊 pushButton_05 觸發self.lineEdit.setText("2. 圖像增強")self.plainTextEdit.appendPlainText("2.1 灰度變換")self.stackedWidget.setCurrentIndex(1) # 打開 stackedWidget > page_1self.label_2.setPixmap(QtGui.QPixmap("../image/fractal01.png"))self.label_2.setScaledContents(True) # 圖片自適應 QLabel 區域大小returndef click_pushButton_06(self): # 點擊 pushButton_06 觸發self.plainTextEdit.appendPlainText("2.2 直方圖修正")self.label_3.setPixmap(QtGui.QPixmap("../image/fractal02.png"))returndef click_pushButton_07(self): # 點擊 pushButton_07 觸發self.plainTextEdit.appendPlainText("2.3 圖像平滑")self.label_2.setPixmap(QtGui.QPixmap("../image/fractal03.png"))returndef click_pushButton_08(self): # 點擊 pushButton_08 觸發self.plainTextEdit.appendPlainText("2.4 圖像銳化")self.label_3.setPixmap(QtGui.QPixmap("../image/fractal04.png"))returndef click_pushButton_09(self): # 點擊 pushButton_09 觸發self.lineEdit.setText("3. 頻域處理")self.plainTextEdit.appendPlainText("3.1 傅立葉變換")self.stackedWidget.setCurrentIndex(2) # 打開 stackedWidget > page_2self.label_4.setPixmap(QtGui.QPixmap("../image/fractal01.png"))self.label_5.setPixmap(QtGui.QPixmap("../image/fractal02.png"))self.label_6.setPixmap(QtGui.QPixmap("../image/fractal03.png"))self.label_7.setPixmap(QtGui.QPixmap("../image/fractal04.png"))returndef click_pushButton_10(self): # 點擊 pushButton_10 觸發self.plainTextEdit.appendPlainText("3.2 離散余弦")self.label_5.setPixmap(QtGui.QPixmap(""))self.label_6.setPixmap(QtGui.QPixmap(""))self.label_7.setPixmap(QtGui.QPixmap(""))returndef trigger_actHelp(self): # 動作 actHelp 觸發QMessageBox.about(self, "About","""數字圖像處理工具箱 v1.0\nCopyright YouCans, XUPT 2021""")returnif __name__ == '__main__': # youcans, XUPT 2021app = QApplication(sys.argv) # 在 QApplication 方法中使用,創建應用程序對象myWin = MyMainWindow() # 實例化 MyMainWindow 類,創建主窗口myWin.show() # 在桌面顯示控件 myWinsys.exit(app.exec_()) # 結束進程,退出程序版權聲明:
歡迎關注『Python 小白的 PyQt5 項目實戰 @ youcans』 原創作品
原創作品,轉載必須標注原文鏈接:https://blog.csdn.net/youcans/article/details/120925109
Copyright 2021 youcans, XUPT
Crated:2021-10-24
歡迎關注『Python 小白從零開始 PyQt5 項目實戰 @ Youcans』系列,匯總篇
Python 小白從零開始 PyQt5 項目實戰(1)安裝與環境配置
Python 小白從零開始 PyQt5 項目實戰(2)菜單和工具欄
Python 小白從零開始 PyQt5 項目實戰(3)信號與槽的連接
Python 小白從零開始 PyQt5 項目實戰(4)基本控件
Python 小白從零開始 PyQt5 項目實戰(5)布局管理
Python 小白從零開始 PyQt5 項目實戰(6)窗口切換的堆疊布局
Python 小白從零開始 PyQt5 項目實戰(7)折疊側邊欄的實現
Python 小白從零開始 PyQt5 項目實戰(8)匯總篇(全部例程)
總結
以上是生活随笔為你收集整理的Python 小白从零开始 PyQt5 项目实战(8)汇总篇(完整例程)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python入门基础篇(二)元组,更适合
- 下一篇: sklearn特征工程