zhiyiYo / PyQt-Fluent-Widgets

A fluent design widgets library based on C++ Qt/PyQt/PySide. Make Qt Great Again.
https://qfluentwidgets.com
GNU General Public License v3.0
4.99k stars 464 forks source link

[Bug]: TableWidget安装了事件过滤器后无法监听鼠标按下的事件 #885

Open qianye216 opened 1 month ago

qianye216 commented 1 month ago

What happened?

目前有个场景是想在TableWidget区域监听鼠标侧键按下的事件,监听到则返回上一页,但是发现无法监听,经调试发现是由于基类TableBase中的mousePressEvent方法导致,当TableWidget设置了setSelectRightClickedRow(True)后就无法监听鼠标按下事件, 原代码如下

def mousePressEvent(self, e):
        if e.button() == Qt.LeftButton or self._isSelectRightClickedRow:
            return QTableView.mousePressEvent(self, e)            

        index = self.indexAt(e.pos())
        if index.isValid():
            self._setPressedRow(index.row())

        QWidget.mousePressEvent(self, e)

改成以下代码后发现可以解决问题,但是不确定是否会导致其他问题:

def mousePressEvent(self, e):
        if e.button() == Qt.RightButton and self._isSelectRightClickedRow:
            return QTableView.mousePressEvent(self, e)  

        if e.button() == Qt.LeftButton:
            return QTableView.mousePressEvent(self, e)            

        index = self.indexAt(e.pos())
        if index.isValid():
            self._setPressedRow(index.row())

        QWidget.mousePressEvent(self, e)

Operation System

Mac

Python Version

3.11.7

PyQt/PySide Version

PyQt 5.15.9

PyQt/PySide-Fluent-Widgets Version

v1.5.6

How to Reproduce?

希望TableWidget能够支持通过事件过滤器监听鼠标按下事件

Minimum code

组件库源码table_view.py
immiProgrammer commented 1 month ago

maybe to solve this problem modify mousePressEvent() in qfluentwidgets.TableBase

    def mousePressEvent(self, e):
        if e.button() == Qt.LeftButton:
            if self._isSelectRightClickedRow:
                QTableView.mousePressEvent(self, e)
            return # or use else

        index = self.indexAt(e.pos())
        if index.isValid():
            self._setPressedRow(index.row())

        QTableView.mousePressEvent(self, e)
zhiyiYo commented 1 month ago

可以提供最小复现代码吗

qianye216 commented 1 month ago

可以提供最小复现代码吗

# coding: utf-8
import sys

from PyQt5.QtCore import QModelIndex, Qt
from PyQt5.QtGui import QPalette
from PyQt5.QtWidgets import QApplication, QStyleOptionViewItem, QTableWidget, QTableWidgetItem, QWidget, QHBoxLayout

from qfluentwidgets import TableWidget, isDarkTheme, setTheme, Theme, TableView, TableItemDelegate, setCustomStyleSheet

class Demo(QWidget):

    def __init__(self):
        super().__init__()
        # setTheme(Theme.DARK)

        self.hBoxLayout = QHBoxLayout(self)
        self.tableView = TableWidget(self)

        # select row on right-click
        self.tableView.setSelectRightClickedRow(True)

        # enable border
        self.tableView.setBorderVisible(True)
        self.tableView.setBorderRadius(8)

        self.tableView.setWordWrap(False)
        self.tableView.setRowCount(60)
        self.tableView.setColumnCount(5)
        songInfos = [
            ['かばん', 'aiko', 'かばん', '2004', '5:04'],
            ['爱你', '王心凌', '爱你', '2004', '3:39'],
            ['星のない世界', 'aiko', '星のない世界/横顔', '2007', '5:30'],
            ['横顔', 'aiko', '星のない世界/横顔', '2007', '5:06'],
            ['秘密', 'aiko', '秘密', '2008', '6:27'],
            ['シアワセ', 'aiko', '秘密', '2008', '5:25'],
            ['二人', 'aiko', '二人', '2008', '5:00'],
            ['スパークル', 'RADWIMPS', '君の名は。', '2016', '8:54'],
            ['なんでもないや', 'RADWIMPS', '君の名は。', '2016', '3:16'],
            ['前前前世', 'RADWIMPS', '人間開花', '2016', '4:35'],
            ['恋をしたのは', 'aiko', '恋をしたのは', '2016', '6:02'],
            ['夏バテ', 'aiko', '恋をしたのは', '2016', '4:41'],
            ['もっと', 'aiko', 'もっと', '2016', '4:50'],
            ['問題集', 'aiko', 'もっと', '2016', '4:18'],
            ['半袖', 'aiko', 'もっと', '2016', '5:50'],
            ['ひねくれ', '鎖那', 'Hush a by little girl', '2017', '3:54'],
            ['シュテルン', '鎖那', 'Hush a by little girl', '2017', '3:16'],
            ['愛は勝手', 'aiko', '湿った夏の始まり', '2018', '5:31'],
            ['ドライブモード', 'aiko', '湿った夏の始まり', '2018', '3:37'],
            ['うん。', 'aiko', '湿った夏の始まり', '2018', '5:48'],
            ['キラキラ', 'aikoの詩。', '2019', '5:08', 'aiko'],
            ['恋のスーパーボール', 'aiko', 'aikoの詩。', '2019', '4:31'],
            ['磁石', 'aiko', 'どうしたって伝えられないから', '2021', '4:24'],
            ['食べた愛', 'aiko', '食べた愛/あたしたち', '2021', '5:17'],
            ['列車', 'aiko', '食べた愛/あたしたち', '2021', '4:18'],
            ['花の塔', 'さユり', '花の塔', '2022', '4:35'],
            ['夏恋のライフ', 'aiko', '夏恋のライフ', '2022', '5:03'],
            ['あかときリロード', 'aiko', 'あかときリロード', '2023', '4:04'],
            ['荒れた唇は恋を失くす', 'aiko', '今の二人をお互いが見てる', '2023', '4:07'],
            ['ワンツースリー', 'aiko', '今の二人をお互いが見てる', '2023', '4:47'],
        ]
        songInfos += songInfos
        for i, songInfo in enumerate(songInfos):
            for j in range(5):
                self.tableView.setItem(i, j, QTableWidgetItem(songInfo[j]))

        self.tableView.verticalHeader().hide()
        self.tableView.setHorizontalHeaderLabels(['Title', 'Artist', 'Album', 'Year', 'Duration'])
        self.tableView.resizeColumnsToContents()
        self.tableView.setSortingEnabled(True)

        self.setStyleSheet("Demo{background: rgb(255, 255, 255)} ")
        self.hBoxLayout.setContentsMargins(50, 30, 50, 30)
        self.hBoxLayout.addWidget(self.tableView)
        self.resize(735, 760)

    def mousePressEvent(self, e):
        if e.button() == Qt.RightButton:
            print('right click')

        elif e.button() == Qt.LeftButton:
            print('left click')
        #鼠标侧键
        elif e.button() == Qt.BackButton:
            print('back click')

if __name__ == "__main__":
    # enable dpi scale
    QApplication.setHighDpiScaleFactorRoundingPolicy(
        Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
    QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
    QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)

    app = QApplication(sys.argv)
    w = Demo()
    w.show()
    app.exec()

当有设置self.tableView.setSelectRightClickedRow(True)的时候,鼠标按下事件就无法监听右键、鼠标侧键了,事件过滤器也一样