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 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/