Last Updated on 2021-04-09 by Clay
一個好的、完善的界面通常都具有著選單(也就是上方的菜單),方便我們針對我們的程式使用各種功能。雖然說小一點的界面並不需要有這種功能,但我最近還是在研究我的記譜程式,所以也研究了一下『菜單』、『工具欄』等等的使用方始。
我想等到我記譜工具完成的那一天,會以『實戰分享』的方式紀錄成筆記放上來的。
那麼,以下就是我今天的心得筆記:紀錄如何使用菜單、工具欄等等的工具!
菜單
在我們開始之前,我先說明一下一件事情:我通常都實做界面、邏輯分離的程式,所以若想要直接拿我的程式進行測試,界面的部份只要拿我轉好的 .py 檔測試即可,並不是一定得要使用 Qt Designer。(當然,PyQt5 這個 package 就是一定要有的了。)
首先,我使用 Qt Designer 拉出一個界面:
大家可以注意到,我在右上角的 Type Here 新增了一個『文件』的選單,這就是我們今天要講的『菜單』。
我也建立了菜單裡的選項:
存檔、轉檔之後,我們會得到一份這樣的檔案:
# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'Menu.ui' # # Created by: PyQt5 UI code generator 5.11.3 # # WARNING! All changes made in this file will be lost! from PyQt5 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(800, 600) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 25)) self.menubar.setObjectName("menubar") self.menu = QtWidgets.QMenu(self.menubar) self.menu.setObjectName("menu") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.actionNew_File = QtWidgets.QAction(MainWindow) self.actionNew_File.setObjectName("actionNew_File") self.actionOpen_File = QtWidgets.QAction(MainWindow) self.actionOpen_File.setObjectName("actionOpen_File") self.actionClose = QtWidgets.QAction(MainWindow) self.actionClose.setObjectName("actionClose") self.menu.addAction(self.actionNew_File) self.menu.addAction(self.actionOpen_File) self.menu.addAction(self.actionClose) self.menubar.addAction(self.menu.menuAction()) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.menu.setTitle(_translate("MainWindow", "文件")) self.actionNew_File.setText(_translate("MainWindow", "New File")) self.actionOpen_File.setText(_translate("MainWindow", "Open File")) self.actionClose.setText(_translate("MainWindow", "Close"))
跟之前的檔案不同的是,這次我們設定好的 Menu 並不是放在 setupUi() 底下,而是放在我們之前一直忽略的 retranslateUi()
底下。不過,當然,使用方法跟之前定義的元件並沒有太大的區別。
我們在自己的邏輯程式腳本裡頭寫下這樣的程式碼:
# -*- coding: utf-8 -*- from PyQt5 import QtWidgets, QtGui, QtCore from Menu import Ui_MainWindow import sys class MainWindow(QtWidgets.QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) # Menu self.ui.retranslateUi(self) self.ui.actionClose.setShortcut('Ctrl+Q') self.ui.actionClose.triggered.connect(app.exit) if __name__ == '__main__': app = QtWidgets.QApplication([]) window = MainWindow() window.show() sys.exit(app.exec_())
Output:
目前前面兩樣 New File、 Open File 還沒有實做任何的功能,唯一做出的就是 Close,因為示範起來比較方便哈哈哈哈。
在我們的程式試中,首先,我們可以使用 setShortcut() 來製作簡單的快捷鍵。
下面那一行:self.ui.actionClose.triggered.connect(app.exit)
代表著被觸發時,這個應用程式便結束。
當然,如果你希望有其他的功能,依此類推,一樣使用 triggered.connect() 來觸發事先寫好的功能。
這樣,我們簡單的菜單按鈕就完成了。
如果還希望再界面上再加著圖示的話,可以使用我們之前教過得 QIcon。
在程式碼中加入行程式碼:
self.ui.actionClose.setIcon(QtGui.QIcon('pic/Cancel.png'))
pic 是我放圖片的資料夾名稱、而 Cancel.png 為我要放的圖片。
Output:
我們可以看到,選單前面加上了個 X 的圖示!
工具欄
講完了 Menu,其實『工具欄』這個欄位也就差不多了;通常工具欄這個欄位都只是設定成 Menu 的圖示按鈕,點擊就會產生相似的功能。
不過,我還是來匆匆瀏覽下吧!
首先,我使用了 ToolBar 這個元件。ToolBar 可以很好地將元件放置在一起,甚至還可以新增頁面切換不同的工具欄位。
在這裡可以看到,我放了兩個 ToolButton 進去這個 ToolBar。然後,我們存檔。
轉換成 Python 檔之後如下:
# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'Menu.ui' # # Created by: PyQt5 UI code generator 5.11.3 # # WARNING! All changes made in this file will be lost! from PyQt5 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(800, 600) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.toolBox = QtWidgets.QToolBox(self.centralwidget) self.toolBox.setGeometry(QtCore.QRect(0, 0, 91, 551)) self.toolBox.setObjectName("toolBox") self.page = QtWidgets.QWidget() self.page.setGeometry(QtCore.QRect(0, 0, 91, 491)) self.page.setObjectName("page") self.toolButton = QtWidgets.QToolButton(self.page) self.toolButton.setGeometry(QtCore.QRect(0, -10, 91, 81)) self.toolButton.setText("") self.toolButton.setObjectName("toolButton") self.toolButton_2 = QtWidgets.QToolButton(self.page) self.toolButton_2.setGeometry(QtCore.QRect(0, 70, 91, 81)) self.toolButton_2.setObjectName("toolButton_2") self.toolBox.addItem(self.page, "") self.page_2 = QtWidgets.QWidget() self.page_2.setGeometry(QtCore.QRect(0, 0, 91, 221)) self.page_2.setObjectName("page_2") self.toolBox.addItem(self.page_2, "") MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 25)) self.menubar.setObjectName("menubar") self.menu = QtWidgets.QMenu(self.menubar) self.menu.setObjectName("menu") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.actionNew_File = QtWidgets.QAction(MainWindow) self.actionNew_File.setObjectName("actionNew_File") self.actionOpen_File = QtWidgets.QAction(MainWindow) self.actionOpen_File.setObjectName("actionOpen_File") self.actionClose = QtWidgets.QAction(MainWindow) self.actionClose.setObjectName("actionClose") self.menu.addAction(self.actionNew_File) self.menu.addAction(self.actionOpen_File) self.menu.addAction(self.actionClose) self.menubar.addAction(self.menu.menuAction()) self.retranslateUi(MainWindow) self.toolBox.setCurrentIndex(0) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.toolButton_2.setText(_translate("MainWindow", "Hello World")) self.toolBox.setItemText(self.toolBox.indexOf(self.page), _translate("MainWindow", "Page 1")) self.toolBox.setItemText(self.toolBox.indexOf(self.page_2), _translate("MainWindow", "Page 2")) self.menu.setTitle(_translate("MainWindow", "文件")) self.actionNew_File.setText(_translate("MainWindow", "New File")) self.actionOpen_File.setText(_translate("MainWindow", "Open File")) self.actionClose.setText(_translate("MainWindow", "Close"))
然後我們再次撰寫邏輯部份的程式碼。(改寫自剛才的程式碼。)
# -*- coding: utf-8 -*- from PyQt5 import QtWidgets, QtGui, QtCore from Menu import Ui_MainWindow import sys class MainWindow(QtWidgets.QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) # Menu self.ui.retranslateUi(self) self.ui.actionClose.setShortcut('Ctrl+Q') self.ui.actionClose.setIcon(QtGui.QIcon('pic/Cancel.png')) self.ui.actionClose.triggered.connect(self.exit) # ToolBar self.ui.toolButton.setShortcut('Ctrl+E') self.ui.toolButton.setIcon(QtGui.QIcon('pic/Cancel.png')) self.ui.toolButton.clicked.connect(self.exit) def exit(self): app.exit() if __name__ == '__main__': app = QtWidgets.QApplication([]) window = MainWindow() window.show() sys.exit(app.exec_())
Output:
可以看到,我新增了兩個按鈕。其中一個我還是設定使用相同的圖片。
我們點擊這個圖片,應該可以順利地離開程式。
順帶一題,可以看到我設定了兩組不同的快捷鍵,這是因為我選單的 Exit 按鈕已經設定了相當的快捷鍵,兩個元件設定相同的快捷鍵是會報錯的!
然後,由於這次是 Button ,故我們的使用 clicked.connect()
來綁定觸發的事件。
以上,就是今天的教學,謝謝大家的過目。
前天熬了一整夜和朋友熬夜聊天,然後整個人睏得很啊,果然是上了年紀了嗎 ...... 我昨天早上寫個圍棋的吃子判定老半天寫不出來,那明明就是我數年前大學時代就寫過的程式啊!
然後晚上八點從實驗室回家,立刻躺平了,一直睡到凌晨五點才醒,連文章都忘了發。
然後我振筆疾書(?),俐落地刪掉昨天寫的吃子判定,重寫。
這次不到一個小時就寫完了,測試圖形化界面,嗯,OK!看起來沒有 Bug。
離奇的是,我覺得我是寫一模一樣的程式下去跑啊!果然不該撐著熬夜寫程式啊 XDDDD 我連我前一個版本怎麼錯的都不知道。
想要能持之以恆地開發程式、撰寫部落格,看來每天固定地運動也不錯。也不要節食、更要好好睡覺。
References
Read More
- [PyQt5] 基本教學(1) 安裝 PyQt5,印出 Hello World!
- [PyQt5] 基本教學(2) QLabel, QLineEdit, QPushButtom
- [PyQt5] 基本教學(3) QMainWindow, QIcon, QPixmap, QPalette
- [PyQt5] 基本教學(4) 菜單、工具欄
- [PyQt5] 基本教學(5) 進度條、滑動條、旋轉鈕
- [PyQt5] 基本教學(6) 下拉選單、BoxLayout
- [PyQt5] 基本教學(7) hide, show, 自動適應窗口大小
- [PyQt5] 基本教學(8) QTimer, QlcdNumber
- [PyQt5] 基本教學(9) QCaledar,使用 Python 輕鬆創造日曆元件
- [PyQt5] 基本教學(10) 使用鍵盤輸入指令、判斷滑鼠點擊位置
- [PyQt5] 基本教學(11) 使用 QColorDialog 調色盤來進行顏色的設定