【问题标题】:Update displayed tool tips for elements of QXXXView (QTableView, QTreeView,...) in a model/view scenario在模型/视图场景中更新显示的 QXXXView 元素(QTableView、QTreeView、...)的工具提示
【发布时间】:2017-03-23 13:42:08
【问题描述】:

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

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

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

编辑: 单独使用Qt::ToolTipRole 发出dataChanged 似乎不会更新活动工具提示,这是我的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;
};

【问题讨论】:

  • 您的模型在roles 参数(或空的roles)中是否正确发出dataChanged() 信号和Qt::ToolTipRole?如果没有,请先修复它!
  • 好点,我已经测试了您的建议,但如果我尝试正确,它似乎不会更新/替换活动工具提示(请参阅更新的问题)。顺便说一句,任何QWidget 似乎都一样:调用setToolTip(...) 似乎不会更新活动工具提示(它需要hideText/showText
  • TBH,我怀疑它一旦显示就不太可能改变,但我确实想确定你至少尝试过。感谢您更新问题以显示您所做的事情。

标签: c++ qt qt5


【解决方案1】:

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

我最终重新实现了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);
}

【讨论】:

    【解决方案2】:

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

    QVariant MyModel::data(const QModelIndex &item, int role) const
    {
      if (role == Qt::DisplayRole)
      {
        return "This is view item text";
      }
      else if (role == Qt::ToolTipRole)
      {
        // Here you should decide what to return.
        if (someCondition)
          return "This is the actual tool tip";
        else
          return "Something else";
      }
      return QAbstractItemModel::data(item, role);
    }
    

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

    【讨论】:

    • 感谢您的回答。问题是,当显示工具提示数据并同时更改它时 - 如果用户不移动鼠标,则工具提示不会更新。
    • 是的。那是因为工具提示是静态信息。它应该再次重新打开以显示新状态。
    • 您还需要发出dataChanged(),但可能仍然是视图没有响应。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-28
    • 2017-07-04
    • 1970-01-01
    • 2014-03-30
    • 2018-06-22
    • 1970-01-01
    相关资源
    最近更新 更多