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] QLineEdit --> QListView and event filter not catching mouse events
Qt 6.11 is out! See what's new in the release blog

[SOLVED] QLineEdit --> QListView and event filter not catching mouse events

Scheduled Pinned Locked Moved General and Desktop
13 Posts 3 Posters 9.6k 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.
  • I Offline
    I Offline
    i92guboj
    wrote on last edited by
    #1

    Hello.

    I have a line edit widget, and a QListView which acts as a completer for the former. I want to control from the first how the later behaves, in a way that, let's say, single click will select, and, then, if you click the same element again, it will be set as the text for the QLineEdit.

    If I understand that correctly, for that, I have to install an event filter in the QLineEdit, so that it will handle the events received by the QListView, and then define the eventFilter() method also in the QLineEdit().

    So far so good. I did so, and the eventFilter() is being triggered, but it doesn't get any mouse related events when I click the items in QListView.

    @bool CompleteLineEdit::eventFilter(QObject *object, QEvent *event)
    {
    qDebug() << Q_FUNC_INFO;
    if(event->type() == QEvent::MouseButtonPress)
    {
    qDebug() << Q_FUNC_INFO << "Mouse";
    QMouseEvent me = static_cast<QMouseEvent>(event);

        if (!listView->isHidden())
        {
            int button = me->button();
            //QModelIndex currentIndex = listView->currentIndex();
    
            if (Qt::LeftButton == button)
            {
                qDebug() << Q_FUNC_INFO << "left";
                QModelIndex new_index = listView->indexAt(me->pos());
                if(new_index.row() == previousIndex)
                {
                    listView->hide();
                    QString text = listView->currentIndex().data().toString();
                    setText(text);
                }
                else
                {
                    qDebug() << Q_FUNC_INFO << "los índices son distintos";
                    listView->setCurrentIndex(new_index);
                    previousIndex = new_index.row();
                }
            }
            return true;
        }
        else
        {
            listView->show();
            return QLineEdit::eventFilter(object, event);
        }
    }
    else if(event->type() == QEvent::MouseMove)
    {
        qDebug() << Q_FUNC_INFO << "mouse is moving";
        return true;
    }
    else
        return QLineEdit::eventFilter(object, event);
    

    }@

    In qdebug I get a lot of

    @virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*)
    virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*)
    virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*)
    virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*)
    virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*)
    virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*)
    virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*)
    virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*)
    virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) @

    But no other qDebug line ever runs. Is there a chance that something else is filtering these events out or something? Or am I doing something wrong in that code?

    Thanks you for any help :)

    1 Reply Last reply
    0
    • N Offline
      N Offline
      NicuPopescu
      wrote on last edited by
      #2

      Hi,

      how have you installed the filter and what type of events do you get? I suppose mostly are paint events ... print out event->type()

      1 Reply Last reply
      0
      • I Offline
        I Offline
        i92guboj
        wrote on last edited by
        #3

        [quote author="NicuPopescu" date="1382104701"]Hi,

        how have you installed the filter and what type of events do you get? I suppose mostly are paint events ... print out event->type() [/quote]

        I have a class that inherits from QLineEdit, that's the one I was talking about above. I install the event filter in the constructor for that class.

        @CompleteLineEdit::CompleteLineEdit(/QStringList words/QSqlQueryModel *m, QWidget *parent)
        : QLineEdit(parent), m(m) {

        widget = new QWidget;
        QHBoxLayout *hbox = new QHBoxLayout;
        widget->setLayout(hbox);
        
        listView = new QListView;
        photo = new QLabel;
        model = new QStringListModel;
        listView->setModel(model);
        
        hbox->setMargin(0);
        hbox->addWidget(listView);
        hbox->addWidget(photo);
        hbox->setSpacing(0);
        
        photo->setVisible(false);
        photo->setMinimumWidth(0);
        photo->setStyleSheet("border: 2px solid black;");
        
        widget->setWindowFlags(Qt::ToolTip|Qt::WindowStaysOnTopHint);
        
        listView->installEventFilter(this);
        
        previousIndex = -1;
        
        connect(listView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
                this, SLOT(onSelectionChanged(QItemSelection)));
        connect(this, SIGNAL(textChanged(const QString &)), this, SLOT(setCompleter(const QString &)));
        

        // connect(listView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(completeText(const QModelIndex &)));
        }@

        One thing to note is that the completer is a QWidget that contains the two things: a QListView and a QLabel. This QListView is the one whose events I am trying to fetch from my QLineEdit derivative.

        I hope it's a bit clearer now.

        About the type of events I am getting, I have tried to print them, but that gives me little info because they are just integers. I guess I'll have to check some qt header to get the meaning for those so that's what I'll do next.

        @virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) We are in
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) 75
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) We are in
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) 70
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) We are in
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) 70
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) We are in
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) 70
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) We are in
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) 69
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) We are in
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) 69
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) We are in
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) 69
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) We are in
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) 26
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) We are in
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) 13
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) We are in
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) 14
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) We are in
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) 17
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) We are in
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) 67
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) We are in
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) 74
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) We are in
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) 43
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) We are in
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) 76
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) We are in
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) 1
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) We are in
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) 12
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) We are in
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) 10
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) We are in
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) 11
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) We are in
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) 10
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) We are in
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) 11
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) We are in
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) 10
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) We are in
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) 11
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) We are in
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) 10
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) We are in
        virtual bool CompleteLineEdit::eventFilter(QObject*, QEvent*) 18 @

        1 Reply Last reply
        0
        • I Offline
          I Offline
          i92guboj
          wrote on last edited by
          #4

          Oh, for what it's worth, if I click a QListView line, a '1' is printed.

          I tried hard-coding that value (just for testing purposes, of course), but then lots and lots of '1' are printed, and the eventFilter() doesn't work either.

          I don't know what that can mean.

          Also, as you can see, I disabled a connection that I have to the clicked() signal in the list view, so that it doesn't interfere...

          ps.

          This is stranger and stranger. According to /usr/include/qt4/QtCore/qcoreevent.h, '1' is a Timer event. That would make sense if it wasn't because it's not always ticking... mmm... maybe some other eventFilter is catching this (and MouseButtonPress) before they arrive there?

          1 Reply Last reply
          0
          • N Offline
            N Offline
            NicuPopescu
            wrote on last edited by
            #5

            I think your CompleteLineEdit widget and listView lay in different window-children hierarchy

            @widget = new QWidget;@

            it seems this with parent=0 becomes a window as doc says and has its own children ... anyway among the event type codes there are and related to the mouse, Enter, Leave etc.

            try to put list view and completer in the same main window

            1 Reply Last reply
            0
            • I Offline
              I Offline
              i92guboj
              wrote on last edited by
              #6

              First thing first, thanks you so much for all your help.

              However I have no idea how to do that hehe. This QLineEdit is an edit delegate for a column of a QTableView, so, the QLineEdit lies in there.

              The QWidget enclosing a QListView and a QLabel opens as a popup with the Qt::Tooltip hint which as I understand it is what allows the whole thing to "fly" over the main window.

              As you say, I get events when I traverse the borders in and out. I am also getting the click event in the QLineEdit, but not in the QListView inside my QWidget.

              Maybe I should redo the whole thing in a way that QWidget does not wrap the widget that instantiates QWidget, in first place. I don't know if that can be a problem... I did it that way just because this originally was a QListView. There wasn't a photo to the right side, and hence QWidget wasn't needed to wrap it all together.

              Well, I have some things to try now hehe, again, thank you :)

              1 Reply Last reply
              0
              • I Offline
                I Offline
                i92guboj
                wrote on last edited by
                #7

                I really can't tell you why, but doing "this":http://www.qtcentre.org/threads/20151-QTextEdit-not-receiving-MouseButtonDblClick-or-MouseButtonPress?p=98976#post98976 made the whole thing work as it was intended, without a single modification in the rest of the code.

                1 Reply Last reply
                0
                • N Offline
                  N Offline
                  NicuPopescu
                  wrote on last edited by
                  #8

                  good to know!

                  at the moment I only have this clue:

                  bq. bool QAbstractItemView::viewportEvent ( QEvent * event ) [virtual protected]
                  Reimplemented from QAbstractScrollArea::viewportEvent().
                  This function is used to handle tool tips, and What's This? mode, if the given event is a QEvent::ToolTip,or a QEvent::WhatsThis. It passes all other events on to its base class viewportEvent() handler.

                  it looks a little weird :)

                  1 Reply Last reply
                  0
                  • I Offline
                    I Offline
                    i92guboj
                    wrote on last edited by
                    #9

                    So it's my tooltip hint which cause the havoc. As I understand it, in that case, the event is not passed from the intended place, but from the parent object (which is below and out of the mouse focus, of course). Well, thanks for the hint, now at least I know that what was happening has its logic and is not some kind of random behavior on qt's side.

                    Thank you :)

                    1 Reply Last reply
                    0
                    • I Offline
                      I Offline
                      i92guboj
                      wrote on last edited by
                      #10

                      I don't know if anyone is still listening here, but it turned out that this doesn't work in Windows. Ideas are welcome. I'll post back if I find something.

                      1 Reply Last reply
                      0
                      • I Offline
                        I Offline
                        i92guboj
                        wrote on last edited by
                        #11

                        Right, I managed to solve this by just using listView->viewport()->grabMouse() after show()'ing the widget. Note that, unless you enjoy paralysis, you must be careful enough to also use listView->viewport()->releaseMouse() when hiding it, otherwise you'll need to kill the program by using the keyboard, which in some OSes is more difficult that in some others :)

                        1 Reply Last reply
                        0
                        • I Offline
                          I Offline
                          i92guboj
                          wrote on last edited by
                          #12

                          This is going to be bitting me for longer that I was expecting :P

                          I just discovered that this whole mess has rendered my scrollbar useless. It doesn't seem to get any event at all. I can still scroll using the wheel over the listview, or with the keyboard, though. Still, it's a pain. :(

                          1 Reply Last reply
                          0
                          • B Offline
                            B Offline
                            bmedina
                            wrote on last edited by
                            #13

                            I just ran into the same problem: I install an event filter on a QListView, but it never receives mouse-related events. This is using Qt 5.2 on Windows.

                            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