尝试用python检查多个qt单选按钮

Trying to check multiple qt radio buttons with python

我需要用python检查qt用户界面中的多个单选按钮。到目前为止,我们使用的是类似于:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
if main.ui.radioButton_1.isChecked():
    responses["q1"] ="1"
elif main.ui.radioButton_2.isChecked():
    responses["q1"] ="2"
elif main.ui.radioButton_3.isChecked():
    responses["q1"] ="3"

if main.ui.radioButton_4.isChecked():
    responses["q2"] ="1"
elif main.ui.radioButton_5.isChecked():
    responses["q2"] ="2"
elif main.ui.radioButton_6.isChecked():
    responses["q2"] ="3"
...

因为有很多按钮和许多不同的类别(Q1,Q2,…),我考虑了一下优化它。所以这就是我希望的工作方式(通过如何从Pyqt中的GroupBox中获取选中的RadioButton):

1
2
3
for i, button in enumerate(["main.ui.radioButton_" + str(1) for i in range(1, 8)]):
    if button.isChecked():
        responses["q1"] = str(i - 1)

我明白为什么这行不通,但我希望能写下来。所以我尝试使用类似的方法(是否有一种方法可以循环并执行Python类中的所有函数?):

1
for idx, name, val in enumerate(main.ui.__dict__.iteritems()):

然后使用一些模3等来分配结果。但这也不管用。不确定是因为我用了口述还是别的什么。我得到的错误是:

1
TypeError: 'QLabel' object is not iterable

现在有人可能会说隐式比显式更好,也因为可读性,if-elif链是好的,但是有400多行。同样,在阅读了这篇文章之后,最有效的方式是在其他人做得最多的时候,发表if-elif-elif-else声明?我认为必须有一种更好、更有效的方法来做到这一点(见已接受答案的示例3.py和4.py)。因为我需要检查main.ui.radiobutton_1.ischecked()的布尔值,然后根据buttons组(q1,q2,…)分配该值,所以我还没有像本文中描述的那样使用字典来实现解决方案。

我是坚持使用if-elif链还是有办法不仅减少loc,而且使代码更高效(更快)?


看起来您已经使用QtDesigner创建了用户界面,所以我建议将每一组单选按钮放在QButtonGroup中。这将为您提供一个简单的现成的API,用于在一个组中获取选中的按钮,而无需单独查询每个按钮。

在Qt设计器中,通过选择按钮,然后从上下文菜单中选择"分配给按钮组>新建按钮组",可以将按钮添加到按钮组。按钮ID(稍后需要使用)按按钮的选择顺序分配。因此,使用ctrl+click以正确的顺序选择组中的每个按钮。对于每个组,ID从1开始,对于添加到该组的每个按钮,只增加一个。

添加新按钮组时,它将显示在对象检查器中。这将允许您选择它并给它一个更有意义的名称。

创建完所有组后,您可以按如下方式获得组的选中按钮:

1
2
3
    responses["q1"] = str(main.ui.groupQ1.checkedId())
    responses["q2"] = str(main.ui.groupQ2.checkedId())
    # etc...

这可以进一步简化,以便在一个循环中处理所有组:

1
2
3
4
    for index in range(1, 10):
        key = 'q%d' % index
        group = 'groupQ%d' % index
        responses[key] = str(getattr(main.ui, group).checkedId())

另一种方法是使用信号。如果在应用程序中有大量的单选按钮,我怀疑这种方法会明显更快。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *

class MoodExample(QGroupBox):

    def __init__(self):
        super(MoodExample, self).__init__()

        # Create an array of radio buttons
        moods = [QRadioButton("Happy"), QRadioButton("Sad"), QRadioButton("Angry")]

        # Set a radio button to be checked by default
        moods[0].setChecked(True)  

        # Radio buttons usually are in a vertical layout  
        button_layout = QVBoxLayout()

        # Create a button group for radio buttons
        self.mood_button_group = QButtonGroup()

        for i in xrange(len(moods)):
            # Add each radio button to the button layout
            button_layout.addWidget(moods[i])
            # Add each radio button to the button group & give it an ID of i
            self.mood_button_group.addButton(moods[i], i)
            # Connect each radio button to a method to run when it's clicked
            self.connect(moods[i], SIGNAL("clicked()"), self.radio_button_clicked)

        # Set the layout of the group box to the button layout
        self.setLayout(button_layout)

    #Print out the ID & text of the checked radio button
    def radio_button_clicked(self):
        print(self.mood_button_group.checkedId())
        print(self.mood_button_group.checkedButton().text())

app = QApplication(sys.argv)
mood_example = MoodExample()
mood_example.show()
sys.exit(app.exec_())

我在以下网站找到了更多信息:

http://codeprogress.com/python/libraries/pyqt/showpyqt示例.php?index=387&key=qButtonGroupClick

http://www.pythonschool.net/pyqt/radio-button-widget/