Как перехватить сигнал мыши в QComboBox - PullRequest
1 голос
/ 02 мая 2019

У меня есть пользовательское поле со списком, помещенное в виджет QDialog, и я не могу поймать ни один из сигналов мыши. Я подклассифицировал QComboBox для перехвата двух сигналов, не предоставляемых QComboBox: LostFocusEvent и mouseDobleClickEvent. LostFocusEvent работает хорошо, но комбо не запускает события мыши. Мне нужно три сигнала в поле со списком, и предоставляется только один подходящий.

Я попытался установить combo.grabMouse (), не обращая внимания на предупреждения документации, и combo.doubleClicked начал работать, но все остальные виджеты, подключенные через сигналы, начинают работать беспорядочно. Также попробовал combo.view (). DoubleClick.connect с похожими результатами. Также я пробовал другие события мыши с похожими результатами (пресс-релиз-и т. Д.) Наконец, я попытался использовать событие вместо QMouseEvent в подклассе comboBox, но оно перехватывается слотом focusOutEvent. Работа с мышью на QPushButtons, включая двойной щелчок на виджетах QTableView Использование Windows 8 Python 3.7 PyQt5.

`class Agreement(QDialog):
    def __init__(self,db, address, parent=None):
        super().__init__(parent= None)
        self.parent = parent
.......................................

    def setUi(self):
    .....................................
        self.comboSupplier = ComboFocus.FocusCombo(self)
        self.comboSupplier.setMaximumSize(220,30)
        self.comboSupplier.setEditable(True)
        #self.comboSupplier.grabMouse()
        self.comboSupplier.activated.connect(self.supplierChange)
        self.comboSupplier.focusLost.connect(self.supplierFocusLost)
        self.comboSupplier.doubleClicked.connect(self.editContact)
    ...........................................

     def supplierChange(self):
        try:
            row = self.comboSupplier.currentIndex()
            idx = self.comboSupplier.model().index(row,0)
            self.supplierId = self.comboSupplier.model().data(idx)
            self.agreementTitle[0] = self.comboSupplier.currentText()
            self.setAgreementTitle()
            self.okToSave[2] = int(self.supplierId)
            self.okSaving()
        except TypeError as err:
            print('supplierChange' + type(err).__name__ + ' ' + err.args[0])

    @pyqtSlot()
    def editContact(self):
        try:
            c = Contacts(self.db,self.comboSupplier.currentText(), 
                APM.OPEN_EDIT_ONE, self.supplierId,parent=self)
            c.show()
            c.exec()
        except Exception as err:
            print(type(err).__name__, err-args)

    @pyqtSlot(ComboFocus.FocusCombo)
    def supplierFocusLost(self, combo):
        try:
            self.setFocusPolicy(Qt.NoFocus)
            name = combo.currentText()
            if combo.findText(name) > -1:
                return
       ........................................

class FocusCombo(QComboBox):
    focusLost = pyqtSignal(QComboBox)
    focusGot = pyqtSignal(QComboBox)
    doubleClicked = pyqtSignal(QComboBox)

    def __init__(self, parent = None):
        super().__init__(parent)
        self.parent = parent

    def mouseDoubleClickEvent(self,event=QMouseEvent.MouseButtonDblClick):
        print("double click detected")

        self.doubleClicked.emit(self)

    def focusOutEvent(self, event):
        if event.gotFocus():
            self.focusGot.emit(self)

        elif event.lostFocus():
            self.focusLost.emit(self)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    cb = FocusCombo()
    cb.show()
    app.exec_()
    sys.exit(app.exec_())

Я бы хотел дважды щелкнуть на поле со списком, чтобы открыть виджет для редактирования атрибутов контакта на лету.

1 Ответ

0 голосов
/ 02 мая 2019

Когда вы устанавливаете QLineEdit для редактирования, добавляется QLineEdit, поэтому для отслеживания ваших событий вы должны использовать eventFilter:

from PyQt5 import QtCore, QtGui, QtWidgets

class FocusCombo(QtWidgets.QComboBox):
    focusLost = QtCore.pyqtSignal(QtWidgets.QComboBox)
    focusGot = QtCore.pyqtSignal(QtWidgets.QComboBox)
    doubleClicked = QtCore.pyqtSignal(QtWidgets.QComboBox)

    def setEditable(self, editable):
        super(FocusCombo, self).setEditable(editable)
        if self.lineEdit() is not None:
            self.lineEdit().installEventFilter(self)

    def eventFilter(self, obj, event):
        if obj is self.lineEdit():
            if event.type() == QtCore.QEvent.MouseButtonDblClick:
                self.doubleClicked.emit(self)
            """elif event.type() == QtCore.QEvent.MouseButtonPress:
                print("press")
            elif event.type() == QtCore.QEvent.MouseButtonRelease:
                print("release")"""
        return super(FocusCombo, self).eventFilter(obj, event)

    def mouseDoubleClickEvent(self,event):
        print("double click detected")
        self.doubleClicked.emit(self)
        super(FocusCombo, self).mouseDoubleClickEvent(event)

    def focusOutEvent(self, event):
        if event.gotFocus():
            self.focusGot.emit(self)

        elif event.lostFocus():
            self.focusLost.emit(self)
        super(FocusCombo, self).focusOutEvent(event)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    cb = FocusCombo()
    cb.addItems(list("abcdef"))
    cb.setEditable(True)
    cb.doubleClicked.connect(print)
    cb.show()
    sys.exit(app.exec_())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...