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.
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:
In the following link you will find an example.