Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Mouse handling using asyncio?
Forum Updated to NodeBB v4.3 + New Features

Mouse handling using asyncio?

Scheduled Pinned Locked Moved Solved Qt for Python
8 Posts 3 Posters 1.0k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    dullfig
    wrote on last edited by
    #1

    So I'm writing a mouse class that you call when you want to drag and draw a selection area on the screen. The idea is that the calling function calls areaSelect, then waits for areaSelect to return a Rect() of the location of the dragged rectangle. I have written a very basic outline of what the class will look like. Right now it hooks into the mouse events, sets a bool to True, then waits forever for the mouse release. I was wondering if there is a more elegant way than an endless While, like using async or something, to wait for the bool to be set to False.

    from PySide6.QtWidgets import QWidget
    from PySide6.QtCore import QRect
    
    class MouseHandler(QWidget):
        def __init__(self):
            super().__init__()
            self.drag_in_progress = False
    
        def mousePressEvent(self, event):
            if self.drag_in_progress is True:
                # do something
                pass
    
        def mouseMoveEvent(self, event):
            if self.drag_in_progress is True:
                # do something
                pass
    
        def mouseReleaseEvent(self, event):
            if self.drag_in_progress is True:
                # do something
                self.drag_in_progress = False
    
        def areaSelect(self) -> QRect:
            self.drag_in_progress = True
            while self.drag_in_progress is not False:
                pass
            return QRect(0, 0, 1, 1)
    
    
    1 Reply Last reply
    0
    • D Offline
      D Offline
      dullfig
      wrote on last edited by dullfig
      #5

      I just realized that this idea won't work. You can't just have one event handler halt the whole GUI while waiting for a rectangle to be drawn. Back to the drawing board.

      JonBJ 1 Reply Last reply
      0
      • JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by JonB
        #2

        Leaving aside whether there are already other ways to do this.

        The point about event-driven UI coding is that you don't write or call a function like your areaSelect(), which blocks till something happens. Instead in your mouseReleaseEvent() you recognise/calculate the dragged rectangle and execute whatever you want to do with it from there, either directly or via Qt's signal/slot system so you can write the handler code elsewhere.

        1 Reply Last reply
        1
        • D Offline
          D Offline
          dullfig
          wrote on last edited by
          #3

          two things:

          my code already does a "zoom to area" thing that does get handled in the mouseRelease event, but I wanted to come up with a more generalized way of doing it, as I can see "drag and click" to come in handy in other parts of my program. And yes, if I call this function from inside another event handler, then the mouse clicks will never even be seen.

          you mentioned "other ways to do this". can you point me in that direction?

          1 Reply Last reply
          0
          • JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by JonB
            #4

            If you want to draw the selecting band see QRubberBand.
            If you were using a GraphicsScene that has rubberband drawing and selection. I don't know about QWidget, what you are doing there, what your zooming is about, etc.
            Qt also has various item-selection mechanisms if that is what you want.
            If you want a "more generalized way of doing it" have your mouseReleaseEvent() emit a signal for the area selection or whatever.
            It is "unusual" to declare a class deriving from QWidget to be a MouseHandler in any generic sense. I don't know how you think you are going to use your class.

            1 Reply Last reply
            0
            • D Offline
              D Offline
              dullfig
              wrote on last edited by dullfig
              #5

              I just realized that this idea won't work. You can't just have one event handler halt the whole GUI while waiting for a rectangle to be drawn. Back to the drawing board.

              JonBJ 1 Reply Last reply
              0
              • D dullfig has marked this topic as solved on
              • D dullfig

                I just realized that this idea won't work. You can't just have one event handler halt the whole GUI while waiting for a rectangle to be drawn. Back to the drawing board.

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #6

                @dullfig
                But that is exactly what I said! You must not "wait" for anything. And you don't need to. You don't have to "go back to the drawing board", you just need to do your work from mouseReleaseEvent(), as I wrote earlier either directly or via emitting a signal. I don't see the problem.

                1 Reply Last reply
                1
                • D Offline
                  D Offline
                  dullfig
                  wrote on last edited by
                  #7

                  yup. thanks

                  1 Reply Last reply
                  0
                  • S Offline
                    S Offline
                    SimonSchroeder
                    wrote on last edited by
                    #8

                    Well, there is a way to achieve what you want to do. Still, it is better not to do it this way. Instead of your infinite loop you can create QEventLoop and call exec() on it. On mouseReleaseEvent you can then quit the local event loop. Be careful with this if you really want to go down this route... (nested event loops can be nasty!)

                    1 Reply Last reply
                    0

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved