基于用户选择的标签组合框状态
Posted
技术标签:
【中文标题】基于用户选择的标签组合框状态【英文标题】:Combo box state of labels based on the user`s choice 【发布时间】:2020-10-09 20:59:30 【问题描述】:我有一个包含两个选项的组合框,我希望组合框中的选择将确定两个标签的状态。我的意思是,例如,如果用户选择“1”,我希望他只看到第一个标签,如果他选择“2”,第二个标签将出现。我成功地做到了,但问题是选择一次后,这个实现不再起作用了,我的意思是当做出新的选择时我不能让它起作用
这是我的代码:
self.comboBox.textActivated['QString'].connect(self.on_combobox_changed)
self.label_2.hide()
def on_combobox_changed(self):
if self.comboBox.currentText() == "2":
self.label_2.show()
好的,我刚刚添加了一个这样的 for 循环,它似乎可以工作,但我不确定它是否是一个好的实现
编辑:
def on_combobox_changed(self):
for x in range(0, 1000):
if self.comboBox.currentText() == "2":
self.label_2.show()
else:
self.label_2.hide()
【问题讨论】:
请提供minimal reproducible example 不,使用循环当然不是一个好的实现。你为什么使用textActivated
而不是currentTextChanged
?你为什么使用[QString]
语法?对于只有一种可能签名的信号(如 QComboBox 的所有信号),不需要选择信号签名。最后,如果要检查文本,信号已经在参数中提供了它,无需检查currentText()
属性。
您好,首先感谢您的回答。其次,我对 Gui 这个东西和 pyqt5 真的很陌生,所以我只是凭直觉做的。最后,我可以请你给我看一个它应该如何工作的例子吗?我没成功l。 @musicamante
【参考方案1】:
主要问题是一旦选择了组合框中的项目,就会发送textActivated
信号。
虽然这看起来很直观,但您必须考虑以下方面。
-
即使项目已经是当前项,也会发送信号
由于上述原因,每当用户激活组合中的项目时,它也会始终发送,当用户执行以下操作时也会发生这种情况:
使用键盘导航(箭头键、home/end、page up/down);
使用键盘在组合项中搜索;
在可编辑的组合上按 Enter;
点击弹出窗口中的项目;
键盘交互或鼠标选择不会立即更新视图的内容,包括
currentText()
属性,因为Qt需要一些时间来完成它的工作(通常,如果可编辑的组合有要添加的新项目,则更新组合模型)
另外,需要考虑的一个重要方面是textActivated
是一个相当新的功能(它是在不到一年前的 2019 年底在 Qt 5.14 中引入的),对于您的需求可能不是那么必要。
最后,基于索引的对象的字符串比较很少是个好主意,至少有两个重要原因:
-
在某些时候,您可能需要进行一些本地化;虽然在您的简单情况下,它只是一个数字的字符串表示形式,但有一天,简单的“2”可能会变成“text 2”、“texto 2”、“texte 2”或“testo 2”。
基于 UI 的框架有时会自动更改小部件的显示文本;虽然组合框项通常不是这种情况,但 Qt 有时会更改小部件的文本集以包含 助记符:包含可用作键盘加速器的下划线字母的文本,即以
&
开头的字母以编程方式可读;结果是您在按钮上设置了文本“保存”,然后当您调用button.text()
时,您会得到“&Save”。
因此,考虑到上述情况,这是您可能需要的一种可能实现(使用组合项索引而不是字符串):
from PyQt5 import QtWidgets
class ComboTest(QtWidgets.QWidget):
def __init__(self):
super().__init__()
layout = QtWidgets.QGridLayout(self)
self.comboBox = QtWidgets.QComboBox()
layout.addWidget(self.comboBox, 0, 0, 1, 2)
self.comboBox.addItems(['Label 1', 'Label 2'])
self.label_1 = QtWidgets.QLabel('Hello, label 1!')
layout.addWidget(self.label_1, 1, 0)
self.label_2 = QtWidgets.QLabel('Hello, label 2!')
layout.addWidget(self.label_2, 1, 1)
self.label_2.hide()
self.comboBox.currentIndexChanged.connect(self.showLabel)
def showLabel(self, index):
if index == 0:
self.label_1.show()
self.label_2.hide()
elif index == 1:
self.label_1.hide()
self.label_2.show()
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
test = ComboTest()
test.show()
sys.exit(app.exec_())
最后一点。在显示其父级之前隐藏小部件可能是个问题。在上面的示例中,您会注意到,当您再次选择第二个项目并然后第一个项目时,小部件将自行调整大小。虽然在这种特定情况下它可能不是什么大问题,但对于复杂的布局,从用户体验的角度来看这不是一件好事(用户不喜欢 UI 意外改变其大小)。一种可能的替代方法是改用QStackedWidget,使用addWidget()
添加标签,然后使用组合索引调用其setCurrentIndex()
。
from PyQt5 import QtWidgets
class ComboTest(QtWidgets.QWidget):
def __init__(self):
super().__init__()
layout = QtWidgets.QVBoxLayout(self)
self.comboBox = QtWidgets.QComboBox()
layout.addWidget(self.comboBox)
self.comboBox.addItems(['Label 1', 'Label 2'])
self.stackedWidget = QtWidgets.QStackedWidget()
layout.addWidget(self.stackedWidget)
self.label_1 = QtWidgets.QLabel('Hello, label 1!')
self.stackedWidget.addWidget(self.label_1)
self.label_2 = QtWidgets.QLabel('Hello, label 2!')
self.stackedWidget.addWidget(self.label_2)
self.comboBox.currentIndexChanged.connect(
self.stackedWidget.setCurrentIndex)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
test = ComboTest()
test.show()
sys.exit(app.exec_())
【讨论】:
好的,谢谢您的详细解答。从那个答案中学到了很多。欣赏它。以上是关于基于用户选择的标签组合框状态的主要内容,如果未能解决你的问题,请参考以下文章
下拉菜单(选择标签、组合框)在 GeckoView 实现中不起作用