QTableView to show the content of table item when mouse hover

Viewed 4896

Writing with phone, so the format may be bad.

I have a table with QTableView, there are two columns in the table. The second column contains a very long string which can't be fully shown without resizing. I want to show the string in a rectangle when I hover the mouse on one item, and the rectangle is near the mouse (many software like Eclipse and VS have such function).

I have searched the internet for a while, but still don't know how to program this view feature.

enter image description here enter image description here

2 Answers

Damn. Everybody has to try to do it the hard way, and start subclassing stuff and reinventing stuff that doesn't need it. The answer is already in Displaying tooltips in PyQT for a QTreeView item

The answer, is that in the data() function of yer model, just return something useful when called for 'Qt::ToolTipRole;' after first checking 'index.column()' to make sure it is the right column.

Here's some similar foolishness:

Show tooltips for long entries of your custom model

I'll give them the benefit of a doubt, and assume that Qt used to work that way; but it doesn't now. They have people making this custom event filter; whereas I returned a tooltip for the ToolTipRole for a given column in a model of mine, and the tooltips only showed up for cells in the column that values were returned for. This is simply unnecessary work; it is not needed now; and it wastes time. This wiki entry is very likely, simply out of date.

First to implement the popup you need to know when the mouse enters the region of an item in the table, for this we will use the eventFilter() method and will look for when the QEvent::MouseMove event is used and we will obtain the index through the function indexAt() and the position of the mouse, and compare if this is different from the previous index. And if it happens it will show or hide the popup as needed.

To create the PopUp we use a dialog and insert a QLabel, and use the setWordWrap property to fit the text correctly

#ifndef TABLEVIEW_H
#define TABLEVIEW_H

#include <QDialog>
#include <QEvent>
#include <QLabel>
#include <QMouseEvent>
#include <QTableView>
#include <QVBoxLayout>
#include <QHeaderView>

class TableView: public QTableView{
    Q_OBJECT
    QDialog *popup;
    QLabel *popupLabel;

public:
    TableView(QWidget *parent = Q_NULLPTR):QTableView(parent){
        viewport()->installEventFilter(this);
        setMouseTracking(true);
        popup = new QDialog(this, Qt::Popup | Qt::ToolTip);

        QVBoxLayout *layout = new QVBoxLayout;
        popupLabel = new QLabel(popup);
        popupLabel->setWordWrap(true);
        layout->addWidget(popupLabel);
        popupLabel->setTextFormat(Qt::RichText);
        //popupLabel->setOpenExternalLinks(true);
        popup->setLayout(layout);
        popup->installEventFilter(this);
    }

    bool eventFilter(QObject *watched, QEvent *event){
        if(viewport() == watched){
            if(event->type() == QEvent::MouseMove){
                QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
                QModelIndex index = indexAt(mouseEvent->pos());
                if(index.isValid()){
                    showPopup(index);
                }
                else{
                    popup->hide();
                }
            }
            else if(event->type() == QEvent::Leave){
                popup->hide();
            }
        }
        else if(popup == watched){
            if(event->type() == QEvent::Leave){
                popup->hide();
            }
        }
        return QTableView::eventFilter(watched, event);
    }

private:
    void showPopup (const QModelIndex &index) const {
        if(index.column() == 1){
            QRect r = visualRect(index);
            popup->move(viewport()->mapToGlobal(r.bottomLeft()));
            popup->setFixedSize(100, popup->heightForWidth(100));
            popupLabel->setText(index.data(Qt::DisplayRole).toString());
            popup->adjustSize();
            popup->show();
        }
        else {
            popup->hide();
        }
    }
};

#endif // TABLEVIEW_H

Screenshot:

enter image description here

In the following link you will find an example.

Related