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. [SOLVED] Handle mouse double clicked and mouse single click event
Forum Updated to NodeBB v4.3 + New Features

[SOLVED] Handle mouse double clicked and mouse single click event

Scheduled Pinned Locked Moved General and Desktop
14 Posts 3 Posters 26.4k Views 2 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.
  • SGaistS Offline
    SGaistS Offline
    SGaist
    Lifetime Qt Champion
    wrote on last edited by
    #2

    Hi,

    Can you share your code ?

    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
    • mistralegnaM Offline
      mistralegnaM Offline
      mistralegna
      wrote on last edited by
      #3

      Here is an extracted version of the code, showing the issue I'm encountering.

      I'm compiling in C++11.

      File main.cpp

      #include <QApplication>
      
      #include <QDebug>
      #include <QFileSystemModel>
      
      #include "ListView.hpp"
      
      void viewClicked(const QModelIndex& idx)
      {
          qDebug() << QObject::trUtf8("Item %1 has been clicked.").arg(idx.data().toString());
      }
      
      void viewDoubleClicked(const QModelIndex& idx)
      {
          qDebug() << QObject::trUtf8("Item %1 has been double clicked.").arg(idx.data().toString());
      }
      
      int testWithNoSubclass(int argc, char** argv)
      {
          QApplication app(argc, argv);
      
          QFileSystemModel fileModel;
      
          QListView view;
          view.setWindowTitle(QObject::trUtf8("Test with standard view"));
          view.setEditTriggers(QAbstractItemView::NoEditTriggers);
          view.setModel(&fileModel);
          view.setRootIndex(fileModel.setRootPath(QDir::homePath()));
          view.show();
      
          QObject::connect(&view, &QListView::clicked, &viewClicked);
          QObject::connect(&view, &QListView::doubleClicked, &viewDoubleClicked);
      
          return app.exec();
      }
      
      int testWithSubclass(int argc, char** argv)
      {
          QApplication app(argc, argv);
      
          QFileSystemModel fileModel;
      
          ListView view;
          view.setWindowTitle(QObject::trUtf8("Test with subclassed view"));
          view.setEditTriggers(QAbstractItemView::NoEditTriggers);
          view.setModel(&fileModel);
          view.setRootIndex(fileModel.setRootPath(QDir::homePath()));
          view.show();
      
          return app.exec();
      }
      
      int main(int argc, char** argv)
      {
         testWithNoSubclass(argc, argv);
         testWithSubclass(argc, argv);
      }
      

      FIle ListView.hpp

      #ifndef LISTVIEW_HPP
      #define LISTVIEW_HPP
      
      #include <QDebug>
      
      #include <QAbstractItemModel>
      #include <QListView>
      #include <QMouseEvent>
      
      class ListView : public QListView
      {
          Q_OBJECT
      
      public:
          ListView(QWidget* parent = nullptr) : QListView(parent) {}
      
      protected:
          void mousePressEvent(QMouseEvent* e)
          {
              if ( e == nullptr )
                  return;
      
              QModelIndex idx = QListView::indexAt(e->pos());
      
              if ( not idx.isValid() )
                  return;
      
              qDebug() << QObject::trUtf8("Item %1 has been clicked.").arg(idx.data().toString());
          }
      
          void mouseDoubleClickEvent(QMouseEvent* e)
          {
              if ( e == nullptr )
                  return;
      
              QModelIndex idx = QListView::indexAt(e->pos());
      
              if ( not idx.isValid() )
                  return;
      
              qDebug() << QObject::trUtf8("Item %1 has been double clicked.").arg(idx.data().toString());
          }
      };
      
      #endif // LISTVIEW_HPP
      
      

      I put the code in the header just in order to avoid copying too many files here.

      Thank you a lot !

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

        Since you have re-implemented mousePressEvent and mouseDoubleClickEvent and you don't call the base class implementation, you are breaking the base functionality

        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
        • mistralegnaM Offline
          mistralegnaM Offline
          mistralegna
          wrote on last edited by
          #5

          So, according to you, I should call QListView::mousePressEvent and QListView::mouseDoubleClickEvent in the subclassed class ? In that case, I should call it at the end of the method, should I ?

          I was insipired by the Scribber example, where some protected methods are reimplemented, but base class is not called in this example.

          I try to modify the code today, and see how it will react to single and double click events.

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

            It really depends on what you do in your subclass.

            You can ignore the base class implementation, but in the case of e.g. QAbstractItemView derived classes, the function your reimplemented handles the drag and drop part. So if you want it to work, then you need to call the base class implementation or rewrite the code (you don't want to do that)

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

            mistralegnaM 1 Reply Last reply
            0
            • SGaistS SGaist

              It really depends on what you do in your subclass.

              You can ignore the base class implementation, but in the case of e.g. QAbstractItemView derived classes, the function your reimplemented handles the drag and drop part. So if you want it to work, then you need to call the base class implementation or rewrite the code (you don't want to do that)

              mistralegnaM Offline
              mistralegnaM Offline
              mistralegna
              wrote on last edited by
              #7

              The aim is to distinguish the single click from the double click. I would like to handle those two types of events independently.

              My first message was not clear about how I did it in a first time, i.e. by connecting the signals clicked(QModelIndex) and doubleClicked(QModelIndex) of a QListView to appropriate slots. However, even in this case, the first slot is called on a double click event.

              Sorry for my poor English, that is not at all my native language.

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

                Do you mean you had that problem with unmodified methods ?

                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
                • mistralegnaM Offline
                  mistralegnaM Offline
                  mistralegna
                  wrote on last edited by
                  #9

                  When I connected the clicked(QModelIndex) and doubleClicked(QModelIndex) signals of QListView to the following slots :

                  @mistralegna said:

                  void viewClicked(const QModelIndex& idx)
                  {
                  qDebug() << QObject::trUtf8("Item %1 has been clicked.").arg(idx.data().toString());
                  }

                  void viewDoubleClicked(const QModelIndex& idx)
                  {
                  qDebug() << QObject::trUtf8("Item %1 has been double clicked.").arg(idx.data().toString());
                  }

                  the double click on an item is first calling the first slot.

                  I would like to call only the second slot in case of an item's double click and only the first slot in the case of a single click.

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

                    Does it also happen if you don't modify mousePressEvent ?

                    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
                    • A Offline
                      A Offline
                      alex_malyu
                      wrote on last edited by
                      #11

                      Do you mean you had that problem with unmodified methods ?

                      I believe widget will always receive both single click and double click event.
                      When I needed I have not found reliable way to skip single click event.

                      As far as I can recall the working solution was to start a timer on a single click which in case doubleclick event arrived was destroyed.
                      But most of the time it is better just to change functionality which allows both single click and double click actions to coexist.

                      mistralegnaM 1 Reply Last reply
                      0
                      • A alex_malyu

                        Do you mean you had that problem with unmodified methods ?

                        I believe widget will always receive both single click and double click event.
                        When I needed I have not found reliable way to skip single click event.

                        As far as I can recall the working solution was to start a timer on a single click which in case doubleclick event arrived was destroyed.
                        But most of the time it is better just to change functionality which allows both single click and double click actions to coexist.

                        mistralegnaM Offline
                        mistralegnaM Offline
                        mistralegna
                        wrote on last edited by
                        #12

                        @SGaist My first post showed two different implementations to handle click events. The first is just to connect the signals QAbstractItemView::clicked(const QModelIndex&) and QAbstractItemView::doubleClicked(const QModelIndex&) to respective slots.

                        #include <QApplication>
                        
                        #include <QDebug>
                        #include <QFileSystemModel>
                        #include <QListView>
                        
                        void viewClicked(const QModelIndex& idx)
                        {
                            qDebug() << QObject::trUtf8("Item %1 has been clicked.").arg(idx.data().toString());
                        }
                        
                        void viewDoubleClicked(const QModelIndex& idx)
                        {
                            qDebug() << QObject::trUtf8("Item %1 has been double clicked.").arg(idx.data().toString());
                        }
                        
                        int main(int argc, char** argv)
                        {
                            QApplication app(argc, argv);
                        
                            QFileSystemModel fileModel;
                        
                            QListView view;
                            view.setWindowTitle(QObject::trUtf8("Test with standard view"));
                            view.setEditTriggers(QAbstractItemView::NoEditTriggers);
                            view.setModel(&fileModel);
                            view.setRootIndex(fileModel.setRootPath(QDir::homePath()));
                            view.show();
                        
                            QObject::connect(&view, &QListView::clicked, &viewClicked);
                            QObject::connect(&view, &QListView::doubleClicked, &viewDoubleClicked);
                        
                            return app.exec();
                        }
                        

                        Here, there is no reimplementation at all. I'm just using base functionnalities (at least, I think I am). Unfortunately, when I double click on an item, here is the output:

                        "Item data has been clicked."  // Seems to be the first click handled.
                        "Item data has been double clicked."  // Double click event.
                        "Item data has been clicked." // Seems to be the second click of the double click.
                        

                        This is quite relevant, because the view seems to have handled two single clicks and the double click. But that's not corresponding to what I'd like to have. I thought the view would have blocked the single click event when reacting to a double click.

                        @alex_malyu So, according to you, does it mean that without a timer, we cannot distinguish between a single click and a double click? I'd prefer to make the distinction between those two events without any timer, if possible.

                        Thank you a lot!

                        1 Reply Last reply
                        0
                        • A Offline
                          A Offline
                          alex_malyu
                          wrote on last edited by alex_malyu
                          #13

                          If nothing changed since Qt 4 single click event on the platforms I was working on always arrives before double click event.
                          Lets look at scenario:

                          1. single click occurs:

                          Single click event arrives.
                          If you want to do something on a single click that is only event you will get,
                          So you have to react on it.

                          1. double click occurs:
                          • First single click event arrives.
                          • second double click event arrives

                          You want to ignore single click , but react on second event.

                          Question: How do you know that it was double click and will not react on a single click?

                          I might be missing the obvious , but the only way I found to achieve this was to start the timer when single click arrived at event handler.
                          This timer was stopped at double click event handler.
                          If it was not stopped slot with reaction needed on a single click was executed.

                          As I said solution was not perfect and it was done for Qt 4.
                          But I did not see anything better except implementing behavior when reaction on single click does not have to be avoided on double click.

                          mistralegnaM 1 Reply Last reply
                          0
                          • A alex_malyu

                            If nothing changed since Qt 4 single click event on the platforms I was working on always arrives before double click event.
                            Lets look at scenario:

                            1. single click occurs:

                            Single click event arrives.
                            If you want to do something on a single click that is only event you will get,
                            So you have to react on it.

                            1. double click occurs:
                            • First single click event arrives.
                            • second double click event arrives

                            You want to ignore single click , but react on second event.

                            Question: How do you know that it was double click and will not react on a single click?

                            I might be missing the obvious , but the only way I found to achieve this was to start the timer when single click arrived at event handler.
                            This timer was stopped at double click event handler.
                            If it was not stopped slot with reaction needed on a single click was executed.

                            As I said solution was not perfect and it was done for Qt 4.
                            But I did not see anything better except implementing behavior when reaction on single click does not have to be avoided on double click.

                            mistralegnaM Offline
                            mistralegnaM Offline
                            mistralegna
                            wrote on last edited by
                            #14

                            @alex_malyu Thank you ;-)

                            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