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

时间:2015-11-07 13:16:27

标签: python qt loops button pyqt

我需要使用python检查来自qt ui的多个单选按钮。 到目前为止,我们正在使用类似的东西:

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,...),我正在考虑优化它。所以这就是我希望的工作(从How to get the checked radiobutton from a groupbox in pyqt采用):

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

我明白为什么这不起作用,但写作我希望它会。 所以我尝试使用类似于(Is there a way to loop through and execute all of the functions in a Python class?)的东西来迭代按钮:

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

然后使用一些模3等来分配结果。但这也不起作用。不知道是不是因为我使用__ dict __或其他东西。我得到的错误是:

TypeError: 'QLabel' object is not iterable

现在有些人可能会说明确的隐含性更好,而且由于可读性,如果elif链条是好的,但它有400多行。在阅读了这篇文章Most efficient way of making an if-elif-elif-else statement when the else is done the most?之后,我认为必须有一种更好,更有效的方法(参见接受答案的例子3.py和4.py)。因为我需要检查main.ui.radioButton_1.isChecked()的布尔值,然后根据Buttons组(q1,q2,...)分配值,我还没有设法使用词典来实现解决方案如帖子中所述。

我是否坚持使用if elif链或是否有办法不仅降低LOC而且还使代码更高效(更快)?

2 个答案:

答案 0 :(得分:1)

看起来您已经使用Qt Designer来创建您的UI,因此我建议将每组单选按钮放在QButtonGroup中。这将为您提供一个简单的现成API,用于获取组中的选中按钮,而无需单独查询每个按钮。

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

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

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

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

这可以进一步简化以循环处理所有组:

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

答案 1 :(得分:0)

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

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/showPyQTExample.php?index=387&key=QButtonGroupClick

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