QRadioButton 單選按鈕
QRadioButton 是 PyQt5 裡的單選按鈕元件,這篇教學會介紹如何在 PyQt5 視窗裡加入 QRadioButton 單選按鈕,並進行一些基本的樣式設定,以及進行按鈕群組和點擊事件的設定。
快速導覽:
- PyQt6 版本參考:PyQt6 教學 - QRadioButton 單選按鈕
- 因為 Google Colab 不支援 PyQt5,所以請使用本機環境 ( 參考:使用 Python 虛擬環境 ) 或使用 Anaconda Jupyter 進行實作 ( 參考:使用 Anaconda )。
加入 QRadioButton 單選按鈕
建立 PyQt5 視窗物件後,透過 QtWidgets.QRadioButton(widget)
方法,就能在指定的元件中建立單選按鈕,下方的程式碼執行後,會加入兩個 QRadioButton 按鈕 ,並使用 setText() 方法加入文字。
注意,放在同樣元件裡的 QRadioButton 視為同一個群組,會套用「單選」的規則,例如下方程式碼的兩個 QRadioButton 都放在 Form 裡,所以只能擇一選擇。
from PyQt5 import QtWidgets
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
rb_a = QtWidgets.QRadioButton(Form) # 單選按鈕 A
rb_a.setGeometry(30, 30, 100, 20)
rb_a.setText('A')
rb_b = QtWidgets.QRadioButton(Form) # 單選按鈕 B
rb_b.setGeometry(30, 60, 100, 20)
rb_b.setText('B')
Form.show()
sys.exit(app.exec_())
如果有「多組」QRadioButton,則可以使用 QtWidgets.QButtonGroup(widget)
方法建立按鈕群組,然後將歸類為同一組的 QRadioButton 加入同一個 QButtonGroup,就能分別進行單選的動作。
from PyQt5 import QtWidgets
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
rb_a = QtWidgets.QRadioButton(Form) # 單選按鈕 A
rb_a.setGeometry(30, 30, 100, 20)
rb_a.setText('A')
rb_b = QtWidgets.QRadioButton(Form) # 單選按鈕 B
rb_b.setGeometry(30, 60, 100, 20)
rb_b.setText('B')
group1 = QtWidgets.QButtonGroup(Form) # 按鈕群組
group1.addButton(rb_a) # 加入單選按鈕 A
group1.addButton(rb_b) # 加入單選按鈕 B
rb_c = QtWidgets.QRadioButton(Form) # 單選按鈕 C
rb_c.setGeometry(150, 30, 100, 20)
rb_c.setText('C')
rb_d = QtWidgets.QRadioButton(Form) # 單選按鈕 D
rb_d.setGeometry(150, 60, 100, 20)
rb_d.setText('D')
group2 = QtWidgets.QButtonGroup(Form) # 按鈕群組
group2.addButton(rb_c) # 加入單選按鈕 C
group2.addButton(rb_d) # 加入單選按鈕 D
Form.show()
sys.exit(app.exec_())
QRadioButton 位置設定
透過下列 QRadioButton 方法,可以將 QRadioButton 元件定位到指定的位置:
|方法|參數|說明| |--|--| |move()|x, y|設定 QRadioButton 在擺放的父元件中的 xy 座標,x 往右為正,y 往下為正,尺寸根據內容自動延伸。| |setGeometry()|x, y, w, h|設定 QRadioButton 在擺放的父元件中的 xy 座標和長寬尺寸,x 往右為正,y 往下為正,如果超過長寬尺寸,預設會被裁切無法顯示。|
下方的程式碼執行後會放入四個 QRadioButton,兩個使用 move() 定位,另外兩個使用 setGeometry() 方法定位。
from PyQt5 import QtWidgets
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
rb_a = QtWidgets.QRadioButton(Form) # 單選按鈕 A
rb_a.move(30, 30)
rb_a.setText('A')
rb_b = QtWidgets.QRadioButton(Form) # 單選按鈕 C
rb_b.move(30, 60)
rb_b.setText('B')
rb_c = QtWidgets.QRadioButton(Form) # 單選按鈕 D
rb_c.setGeometry(150, 30, 100, 20)
rb_c.setText('C')
rb_d = QtWidgets.QRadioButton(Form) # 單選按鈕 E
rb_d.setGeometry(150, 60, 100, 20)
rb_d.setText('D')
Form.show()
sys.exit(app.exec_())
QRadioButton 狀態設定
透過下列幾種方法,可以設定 QRadioButton 的狀態:
方法 | 參數 | 說明 |
---|---|---|
setDisabled() | bool | 是否停用,預設 False 啟用,可設定 True 停用。 |
setChecked() | bool | 是否勾選,預設 False 不勾選,可設定 True 勾選,若同一組有多個勾選,則以最後一個為主。 |
toggle() | 勾選狀態切換。 |
下面的程式碼執行後,QRadioButton B 會停用,QRadioButton C 會預先勾選。
from PyQt5 import QtWidgets
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
rb_a = QtWidgets.QRadioButton(Form)
rb_a.setGeometry(30, 30, 100, 20)
rb_a.setText('A')
rb_b = QtWidgets.QRadioButton(Form)
rb_b.setGeometry(30, 60, 100, 20)
rb_b.setText('B')
rb_b.setDisabled(True)
rb_c = QtWidgets.QRadioButton(Form)
rb_c.setGeometry(30, 90, 100, 20)
rb_c.setText('C')
rb_c.setChecked(True)
Form.show()
sys.exit(app.exec_())
QRadioButton 樣式設定
如果會使用網頁 CSS 語法,就能透過 setStyleSheet() 設定 QRadioButton 樣式,在設計樣式上也較為彈性好用,下方的程式碼執行後,會套用 CSS 樣式語法,將 QRadioButton 設定為藍色字,當滑鼠移到按鈕上,就會觸發 hover 的樣式而變成紅色字。
from PyQt5 import QtWidgets
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
rb_a = QtWidgets.QRadioButton(Form)
rb_a.setGeometry(30, 30, 100, 20)
rb_a.setText('A')
# 設定按鈕 A 的樣式
rb_a.setStyleSheet('''
QRadioButton {
color: #00f;
}
QRadioButton:hover {
color:#f00;
}
''')
rb_b = QtWidgets.QRadioButton(Form)
rb_b.setGeometry(30, 60, 100, 20)
rb_b.setText('B')
# 設定按鈕 B 的樣式
rb_b.setStyleSheet('''
QRadioButton {
color: #00f;
}
QRadioButton:hover {
color:#f00;
}
''')
Form.show()
sys.exit(app.exec_())
如果使用 setDisabled(True) 將 QRadioButton 設定為「停用」,也可透過 disabled 的樣式表進行樣式的設定,下方的程式碼執行後,單選按鈕 B 會變成淺灰色
from PyQt5 import QtWidgets
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
rb_a = QtWidgets.QRadioButton(Form)
rb_a.setGeometry(30, 30, 100, 20)
rb_a.setText('A')
rb_a.setStyleSheet('''
QRadioButton {
color: #00f;
}
QRadioButton:hover {
color:#f00;
}
''')
rb_b = QtWidgets.QRadioButton(Form)
rb_b.setGeometry(30, 60, 100, 20)
rb_b.setText('B')
rb_b.setStyleSheet('''
QRadioButton {
color: #00f;
}
QRadioButton:hover {
color:#f00;
}
QRadioButton:disabled {
color:#ccc;
}
''')
rb_b.setDisabled(True) # 停用按鈕 B
Form.show()
sys.exit(app.exec_())
QRadioButton 點擊事件
如果要偵測勾選了哪個 QRadioButton,有兩種常用的方法,第一種是透過 QButtonGroup() 將 QRadioButton 包裝成同一個群組,使用 addButton() 添加按鈕時,可設定第二個按鈕的 ID 參數,設定後使用 buttonClicked.connect(fn)
方法,就能偵測是否勾選按鈕,並能夠過函式,執行 checkedId() 取得勾選按鈕的 ID,下方的程式碼執行後,會在勾選不同按鈕時,透過 QLabel 顯示對應的勾選按鈕的 ID。
from PyQt5 import QtWidgets
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
rb_a = QtWidgets.QRadioButton(Form)
rb_a.setGeometry(30, 60, 100, 20)
rb_a.setText('A')
rb_b = QtWidgets.QRadioButton(Form)
rb_b.setGeometry(150, 60, 100, 20)
rb_b.setText('B')
def show():
label.setText(str(group.checkedId())) # 設定 label 文字為按鈕群組中勾選按鈕的 ID
group = QtWidgets.QButtonGroup(Form)
group.addButton(rb_a, 1) # 添加 QRadioButton A,ID 設定為 1
group.addButton(rb_b, 2) # 添加 QRadioButton B,ID 設定為 2
group.buttonClicked.connect(show) # 綁定點擊事件
label = QtWidgets.QLabel(Form)
label.setGeometry(30, 30, 100, 20)
Form.show()
sys.exit(app.exec_())
第二種方法則是使用 toggled() 的方法,將函式與各個按鈕綁定,接著就能透過 text() 取得按鈕文字,透過 isChecked() 取得按鈕勾選狀態。
from PyQt5 import QtWidgets
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
def show(rb):
label.setText(rb.text() + ':' + str(rb.isChecked())) # 取得按鈕狀態
rb_a = QtWidgets.QRadioButton(Form)
rb_a.setGeometry(30, 60, 100, 20)
rb_a.setText('A')
rb_a.toggled.connect(lambda: show(rb_a)) # 綁定函式
rb_b = QtWidgets.QRadioButton(Form)
rb_b.setGeometry(150, 60, 100, 20)
rb_b.setText('B')
rb_b.toggled.connect(lambda: show(rb_b)) # 綁定函式
group = QtWidgets.QButtonGroup(Form)
group.addButton(rb_a)
group.addButton(rb_b)
label = QtWidgets.QLabel(Form)
label.setGeometry(30, 30, 100, 20)
Form.show()
sys.exit(app.exec_())
改用 class 的寫法
上方的程式碼,亦可改用 class 的寫法表示。
from PyQt5 import QtWidgets
import sys
class MyWidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('oxxo.studio')
self.resize(300, 200)
self.ui()
def ui(self):
rb_a = QtWidgets.QRadioButton(self)
rb_a.setGeometry(30, 60, 100, 20)
rb_a.setText('A')
rb_a.toggled.connect(lambda: self.showMsg(rb_a)) # 綁定函式
rb_b = QtWidgets.QRadioButton(self)
rb_b.setGeometry(150, 60, 100, 20)
rb_b.setText('B')
rb_b.toggled.connect(lambda: self.showMsg(rb_b)) # 綁定函式
group = QtWidgets.QButtonGroup(self)
group.addButton(rb_a)
group.addButton(rb_b)
self.label = QtWidgets.QLabel(self)
self.label.setGeometry(30, 30, 100, 20)
def showMsg(self, rb):
self.label.setText(rb.text() + ':' + str(rb.isChecked())) # 取得按鈕狀態
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
Form = MyWidget()
Form.show()
sys.exit(app.exec_())
意見回饋
如果有任何建議或問題,可傳送「意見表單」給我,謝謝~