【问题标题】:Why overriding mousePressEvent in PyQt makes clicking signal doesn't trigger?为什么在 PyQt 中覆盖 mousePressEvent 会使点击信号不触发?
【发布时间】:2018-02-06 13:13:35
【问题描述】:

我正在使用 Python 3.5 和 PyQt5 编写软件。当我覆盖 QTableWidget 的 mousePressEvent 时,cellClicked 信号不再触发。我需要覆盖 mousePressEvent 以获取鼠标单击的位置,而 cellClicked 需要为单击的单元格执行另一项工作。为什么会这样?问题出在哪里? 这是我覆盖事件的代码:

class QTableWidget(QTableWidget):
    def checking(self):
        if (self.endgingposx - self.startingposx) >= 50:
            self.clear()
    def mousePressEvent(self,event):
        event.accept()
        self.startingposx = event.x()
    def mouseReleaseEvent(self,event):
        event.accept()
        self.endgingposx = event.x()
        self.checking()

这是我的点击信号,它是已连接的插槽:

self.main_table.cellClicked.connect(self.populatescnte)

def populatescnte(self,row,column):
    itemnum = self.scentence_listw.count()
    exec("item{} = QListWidgetItem(QIcon('content/img/food.png'),'{}')".format(itemnum+1,self.main_table.cellWidget(row,column).text))
    exec("self.scentence_listw.addItem(item{})".format(itemnum+1))

self.scentence_listw 是一个 QListWidget。 提前谢谢你。


更新 谢谢大家,这段代码对我有用:

class myTableWidget(QTableWidget):
def checking(self):
    if (self.endgingposx - self.startingposx) >= 50:
    self.clear()
def mousePressEvent(self,event):
    super().mousePressEvent(event)
    self.startingposx = event.x()
def mouseReleaseEvent(self,event):
    super().mouseReleaseEvent(event)
    self.endgingposx = event.x()
    self.checking()

【问题讨论】:

  • (不太了解 Python 或 QT 警告)- 当您覆盖 GUI 的事件处理程序时,这通常意味着不再调用原始事件处理程序。点击可能是由该原始处理程序生成的。要恢复它,您的替换处理程序应该直接调用原始处理程序 - 可能调用相同的事件处理程序名称,但用于基类。顺便说一句 - 我读的是顶行吗?基类和派生类的名称是否相同?这可能会使调用基类方法(例如原始处理程序)变得困难,尽管我不记得足够多的 Python 来确定。
  • @Steve314 如果我更改派生类的名称,则不会发生更改的事件。如何直接调用原始处理程序?
  • 您需要为 mousePressEvent 调用 super 才能启动原始处理程序。
  • @DanielePantaleone 我写了这个:super().mousePressEvent() 但它给出了错误发送不是我提出的 QMouseEvent 的 enoghu 争论,但它给出了它的论点错误。正确的方法是什么?
  • 您需要将QMouseEvent实例传递给原始处理程序:super().mousePressEvent(event)

标签: python pyqt pyqt5 qtablewidget


【解决方案1】:

该事件没有被传播,因为您已在处理程序中接受它。

您允许需要调用原始处理程序。

FWIW,您可以将处理程序连接到 itemSelectionChanged 并在桌面上获取 selectedItems 而不是跟踪位置。

import sys
from PyQt5.QtWidgets import (
    QApplication, QWidget, QTableWidget, 
    QTableWidgetItem, QGridLayout
)


class Widget(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()    

    def initUI(self):
        self.setGeometry(300, 300, 300, 220)
        self.setWindowTitle('Simple')

        table = TrackedTableWidget()

        layout = QGridLayout()
        layout.addWidget(table, 0, 0)
        self.setLayout(layout)

        self.show()


class TrackedTableWidget(QTableWidget):
    def __init__(self, *args, **kwargs):
        super().__init__()

        self.initUI()    

    def initUI(self):
        self.setRowCount(2)
        self.setColumnCount(2)
        self.setItem(0, 0, QTableWidgetItem('30', 0));
        self.setItem(0, 1, QTableWidgetItem('40', 0));
        self.setItem(1, 0, QTableWidgetItem('50', 0));
        self.setItem(1, 1, QTableWidgetItem('60', 0));

        self.cellClicked.connect(self._handle_cell_clicked)
        self.itemSelectionChanged.connect(self._handle_item_selection)

    def _handle_cell_clicked(self, row, column):
        print('cell_clicked', row, column)
        print('selected cell positions', self.startingposx, self.endingposx)

    def _handle_item_selection(self, *args):
        print(self.selectedItems())
        print('item_selection', args)

    def mousePressEvent(self, event):
        print('mousePressEvent')
        self.startingposx = event.x()
        super().mousePressEvent(event)

    def mouseReleaseEvent(self, event):
        print('mouseReleaseEvent')
        self.endingposx = event.x()
        super().mouseReleaseEvent(event)

if __name__ == '__main__':

    app = QApplication(sys.argv)
    widget = Widget()

    sys.exit(app.exec_())

参考

【讨论】:

  • 这是在您做出@Steve314 所述的更改之后吗?
  • 我做了更改并说出发生了什么。
  • 没有任何变化。无论有没有超级方法,我都测试了接受行但没有任何变化。
【解决方案2】:

我按如下方式处理事件:

class Ui(QtWidgets.QMainWindow):
  def __init__(self):
    super(Ui, self).__init__() # Call the inherited classes __init__ method
    uic.loadUi('./mainwindow.ui', self) # Load the .ui file

    self.myButton.pressed.connect(self.mousePress)

    self.show() # Show the GUI

  def mousePress(self):
     print("Mouse pressed")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-16
    • 1970-01-01
    • 2015-11-20
    • 1970-01-01
    • 1970-01-01
    • 2019-01-30
    • 2015-01-29
    相关资源
    最近更新 更多