QMenuBar、QMenu、QAction 視窗選單
QMenuBar、QMenu 和 QAction 是 PyQt6 裡的選單元件 ( 視窗最上方的選單 ),這篇教學會介紹如何在 PyQt6 視窗裡加入 選單元件,並實作點擊選單後的基本動作。
快速導覽:
因為 Google Colab 不支援 PyQt6,所以請使用本機環境 ( 參考:使用 Python 虛擬環境 ) 或使用 Anaconda Jupyter 進行實作 ( 參考:使用 Anaconda )。
QMenuBar、QMenu 和 QAction 的差別
QMenuBar、QMenu 和 QAction 都是 PyQt6 的選單元件,三個的差別如下:
- QMenuBar:選單主元件,通常一個視窗只會有一個。
- QMenu:選單中帶有「子選項」的選項。
- QAction:選單中的選項。
建立視窗選單
建立 PyQt6 視窗物件後,先透過 QtWidgets.QMenuBar(widget)
方法建立 QMenuBar 視窗選單,接著就能使用 QtWidgets.QMenu(str)
建立帶有「子選項」的選項,使用 QtGui.QAction(str)
建立單一選項,建立 QAction 或 QMenu 後,可以將其加入 QMenu,而 QMenuBar 只能加入 QMenu ( 此處方法和 PyQt5 不同 )。
下方的程式碼執行後,會在建立一個具有一個 File 下拉選單的 QMenuBar,File 下拉選單中有 Open 和 Close 兩個選項。
from PyQt6 import QtWidgets, QtGui
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
menubar = QtWidgets.QMenuBar(Form) # 建立 menubar
menu_file = QtWidgets.QMenu('File') # 建立一個 File 選項 ( QMenu )
action_open = QtGui.QAction('Open') # 建立一個 Open 選項 ( QAction )
menu_file.addAction(action_open) # 將 Open 選項放入 File 選項裡
action_close = QtGui.QAction('Close') # 建立一個 Close 選項 ( QAction )
menu_file.addAction(action_close) # 將 Close 選項放入 File 選項裡
menubar.addMenu(menu_file) # 將 File 選項放入 menubar 裡
Form.show()
sys.exit(app.exec())
class 寫法:
from PyQt6 import QtWidgets, QtGui
import sys
class MyWidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('oxxo.studio')
self.resize(300, 200)
self.ui()
def ui(self):
self.menubar = QtWidgets.QMenuBar(self) # 建立 menubar
self.menu_file = QtWidgets.QMenu('File') # 建立一個 File 選項 ( QMenu )
self.action_open = QtGui.QAction('Open') # 建立一個 Open 選項 ( QAction )
self.menu_file.addAction(self.action_open) # 將 Open 選項放入 File 選項裡
self.action_close = QtGui.QAction('Close') # 建立一個 Close 選項 ( QAction )
self.menu_file.addAction(self.action_close) # 將 Close 選項放入 File 選項裡
self.menubar.addMenu(self.menu_file) # 將 File 選項放入 menubar 裡
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
Form = MyWidget()
Form.show()
sys.exit(app.exec())
除了使用 addAction() 方法可以加入單一選項,也可以使用 addActions() 的方法,一次加入以串列組成的多個選項,下方的程式碼執行後,會在原本的選單後方加入第二層選單,第二個選單使用 addActions() 添加選項。
from PyQt6 import QtWidgets, QtGui
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
menubar = QtWidgets.QMenuBar(Form)
menu_file = QtWidgets.QMenu('File')
action_open = QtGui.QAction('Open')
menu_file.addAction(action_open)
action_close = QtGui.QAction('Close')
menu_file.addAction(action_close)
menu_sub = QtWidgets.QMenu('More') # 建立 More 選項 ( QMenu )
action_A = QtGui.QAction('A') # 建立 A 選項 ( QAction )
action_B = QtGui.QAction('B') # 建立 B 選項 ( QAction )
menu_sub.addActions([action_A, action_B]) # More 選項中加入 A 和 B
menu_file.addMenu(menu_sub) # 將 More 選項放入 File 選項裡
menubar.addMenu(menu_file)
Form.show()
sys.exit(app.exec())
class 寫法:
from PyQt6 import QtWidgets, QtGui
import sys
class MyWidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('oxxo.studio')
self.resize(300, 200)
self.ui()
def ui(self):
self.menubar = QtWidgets.QMenuBar(self)
self.menu_file = QtWidgets.QMenu('File')
self.action_open = QtGui.QAction('Open')
self.menu_file.addAction(self.action_open)
self.action_close = QtGui.QAction('Close')
self.menu_file.addAction(self.action_close)
self.menu_sub = QtWidgets.QMenu('More') # 建立 More 選項 ( QMenu )
self.action_A = QtGui.QAction('A') # 建立 A 選項 ( QAction )
self.action_B = QtGui.QAction('B') # 建立 B 選項 ( QAction )
self.menu_sub.addActions([self.action_A, self.action_B]) # More 選項中加入 A 和 B
self.menu_file.addMenu(self.menu_sub) # 將 More 選項放入 File 選項裡
self.menubar.addMenu(self.menu_file)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
Form = MyWidget()
Form.show()
sys.exit(app.exec())
加入分隔線
選單的選項順序是按照加入的順序決定,因此在加入選項的過程中,可以使用 addSeparator()
方法在指定的位置加入分隔線。
from PyQt6 import QtWidgets, QtGui
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
menubar = QtWidgets.QMenuBar(Form)
menu_file = QtWidgets.QMenu('File')
action_open = QtGui.QAction('Open')
menu_file.addAction(action_open)
menu_file.addSeparator() # 加入分隔線
action_close = QtGui.QAction('Close')
menu_file.addAction(action_close)
menubar.addMenu(menu_file)
Form.show()
sys.exit(app.exec())
class 寫法:
from PyQt6 import QtWidgets, QtGui
import sys
class MyWidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('oxxo.studio')
self.resize(300, 200)
self.ui()
def ui(self):
self.menubar = QtWidgets.QMenuBar(self)
self.menu_file = QtWidgets.QMenu('File')
self.action_open = QtGui.QAction('Open')
self.menu_file.addAction(self.action_open)
self.menu_file.addSeparator() # 加入分隔線
self.action_close = QtGui.QAction('Close')
self.menu_file.addAction(self.action_close)
self.menubar.addMenu(self.menu_file)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
Form = MyWidget()
Form.show()
sys.exit(app.exec())
加入快捷鍵、Icon 圖示
建立選項後,可以透過下列方法設定該選項的快捷鍵、Icon 圖示:
方法 | 說明 |
---|---|
setIcon() | 加入 icon 圖示,圖示需要使用 QtGui.QIcon() 方法。 |
setShortcut() | 加入快捷鍵,快捷鍵的格式為 Ctrl、Shift 或 Alt 搭配「+」與大寫字母所組成 ( 注意,如果快捷鍵和系統預設相同,則不會顯示,例如 Ctrl+Q 是關閉視窗 )。 |
下方的程式碼執行後,會在兩個選項前方加上 icon,並加入快捷鍵的說明
from PyQt6 import QtWidgets, QtGui
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
menubar = QtWidgets.QMenuBar(Form)
menu_file = QtWidgets.QMenu('File')
action_open = QtGui.QAction('Open')
action_open.setIcon(QtGui.QIcon('icon.png'))
action_open.setShortcut('Ctrl+O')
menu_file.addAction(action_open)
action_close = QtGui.QAction('Close')
action_close.setIcon(QtGui.QIcon('mona.jpg'))
action_close.setShortcut('Shift+Ctrl+Q')
menu_file.addAction(action_close)
menubar.addMenu(menu_file)
Form.show()
sys.exit(app.exec())
class 寫法:
from PyQt6 import QtWidgets, QtGui
import sys
class MyWidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('oxxo.studio')
self.resize(300, 200)
self.ui()
def ui(self):
self.menubar = QtWidgets.QMenuBar(self)
self.menu_file = QtWidgets.QMenu('File')
self.action_open = QtGui.QAction('Open')
self.action_open.setIcon(QtGui.QIcon('icon.png'))
self.action_open.setShortcut('Ctrl+O')
self.menu_file.addAction(self.action_open)
self.action_close = QtGui.QAction('Close')
self.action_close.setIcon(QtGui.QIcon('mona.jpg'))
self.action_close.setShortcut('Shift+Ctrl+Q')
self.menu_file.addAction(self.action_close)
self.menubar.addMenu(self.menu_file)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
Form = MyWidget()
Form.show()
sys.exit(app.exec())
視窗選單點擊事件
使用 triggered.connect(fn)
方法,就能在點擊選單的選項時,執行對應的函式,以下方的程式碼為例,點擊 open 選項時,會開啟選擇檔案的對話視窗,點擊 close 選項時會關閉整個視窗。
from PyQt6 import QtWidgets, QtGui
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
def open():
filePath , filterType = QtWidgets.QFileDialog.getOpenFileNames() # 選擇檔案對話視窗
print(filePath , filterType)
def close():
print('close')
app.quit()
menubar = QtWidgets.QMenuBar(Form)
menu_file = QtWidgets.QMenu('File')
action_open = QtGui.QAction('Open')
action_open.triggered.connect(open)
menu_file.addAction(action_open)
action_close = QtGui.QAction('Close')
action_close.triggered.connect(close)
menu_file.addAction(action_close)
menubar.addMenu(menu_file)
Form.show()
sys.exit(app.exec())
class 的寫法:
from PyQt6 import QtWidgets, QtGui
import sys
class MyWidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('oxxo.studio')
self.resize(300, 200)
self.ui()
def ui(self):
self.menubar = QtWidgets.QMenuBar(self)
self.menu_file = QtWidgets.QMenu('File')
self.action_open = QtGui.QAction('Open')
self.action_open.triggered.connect(self.open)
self.menu_file.addAction(self.action_open)
self.action_close = QtGui.QAction('Close')
self.action_close.triggered.connect(self.close)
self.menu_file.addAction(self.action_close)
self.menubar.addMenu(self.menu_file)
def open(self):
filePath , filterType = QtWidgets.QFileDialog.getOpenFileNames() # 選擇檔案對話視窗
print(filePath , filterType)
def close(self):
print('close')
app.quit()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
Form = MyWidget()
Form.show()
sys.exit(app.exec())
意見回饋
如果有任何建議或問題,可傳送「意見表單」給我,謝謝~