Hello I am making a software in python I am not very good and so far I have not had to use any class in my program. I want to do events with the mouse without going through class and the codes I found all use class, it is difficult for me to use it without breaking my program.
Here is my code:
def init_tree(win):
tw = QTreeWidget(win)
tw.resize(500, 500)
tw.setHeaderLabels(['TAGS'])
tw.setAlternatingRowColors(True)
tw = clear_tree(tw)
fill_tree(tw)
tw.show()
def main():
app = QApplication.instance()
if not app:
app = QApplication(argv)
window = widgets()
init_tree(window)
mouse_press_event(window)
exit(app.exec_())
main()
And here is the code i want to add
def contextMenuEvent(self, event):
contextMenu = QMenu(self)
newAct = contextMenu.addAction("New")
openAct = contextMenu.addAction("Open")
quitAct = contextMenu.addAction("Quit")
action = contextMenu.exec_(self.mapToGlobal(event.pos()))
if action == quitAct:
self.close()
OR
class MyWidget(QWidget):
def __init__(self):
super(MyWidget, self).__init__()
def mousePressEvent(self, QMouseEvent):
if QMouseEvent.button() == Qt.LeftButton:
print("Left Button Clicked")
elif QMouseEvent.button() == Qt.RightButton:
#do what you want here
print("Right Button Clicked")
For self I pass win as a parameter
What I'm having trouble with is the "event/ QMouseEvent" parameter
It can partially be done, and it's generally called monkey patching, which is a piece of Python code which extends or modifies other code.
You cannot do that for event management as you did with your
init_tree
function, though: those function are "static", as they just get called once, while event driven functions should be called whenever the related event is emitted.The solution is then to "monkey patch" the class instance with the function that reacts to those events. This is a simple example:
Now, there's a catch. ALL instance methods have a first argument which is a reference to the instance, that's what
self
is (note that "self" is just a convention, you could actually name it as you wish). That's because instance methods normally need to do something with or at the instance. This is clear in thecontextMenuEvent
code you provided: theself
is important to set the parent of the menu and, most importantly, to use itsmapToGlobal
.When you monkey patch with an anonymous function like the one above, you don't get the first instance argument (in fact, we only have the
event
argument). In order to get that, with "anonymous" monkey patching we have to provide the instance argument artificially, and we can uselambda
for that:Note: I changed your code a bit, directly using
event.globalPos()
; the reason is that all QAbstractScrollArea subclasses (like all QAbstractItemView subclasses as QTreeWidget) have a child "viewport" that actually shows the content that are going to scroll, and that viewport is sometimes translated by some pixels, for example when a header is shown.The original function should be changed to this:
But we clearly don't need that, as all mouse events also have a
globalPos()
that is already mapped to global coordinates.Finally, while there are some cases for which your approach is ideal (usually very simple reimplementation done on the fly with temporary instances), if you're going to do that for a whole program you should consider four aspects:
If you believe that following this approach might ease things up, sorry but you're wrong: at some point your program would become too complex, and all those anonymous will only make your program very hard to read and debug.
Instead of finding complex and unorthodox ways to do something in a way it's not supposed to do, learn to do it in the correct way.
As a further note, monkey patching has an important issue with PyQt: Qt uses function caching to speed up things and use less resources, and if a function is called first with an already existing base method, monkey patching will not work at all, as that first original method will always be called afterwards.
So, take your time, learn how to create subclasses, and you'll not only find out that they're more easy than they seem, but will improve your coding dramatically.