如何随机化pyqt中单选按钮的顺序
How to randomize the order of radio buttons in pyqt
我正在做一个测验,我希望单选按钮位于不同的位置。我已经让它工作到一定程度,因为它在第一个问题中是随机排列的,但是它会在剩下的测验中保持这个顺序。我希望它每次都随机化。
class MultipleChoice(QtGui.QWidget):
showTopicsSignal = pyqtSignal()
def __init__(self,parent=None):
super(MultipleChoice, self).__init__(parent)
self.initUI()
def initUI(self):
self.Questions=[]
self.Questionum = QLabel()
self.Questioninfo = QLabel()
self.Correctanswer = QRadioButton()
self.Incorrectans1 = QRadioButton()
self.Incorrectans2 = QRadioButton()
self.Incorrectans3 = QRadioButton()
self.Correctanswer.setAutoExclusive(True)
self.Incorrectans1.setAutoExclusive(True)
self.Incorrectans2.setAutoExclusive(True)
self.Incorrectans3.setAutoExclusive(True)
layout = QVBoxLayout(self)
layout.addWidget(self.Questionum)
layout.addWidget(self.Questioninfo)
randomnumber = randint(0,3)
if randomnumber == 0:
layout.addWidget(self.Correctanswer)
layout.addWidget(self.Incorrectans1)
layout.addWidget(self.Incorrectans2)
layout.addWidget(self.Incorrectans3)
elif randomnumber == 1:
layout.addWidget(self.Incorrectans1)
layout.addWidget(self.Correctanswer)
layout.addWidget(self.Incorrectans2)
layout.addWidget(self.Incorrectans3)
elif randomnumber == 2:
layout.addWidget(self.Incorrectans1)
layout.addWidget(self.Incorrectans2)
layout.addWidget(self.Correctanswer)
layout.addWidget(self.Incorrectans3)
elif randomnumber == 3:
layout.addWidget(self.Incorrectans1)
layout.addWidget(self.Incorrectans2)
layout.addWidget(self.Incorrectans3)
layout.addWidget(self.Correctanswer)
如果将答案选择加载到容器中,则可以将 Python 的 random
(link) 库与以下一种或两种工具结合使用:
random.choice(seq)
(link) 随机选择 seq
中提供的可能项目
random.sample(pop, k)
(link) 从 pop
中提供的可能选项中选择 k
个唯一元素, 不替换 ,我认为这对您的情况很关键,因为您不希望在同一个问题上显示两次相同的答案。
这将简化您当前的 if 语句块,来自
if randomnumber == 0:
layout.addWidget(self.Correctanswer)
layout.addWidget(self.Incorrectans1)
layout.addWidget(self.Incorrectans2)
layout.addWidget(self.Incorrectans3)
到
choices = [self.Correctanswer, self.Incorrectans1, self.Incorrectans2, self.Incorrectans3]
for q in range(4):
layout.addWidget(random.sample(choices, 1))
又想到一个很酷的主意。如果您有大量 "pool" 可能的错误答案,您可以专门定义一个函数来提供随机选择的错误答案。类似于:
def provideWrongAnswers(self, number):
return random.sample(self.allWrongAnswersPool, number)
这将为您提供 number
错误的答案,以将其与正确的答案一起添加到布局中。
In [7]: choices = range(1,11)
In [9]: random.sample(choices, 3) # returns a different order of choices each time
Out[9]: [1, 7, 3]
In [10]: random.sample(choices, 3)
Out[10]: [6, 9, 3]
In [11]: random.sample(choices, 3)
Out[11]: [5, 4, 2]
In [12]: random.sample(choices, 3)
Out[12]: [3, 6, 1]
In [13]: random.sample(choices, 3)
Out[13]: [10, 8, 3]
In [14]: random.sample(choices, 3)
Out[14]: [1, 7, 2]
In [15]: random.sample(choices, 3)
Out[15]: [9, 7, 3]
最后,random.shuffle(x)
(link) 是另一种方法,因为它采用序列 x
并将它们混合到位。所以你可以结合 random.sample(wrongChoices, 3)
的想法,它给你三个随机的错误答案,然后添加正确答案并确保正确答案并不总是在底部,最后用 random.shuffle(allAnswerChoices)
您当前的结构似乎过于复杂。随机化问题选择比小部件本身要简单得多。
这是一个简单的演示,展示了如何做到这一点:
import sys, random
from PyQt4 import QtGui
class MultipleChoice(QtGui.QWidget):
def __init__(self, parent=None):
super(MultipleChoice, self).__init__(parent)
self.Questions = [
['What is the capital of Bhutan?',
'Thimphu', 'Bujumbura', 'Suva', 'Kigali'],
['What is the capital of Yemen?',
'Sana\'a', 'Malabo', 'Riyadh', 'Muscat'],
['What is the capital of Togo?',
'Lomé', 'Dakar', 'Abuja', 'Nouakchott'],
]
self.Questionum = QtGui.QLabel(self)
self.Questioninfo = QtGui.QLabel(self)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.Questionum)
layout.addWidget(self.Questioninfo)
self.buttonGroup = QtGui.QButtonGroup(self)
self.buttonGroup.buttonClicked.connect(self.handleChoice)
for index in range(4):
button = QtGui.QRadioButton(self)
self.buttonGroup.addButton(button, index)
layout.addWidget(button)
self.buttonNext = QtGui.QPushButton('Next', self)
self.buttonNext.clicked.connect(self.handleNext)
layout.addWidget(self.buttonNext)
self.index = -1
self.handleNext()
def handleNext(self):
self.index += 1
if self.index >= len(self.Questions):
self.index = 0
question = self.Questions[self.index]
self.Questionum.setText('Question %d:' % (self.index + 1))
self.Questioninfo.setText(question[0])
choices = question[1:]
random.shuffle(choices)
self.buttonGroup.setExclusive(False)
for index, choice in enumerate(choices):
button = self.buttonGroup.button(index)
button.setChecked(False)
button.setText(choice)
self.buttonGroup.setExclusive(True)
def handleChoice(self, button):
answer = self.Questions[self.index][1]
if button.text() == answer:
print('Right!')
else:
print('Wrong...')
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = MultipleChoice()
window.show()
sys.exit(app.exec_())
我正在做一个测验,我希望单选按钮位于不同的位置。我已经让它工作到一定程度,因为它在第一个问题中是随机排列的,但是它会在剩下的测验中保持这个顺序。我希望它每次都随机化。
class MultipleChoice(QtGui.QWidget):
showTopicsSignal = pyqtSignal()
def __init__(self,parent=None):
super(MultipleChoice, self).__init__(parent)
self.initUI()
def initUI(self):
self.Questions=[]
self.Questionum = QLabel()
self.Questioninfo = QLabel()
self.Correctanswer = QRadioButton()
self.Incorrectans1 = QRadioButton()
self.Incorrectans2 = QRadioButton()
self.Incorrectans3 = QRadioButton()
self.Correctanswer.setAutoExclusive(True)
self.Incorrectans1.setAutoExclusive(True)
self.Incorrectans2.setAutoExclusive(True)
self.Incorrectans3.setAutoExclusive(True)
layout = QVBoxLayout(self)
layout.addWidget(self.Questionum)
layout.addWidget(self.Questioninfo)
randomnumber = randint(0,3)
if randomnumber == 0:
layout.addWidget(self.Correctanswer)
layout.addWidget(self.Incorrectans1)
layout.addWidget(self.Incorrectans2)
layout.addWidget(self.Incorrectans3)
elif randomnumber == 1:
layout.addWidget(self.Incorrectans1)
layout.addWidget(self.Correctanswer)
layout.addWidget(self.Incorrectans2)
layout.addWidget(self.Incorrectans3)
elif randomnumber == 2:
layout.addWidget(self.Incorrectans1)
layout.addWidget(self.Incorrectans2)
layout.addWidget(self.Correctanswer)
layout.addWidget(self.Incorrectans3)
elif randomnumber == 3:
layout.addWidget(self.Incorrectans1)
layout.addWidget(self.Incorrectans2)
layout.addWidget(self.Incorrectans3)
layout.addWidget(self.Correctanswer)
如果将答案选择加载到容器中,则可以将 Python 的 random
(link) 库与以下一种或两种工具结合使用:
random.choice(seq)
(link) 随机选择seq
中提供的可能项目
random.sample(pop, k)
(link) 从pop
中提供的可能选项中选择k
个唯一元素, 不替换 ,我认为这对您的情况很关键,因为您不希望在同一个问题上显示两次相同的答案。
这将简化您当前的 if 语句块,来自
if randomnumber == 0:
layout.addWidget(self.Correctanswer)
layout.addWidget(self.Incorrectans1)
layout.addWidget(self.Incorrectans2)
layout.addWidget(self.Incorrectans3)
到
choices = [self.Correctanswer, self.Incorrectans1, self.Incorrectans2, self.Incorrectans3]
for q in range(4):
layout.addWidget(random.sample(choices, 1))
又想到一个很酷的主意。如果您有大量 "pool" 可能的错误答案,您可以专门定义一个函数来提供随机选择的错误答案。类似于:
def provideWrongAnswers(self, number):
return random.sample(self.allWrongAnswersPool, number)
这将为您提供 number
错误的答案,以将其与正确的答案一起添加到布局中。
In [7]: choices = range(1,11)
In [9]: random.sample(choices, 3) # returns a different order of choices each time
Out[9]: [1, 7, 3]
In [10]: random.sample(choices, 3)
Out[10]: [6, 9, 3]
In [11]: random.sample(choices, 3)
Out[11]: [5, 4, 2]
In [12]: random.sample(choices, 3)
Out[12]: [3, 6, 1]
In [13]: random.sample(choices, 3)
Out[13]: [10, 8, 3]
In [14]: random.sample(choices, 3)
Out[14]: [1, 7, 2]
In [15]: random.sample(choices, 3)
Out[15]: [9, 7, 3]
最后,random.shuffle(x)
(link) 是另一种方法,因为它采用序列 x
并将它们混合到位。所以你可以结合 random.sample(wrongChoices, 3)
的想法,它给你三个随机的错误答案,然后添加正确答案并确保正确答案并不总是在底部,最后用 random.shuffle(allAnswerChoices)
您当前的结构似乎过于复杂。随机化问题选择比小部件本身要简单得多。
这是一个简单的演示,展示了如何做到这一点:
import sys, random
from PyQt4 import QtGui
class MultipleChoice(QtGui.QWidget):
def __init__(self, parent=None):
super(MultipleChoice, self).__init__(parent)
self.Questions = [
['What is the capital of Bhutan?',
'Thimphu', 'Bujumbura', 'Suva', 'Kigali'],
['What is the capital of Yemen?',
'Sana\'a', 'Malabo', 'Riyadh', 'Muscat'],
['What is the capital of Togo?',
'Lomé', 'Dakar', 'Abuja', 'Nouakchott'],
]
self.Questionum = QtGui.QLabel(self)
self.Questioninfo = QtGui.QLabel(self)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.Questionum)
layout.addWidget(self.Questioninfo)
self.buttonGroup = QtGui.QButtonGroup(self)
self.buttonGroup.buttonClicked.connect(self.handleChoice)
for index in range(4):
button = QtGui.QRadioButton(self)
self.buttonGroup.addButton(button, index)
layout.addWidget(button)
self.buttonNext = QtGui.QPushButton('Next', self)
self.buttonNext.clicked.connect(self.handleNext)
layout.addWidget(self.buttonNext)
self.index = -1
self.handleNext()
def handleNext(self):
self.index += 1
if self.index >= len(self.Questions):
self.index = 0
question = self.Questions[self.index]
self.Questionum.setText('Question %d:' % (self.index + 1))
self.Questioninfo.setText(question[0])
choices = question[1:]
random.shuffle(choices)
self.buttonGroup.setExclusive(False)
for index, choice in enumerate(choices):
button = self.buttonGroup.button(index)
button.setChecked(False)
button.setText(choice)
self.buttonGroup.setExclusive(True)
def handleChoice(self, button):
answer = self.Questions[self.index][1]
if button.text() == answer:
print('Right!')
else:
print('Wrong...')
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = MultipleChoice()
window.show()
sys.exit(app.exec_())