i am trying to realize kind a like a swipe gesture on a ListView. The listView is part of a stackedWidget which should change the page if the Event gets triggered.
It works if the return Value of eventFilter is True. But if so the ListView disappears. If the value is False, the ListView reappears, but different events get triggered.
I added a minimal example, which makes the Problem i am facing much more clear.
I understood that the return Value determines if the event should be filtered (True) or not (False) but i dont understand what happens here.
I am Thankful for every hint,tip or for another approach to this. Best with a minimal working example.
main.py
import sys
from PyQt6 import QtCore, QtWidgets
from PyQt6.QtGui import QIcon, QStandardItem
from PyQt6.QtWidgets import QVBoxLayout, QPushButton
from listView_minimal_example import ListView_Categories
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1190, 870)
MainWindow.setStyleSheet(
"QWidget{\n"
" background-color: rgb(61, 121, 60);\n"
"}\n"
"\n"
)
MainWindow.Wrapper_Kategories = QtWidgets.QStackedWidget(MainWindow)
MainWindow.Wrapper_Kategories.setGeometry(QtCore.QRect(9, 179, 1200, 621))
MainWindow.Wrapper_Kategories.setObjectName("Wrapper_Kategories")
self.page_1 = ListView_Categories(MainWindow)
self.page_1.setGeometry(QtCore.QRect(150, 110, 1200, 80))
self.page_1.setObjectName("view 1")
self.page_2 = ListView_Categories(MainWindow)
self.page_2.setGeometry(QtCore.QRect(150, 110, 1200, 80))
self.page_2.setObjectName("view 2")
MainWindow.Wrapper_Kategories.addWidget(self.page_1)
MainWindow.Wrapper_Kategories.addWidget(self.page_2)
item = QStandardItem()
item.setIcon(QIcon("000_Ordnerstruktur/003_Test/1.ico"))
self.page_1.m_model.appendRow(item)
item = QStandardItem()
item.setIcon(QIcon("000_Ordnerstruktur/003_Test/1.ico"))
self.page_2.m_model.appendRow(item)
self.btn = QPushButton()
self.btn.setText("Switch View")
layout = QVBoxLayout()
layout.addWidget(self.btn)
layout.addWidget(MainWindow.Wrapper_Kategories)
self.btn.mousePressEvent = self.switch_view
MainWindow.setLayout(layout)
def switch_view(self,data):
MainWindow.Wrapper_Kategories.setCurrentIndex(1)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QWidget()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec())
listView_minimal_example.py
from PyQt6.QtWidgets import QListView, QAbstractItemView
from PyQt6.QtCore import QSize, QEvent
from PyQt6.QtGui import QStandardItemModel
class ListView_Categories(QListView):
def __init__(self, parent:None):
super().__init__(parent)
self.parent = parent
self.m_model = QStandardItemModel(self)
self.setModel(self.m_model)
self.setAcceptDrops(False)
self.setIconSize(QSize(150,150))
self.setDragDropMode(QAbstractItemView.DragDropMode.NoDragDrop)
self.setResizeMode(QListView.ResizeMode.Adjust)
self.setViewMode(QListView.ViewMode.IconMode)
# Catch the event
self.installEventFilter(self)
self.setStyleSheet(
"QListView{\n"
" background-color:rgb(92, 52, 19)\n"
"}"
)
# True if the event should be filtered
# else Flase
def eventFilter(self, widget, event):
print("event ", event.type())
if(event.type() == QEvent.Type.MouseButtonPress):
print("event")
print(event.type())
print(event.spontaneous())
pos = event.pos()
self.position_1 = pos.x()
print("Entered at:", pos.x(), pos.y())
return True
elif(event.type() == QEvent.Type.MouseButtonRelease):
pos_2 = event.pos()
self.position_2 = pos_2.x()
if(self.position_1 < self.position_2 and abs(self.position_1-self.position_2) >= 100):
print("left swipe")
self.parent.Wrapper_Kategories.setCurrentIndex(self.parent.Wrapper_Kategories.currentIndex() + 1)
return True
elif(abs(self.position_1-self.position_2) >= 100):
print("right swipe")
self.parent.Wrapper_Kategories.setCurrentIndex(self.parent.Wrapper_Kategories.currentIndex() - 1)
return True
#return super().eventFilter(widget,event)
#if True listView disappears if False diffrent Event Types occur
return True
I am unsure if the problem gets clear or stays the same without adding an icon to the listView(s)
return Truefor any event, because it means that NO event will be handled (including painting). Besides, if you want to intercept mouse events, you should just overridemousePressEvent()andmouseReleaseEvent()in the view. Be aware, though, that this would completely prevent -> - musicamantesuper().mousePress/ReleaseEvent(event)), but you should also ensure that you don't need manual item positioning. Besides, is this intended for touch surfaces? If that's so, you should use touch events, not mouse events. Also note that overwriting themousePressEventof the button to switch the view is completely wrong: use the button'sclickedsignal, and connect it to the relative function. - musicamante