Search code examples
c++qtqt5qt-signalsqlistview

Slot for QListView::doubleClicked not getting called


I have a QListView named listView. It is the only widget in the MainWindow. I want to track the double clicks on the listView. So, I did this:

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    listView = new QListView(this);

    this->setCentralWidget(listView);

    connect(listView, &QListView::doubleClicked, this, &MainWindow::onDoubleClicked);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow :: onDoubleClicked(const QModelIndex &index)
{
    QMessageBox :: information(this, "Info", "List view was double clicked at\nColumn: " + QString :: number(index.column()) + " and Row: " + QString::number(index.row()));
}

But when I double click the listView a get no message box


Solution

  • If the docs are reviewed:

    void QAbstractItemView::doubleClicked(const QModelIndex &index)

    This signal is emitted when a mouse button is double-clicked. The item the mouse was double-clicked on is specified by index. The signal is only emitted when the index is valid.

    In your case, your QListView does not have a model, so when you click there is no valid QModelIndex, so the signal will not be emitted.

    If you want to follow the double-click event there are 2 possible solutions:

    • Create a QListView and overwrite the mouseDoubleClickEvent event.
    • Or use an event filter.

    In my solution I will use the second method:

    *.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    
    class QListView;
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
        bool eventFilter(QObject *watched, QEvent *event);
    
    private:
        Ui::MainWindow *ui;
        QListView *listView;
    };
    
    
    #endif // MAINWINDOW_H
    

    *.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    #include <QEvent>
    #include <QListView>
    #include <QMouseEvent>
    
    #include <QDebug>
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        listView = new QListView;
        this->setCentralWidget(listView);
    
        listView->viewport()->installEventFilter(this);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    bool MainWindow::eventFilter(QObject *watched, QEvent *event)
    {
        if(watched == listView->viewport() && event->type() == QEvent::MouseButtonDblClick){
            QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
            qDebug()<<"MouseButtonDblClick"<<mouseEvent->pos();
        }
        return QMainWindow::eventFilter(watched, event);
    }