Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. setCursor Confusion
QtWS25 Last Chance

setCursor Confusion

Scheduled Pinned Locked Moved Unsolved General and Desktop
13 Posts 4 Posters 1.4k Views
  • 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.
  • S Offline
    S Offline
    sandro4912
    wrote on last edited by
    #1

    I have a class derrived from QGraphicsView.

    Here I use setCursor like this:

    void DungeonView::mousePressEvent(QMouseEvent *event)
    {
        if (event->button() == Qt::RightButton) {
            setCursor(Qt::CrossCursor);
        }
        else {
            QGraphicsView::mousePressEvent(event);
        }
    }
    
    void DungeonView::mouseReleaseEvent(QMouseEvent *event)
    { 
        if (cursor() == Qt::CrossCursor) {
            setCursor(Qt::ArrowCursor);
        }
        else {
            QGraphicsView::mouseReleaseEvent(event);
        }
    }
    

    This view contains a widget derrived from QGraphicsWidget.

    Here I do this:

    void Room::mousePressEvent(QGraphicsSceneMouseEvent *event)
    {
        if (event->button() == Qt::MouseButton::LeftButton) {
            setCursor(Qt::ClosedHandCursor);
        }
    }
    
    void Room::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
    {
        if (event->button() == Qt::LeftButton) {
            setCursor(Qt::OpenHandCursor);
        }
    }
    

    My assumption Is what I expect what will happen:

    If i press release the right button DungeonView handles the changes of the Cursor.
    If i press release the left button DungeonView forwards the events to room and it
    handles the changes of the Cursor.

    However if I pressed the left Button I alway see the Cursor of the left button. Event if I use right button again I always see the Cursor from the left button.

    It looks like Room never gives the events to DungeonView back. Why is that so ?

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      Why don't you call the base class implementation in your Room subclass ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      4
      • mrjjM Offline
        mrjjM Offline
        mrjj
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi
        In room, try calling
        https://doc.qt.io/qt-5/qevent.html#ignore

        1 Reply Last reply
        1
        • S Offline
          S Offline
          sandro4912
          wrote on last edited by
          #4

          I tryed this but still the hand cursors from Room stay.

          void Room::mousePressEvent(QGraphicsSceneMouseEvent *event)
          {
              if (event->button() == Qt::MouseButton::LeftButton) {
                  setCursor(Qt::ClosedHandCursor);
              }
              else {
                  event->ignore();
                  QGraphicsWidget::mousePressEvent(event);
              }
          }
          
          void Room::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
          {
              if (event->button() == Qt::LeftButton) {
                  setCursor(Qt::OpenHandCursor);
              }
              else {
                  event->ignore();
                  QGraphicsWidget::mouseReleaseEvent(event);
              }
          }
          

          how is the correct way use ignore or forward to the parent?

          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #5

            Don't call both.

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            0
            • S Offline
              S Offline
              sandro4912
              wrote on last edited by
              #6

              I also tryed to call only one but same behaviour.

              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #7

                Can you provide a minimal compilable example that shows that behaviour ?

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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

                  @sandro4912 said in setCursor Confusion:

                  QGraphicsWidget::mouseReleaseEvent(event);

                  Sorry for the delay. Here is the minimal example. If you click in the rectangle with right or left it should toggle hand cursor or cross. However if hand cursor was active the cross gets never enabled again.

                  #ifndef ROOM_H
                  #define ROOM_H
                  
                  #include <QGraphicsWidget>
                  
                  class Room : public QGraphicsWidget
                  {
                      Q_OBJECT
                  public:
                      explicit Room(QGraphicsItem *parent = nullptr);
                  
                      QRectF boundingRect() const override;
                  
                      void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                                 QWidget *widget) override;
                  
                  protected:
                      void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
                      void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
                  
                  };
                  
                  #endif // ROOM_H
                  
                  #include "room.h"
                  
                  #include <QGraphicsSceneMouseEvent>
                  #include <QPainter>
                  #include <QCursor>
                  
                  Room::Room(QGraphicsItem *parent)
                      :QGraphicsWidget{ parent }
                  {
                      resize(boundingRect().size());
                  }
                  
                  QRectF Room::boundingRect() const
                  {
                      return QRectF{QPointF{0, 0}, QPointF{100, 100}};
                  }
                  
                  void Room::paint(QPainter *painter,
                                   const QStyleOptionGraphicsItem *option, QWidget *widget)
                  {
                      painter->drawRect(QRectF{ QPointF{0, 0}, QPointF{100, 100}});
                  }
                  
                  void Room::mousePressEvent(QGraphicsSceneMouseEvent *event)
                  {
                      if (event->button() == Qt::MouseButton::LeftButton) {
                          setCursor(Qt::ClosedHandCursor);
                      }
                      else {
                          event->ignore();
                          //QGraphicsWidget::mousePressEvent(event);
                      }
                  }
                  
                  void Room::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
                  {
                      if (event->button() == Qt::LeftButton) {
                          setCursor(Qt::OpenHandCursor);
                      }
                      else {
                          event->ignore();
                          //QGraphicsWidget::mouseReleaseEvent(event);
                      }
                  }
                  
                  #ifndef DUNGEONVIEW_H
                  #define DUNGEONVIEW_H
                  
                  #include <QGraphicsView>
                  
                  class DungeonView : public QGraphicsView
                  {
                      Q_OBJECT
                  public:
                  
                  
                  protected:
                      void mousePressEvent(QMouseEvent *event) override;
                      void mouseReleaseEvent(QMouseEvent *event) override;
                  };
                  
                  #endif // DUNGEONVIEW_H
                  
                  #include "dungeonview.h"
                  
                  #include <QMouseEvent>
                  
                  void DungeonView::mousePressEvent(QMouseEvent *event)
                  {
                      if (event->button() == Qt::RightButton) {
                          setCursor(Qt::CrossCursor);
                      }
                      else {
                          QGraphicsView::mousePressEvent(event);
                      }
                  }
                  
                  void DungeonView::mouseReleaseEvent(QMouseEvent *event)
                  {
                      if (cursor() == Qt::CrossCursor) {
                           setCursor(Qt::ArrowCursor);
                       }
                       else {
                           QGraphicsView::mouseReleaseEvent(event);
                       }
                  }
                  
                  #ifndef DUNGEON_H
                  #define DUNGEON_H
                  
                  #include <QWidget>
                  
                  class QGraphicsScene;
                  class DungeonView;
                  class Room;
                  
                  class Dungeon : public QWidget
                  {
                      Q_OBJECT
                  public:
                      explicit Dungeon(QWidget *parent = nullptr);
                  
                  private:
                      QGraphicsScene *mGraphicsScene;
                      DungeonView *mDungeonView;
                      Room *mRoom;
                  };
                  
                  #endif // DUNGEON_H
                  
                  #include "dungeon.h"
                  
                  #include "room.h"
                  #include "dungeonview.h"
                  
                  #include <QVBoxLayout>
                  
                  Dungeon::Dungeon(QWidget *parent)
                      :QWidget{ parent },
                        mGraphicsScene{ new QGraphicsScene },
                        mDungeonView{ new DungeonView },
                        mRoom{ new Room }
                  {
                      mRoom->setPos(QPoint{200, 200});
                      mRoom->show();
                  
                      mGraphicsScene->addItem(mRoom);
                  
                      mDungeonView->setScene(mGraphicsScene);
                      auto layout = new QVBoxLayout;
                      layout->addWidget(mDungeonView);
                      setLayout(layout);
                  }
                  
                  #include "dungeon.h"
                  
                  #include <QApplication>
                  
                  int main(int argc, char *argv[])
                  {
                      QApplication app{ argc, argv };
                      Dungeon dungeon;
                      dungeon.show();
                  
                      return QApplication::exec();
                  }
                  
                  1 Reply Last reply
                  0
                  • SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    From the QGraphicsItem::mousePressEvent documentation:

                    The event is QEvent::ignore()d for items that are neither movable nor selectable.
                    

                    You have to make your item at least selectable for mouseReleaseEvent to be called.

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    1 Reply Last reply
                    1
                    • S Offline
                      S Offline
                      sandro4912
                      wrote on last edited by
                      #10

                      @SGaist said in setCursor Confusion:

                      selectable

                      I tryed setFlag(QGraphicsWidget::ItemIsSelectable); in the constructor of Room but it still does not work.

                      1 Reply Last reply
                      0
                      • SGaistS Offline
                        SGaistS Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on last edited by
                        #11

                        What version of Qt are you using ?
                        On what OS ?

                        Works fine on macOS High Sierra with Qt 5.13.1.

                        Interested in AI ? www.idiap.ch
                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                        S 1 Reply Last reply
                        1
                        • A Offline
                          A Offline
                          arkceajin
                          wrote on last edited by arkceajin
                          #12

                          @SGaist
                          I observed a strange behaviour on Windows.

                          1. Right button press on DungeonView shows CrossCursor
                          2. Right button release on DungeonView shows ArrowCursor
                          3. Left button press on DungeonView shows ClosedHandCursor
                          4. Left button release on DungeonView shows OpenHandCursor
                          5. Right button press on DungeonView shows ArrowCursor (expect CrossCursor as step1)
                          1 Reply Last reply
                          0
                          • SGaistS SGaist

                            What version of Qt are you using ?
                            On what OS ?

                            Works fine on macOS High Sierra with Qt 5.13.1.

                            S Offline
                            S Offline
                            sandro4912
                            wrote on last edited by
                            #13

                            @SGaist

                            I use KDE Neon 5.17 with Qt 5.13.2.

                            My behaviour is like this:

                            Right button press on DungeonView shows CrossCursor
                            Right button release on DungeonView shows ArrowCursor
                            Left button press on DungeonView shows ClosedHandCursor
                            Left button release on DungeonView shows OpenHandCursor
                            Now I only can trigger the HandCursors. The CrossCursor never shows up again.

                            I also testet it on Windows 10 which results in the same behaviour.

                            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