为了账号安全,请及时绑定邮箱和手机立即绑定

如何调试 QComboBox 发出多个“激活”信号

如何调试 QComboBox 发出多个“激活”信号

潇潇雨雨 2022-06-07 19:59:35
我在这里找到了一个很好的资源来构建一个 QComboBox,它提供了一个过滤的建议列表。除了每次我在组合框中选择建议的选项时,“activated”和“currentIndexChanged”信号会发出三次之外,它运行良好。行为会有所不同,具体取决于是通过鼠标还是使用箭头键和 Enter 按钮选择了该选项。我的问题是,我该如何调试?代码中没有必要捕获和阻止前两个信号发出。有没有办法覆盖 QComboBox “激活”信号以尝试在行为中捕获它?还是我必须定义自己的信号并使用它?这是代码:#!/usr/bin/env python# -*- coding: utf-8 -*-from PySide2 import QtCore, QtGui, QtWidgetsfrom PySide2.QtCore import Qt, QSortFilterProxyModelfrom PySide2.QtWidgets import QCompleter, QComboBoxclass ExtendedComboBox(QComboBox):    def __init__(self, parent=None):        super(ExtendedComboBox, self).__init__(parent)        self.setFocusPolicy(Qt.StrongFocus)        self.setEditable(True)        # add a filter model to filter matching items        self.pFilterModel = QSortFilterProxyModel(self)        self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)        self.pFilterModel.setSourceModel(self.model())        # add a completer, which uses the filter model        self.completer = QtWidgets.QCompleter(self)        self.completer.setModel(self.pFilterModel)        # always show all (filtered) completions        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)        self.setCompleter(self.completer)        # connect signals        self.lineEdit().textEdited.connect(self.pFilterModel.setFilterFixedString)        self.completer.activated.connect(self.on_completer_activated)    # on selection of an item from the completer, select the corresponding item from combobox     def on_completer_activated(self, text):        if text:            index = self.findText(text)            self.setCurrentIndex(index)            # self.activated.emit(self.itemText(index))您会注意到,如果您运行代码并开始在文本框中输入“hello”,然后单击建议的“hello world”,activated信号会返回正确的“hello world”。如果你开始输入“hello”,但这次使用箭头键向下滚动到“hello world”,它会发出 3 次。我已经尝试过多次实现同样的想法,结果都一样。在用新模型替换模型后,我什至注意到未修改的 QComboBox 的类似行为。PySide2 5.6.0a1 Windows 10.0.18362 内部版本 18362谢谢参观!
查看完整描述

2 回答

?
隔江千里

TA贡献1906条经验 获得超10个赞

我使用的是 PySide2 5.6.0a1,因为这是 Anaconda 在 Python 2.7 环境中安装的一个。@eyllanesc 指出这是一个早期和过时的版本,可能有问题。

当我在 Python 3.7 环境中使用 PySide2-5.13.1 尝试相同的代码时,一切都按预期工作。


查看完整回答
反对 回复 2022-06-07
?
人到中年有点甜

TA贡献1895条经验 获得超7个赞

我没有 PySide2,但在大多数情况下,我认为您所要做的就是用 PySide2 替换我的 PyQt5 引用——因为这就是我所做的一切让你的程序从 PySide2 切换到 PyQt5 ——还有一点重组和微调给了我以下功能代码:


from sys import exit as sysExit


from PyQt5.QtCore import Qt, QSortFilterProxyModel, QStringListModel, pyqtSlot

from PyQt5.QtWidgets import QApplication, QWidget, QCompleter, QComboBox, QCompleter, QHBoxLayout


class ExtendedComboBox(QComboBox):

    def __init__(self):

        QComboBox.__init__(self)


        self.setFocusPolicy(Qt.StrongFocus)

        self.setEditable(True)


        # add a filter model to filter matching items

        self.pFilterModel = QSortFilterProxyModel(self)

        self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)

        self.pFilterModel.setSourceModel(self.model())


        # add a completer, which uses the filter model

        self.completer = QCompleter(self)

        self.completer.setModel(self.pFilterModel)


        # always show all (filtered) completions

        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)

        self.setCompleter(self.completer)


        # connect signals

        self.lineEdit().textEdited.connect(self.pFilterModel.setFilterFixedString)

        self.completer.activated.connect(self.on_completer_activated)


    # on selection of an item from the completer, select the corresponding item from combobox 

    def on_completer_activated(self, text):

        if text:

            index = self.findText(text)

            self.setCurrentIndex(index)

            # self.activated.emit(self.itemText(index))



    # on model change, update the models of the filter and completer as well 

    def setModel(self, model):

        self.setModel(model)

        self.pFilterModel.setSourceModel(model)

        self.completer.setModel(self.pFilterModel)



    # on model column change, update the model column of the filter and completer as well

    def setModelColumn(self, column):

        self.completer.setCompletionColumn(column)

        self.pFilterModel.setFilterKeyColumn(column)

        self.setModelColumn(column)    


class MainApp(QWidget):

    def __init__(self):

        QWidget.__init__(self)


        string_list = ['hola muchachos', 'adios amigos', 'hello world', 'good bye']


        self.combo = ExtendedComboBox()


        # either fill the standard model of the combobox

        self.combo.addItems(string_list)

        self.combo.currentIndexChanged[str].connect(self.change_option)

        # or use another model

        #combo.setModel(QStringListModel(string_list))


        self.resize(300, 100)

        self.combo.resize(300, 50)


        HBox = QHBoxLayout()

        HBox.addWidget(self.combo)


        self.setLayout(HBox)


    @pyqtSlot(str)

    def change_option(self, text):

        print(text)


if __name__ == "__main__":

    MainThred = QApplication([])


    MainGui = MainApp()

    MainGui.show()


    sysExit(MainThred.exec_())

我认为问题是您试图将 Signals/Slots 与非 QObject 函数(又名)一起使用,您的 change_option 函数与从 QObject 继承的任何内容都没有直接关联,所以我不确定它在做什么或没有在做什么,但是只是一个猜测,因为我所做的一切都被放入了一个正常的 Qt 结构中,它工作得很好


查看完整回答
反对 回复 2022-06-07
  • 2 回答
  • 0 关注
  • 161 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信