在模型/视图场景中更新QXXXView(QTableView,QTreeView,...)元素的显示工具提示

时间:2017-03-23 13:42:08

标签: c++ qt qt5

我想更新model/view scenario视图小部件的活动工具提示。通过使用data角色调用模型的Qt::ToolTipRole来确定工具提示。

但是,由于数据更改,我找不到更新显示的/ 活动工具提示的任何解决方案。例如,场景是一些基于时间的工具提示或图像工具提示,在图像加载时带有预览。

我花了一些时间研究解决方案,我想分享上述问题的可能答案。

修改 单独使用dataChanged发送Qt::ToolTipRole似乎不会更新有效的工具提示,这是QTableViewModel模型的最小示例(使用Qt5测试):

class MyModel : public QAbstractTableModel
{
    Q_OBJECT
public:
    MyModel(QObject *parent = 0) : QAbstractTableModel(parent), i(0) {
        QTimer * timer = new QTimer(this);
        timer->setInterval(500);
        connect(timer, &QTimer::timeout, this, &MyModel::onNewTime);
        timer->start();
    }
    int rowCount(const QModelIndex &) const { return 1; }
    int columnCount(const QModelIndex &) const { return 1; }
    QVariant data(const QModelIndex &, int role) const {
        switch(role){
        case Qt::DisplayRole:
            return "Hund";
        case Qt::ToolTipRole:
            return i;
        default:
            return QVariant();
        }
    }
private slots:
    void onNewTime() {
        i+=1;
        QModelIndex model = index(0,0);
        emit dataChanged(model, model, QVector<int>()<<Qt::ToolTipRole);
    }
private:
    int i;
};

2 个答案:

答案 0 :(得分:1)

子类的第一个想法,例如,QTableView失败,因为eventFilter(...) event(...)helpEvent(...)都没有被QEvent::ToolTip - 事件调用。< / p>

我最终重新实施viewportEvent(...)以抓住QEvent::ToolTip事件。此外,我必须确保移动鼠标后不会更新工具提示弹出窗口。

这是我的解决方案。它将基本上关闭并重新打开数据更改的工具提示。要在工具提示运行时更新工具提示,只需致电或连接到插槽showOrUpdateToolTip即可。首先是QTableView的子类化:

class TableViewToolTipModifier : public QTableView
{
    Q_OBJECT
public:
    TableViewToolTipModifier(QWidget *parent=0);
public slots:
    void showOrUpdateToolTip();
protected:
    bool viewportEvent(QEvent *event);
    void mouseMoveEvent(QMouseEvent *);
private:
    QPoint _lastPosition;
    bool _isActive = false;
};

实施:

TableViewToolTipModifier::TableViewToolTipModifier(QWidget* parent)
    : QTableView(parent)
{
    this->setMouseTracking(true);
}

void TableViewToolTipModifier::showOrUpdateToolTip()
{
    if (QTableView::underMouse() && _isActive)
    {
        const QModelIndex index = QTableView::indexAt(
                                       this->mapFromGlobal(_lastPosition));
        if (index.isValid())
        {
            const QString toolTip = index.data(Qt::ToolTipRole).toString();
            QToolTip::showText(_lastPosition, toolTip, this, QRect());
        }
    }
}

void TableViewToolTipModifier::mouseMoveEvent(QMouseEvent * event)
{
    _isActive = false;
     QToolTip::hideText();

     QTableView::mouseMoveEvent(event);
}

bool TableViewToolTipModifier::viewportEvent(QEvent *event)
{
    if (event->type() == QEvent::ToolTip)
    {
        _lastPosition = static_cast<QHelpEvent*>(event)->globalPos();
        _isActive = true;
        showOrUpdateToolTip();
        return true;
    }
    return QTableView::viewportEvent(event);
}

答案 1 :(得分:1)

如果使用模型/视图方法,您唯一需要做的就是在模型的data()函数中编写适当的代码,即[ 2, "my title" ], [ 3, "my title 2" ] 。代码应如下所示:

QAbstactItemModel::data()

因此,您的模型必须返回实际的工具提示文本。