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.2k 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.
  • M Offline
    M Offline
    mistralegna
    wrote on 29 May 2015, 11:31 last edited by mistralegna 6 Aug 2015, 11:44
    #1

    Hello,

    I would like to handle in a list view mouse single click and mouse double click events. So I reimplemented two slots connected to the corresponding signals of the QListView. However, when a I perform a double click, the single click is called. I also tried to reimplement the corresponding protected methods (to mousePress and mouseDoubleClick events) in subclasses of QListView, but the same issue occurs.

    Do you have some idea to avoid this behavior ?

    Thanks a lot !

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 29 May 2015, 21:54 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
      • M Offline
        M Offline
        mistralegna
        wrote on 30 May 2015, 10:27 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
        • S Offline
          S Offline
          SGaist
          Lifetime Qt Champion
          wrote on 30 May 2015, 22:18 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
          • M Offline
            M Offline
            mistralegna
            wrote on 31 May 2015, 08:47 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
            • S Offline
              S Offline
              SGaist
              Lifetime Qt Champion
              wrote on 31 May 2015, 21:23 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

              M 1 Reply Last reply 1 Jun 2015, 06:06
              0
              • S SGaist
                31 May 2015, 21:23

                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)

                M Offline
                M Offline
                mistralegna
                wrote on 1 Jun 2015, 06:06 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
                • S Offline
                  S Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on 1 Jun 2015, 22:56 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
                  • M Offline
                    M Offline
                    mistralegna
                    wrote on 2 Jun 2015, 13:03 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
                    • S Offline
                      S Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on 2 Jun 2015, 23:06 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 2 Jun 2015, 23:38 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.

                        M 1 Reply Last reply 3 Jun 2015, 13:49
                        0
                        • A alex_malyu
                          2 Jun 2015, 23:38

                          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.

                          M Offline
                          M Offline
                          mistralegna
                          wrote on 3 Jun 2015, 13:49 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 4 Jun 2015, 00:10 last edited by alex_malyu 6 Apr 2015, 00:14
                            #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.

                            M 1 Reply Last reply 8 Jun 2015, 11:43
                            0
                            • A alex_malyu
                              4 Jun 2015, 00:10

                              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.

                              M Offline
                              M Offline
                              mistralegna
                              wrote on 8 Jun 2015, 11:43 last edited by
                              #14

                              @alex_malyu Thank you ;-)

                              1 Reply Last reply
                              0

                              1/14

                              29 May 2015, 11:31

                              • Login

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