2017-03-23 41 views
2

我想更新model/view scenario的視圖窗口小部件的活動工具提示。該工具提示是通過調用dataQt::ToolTipRole角色來確定的。在模型/視圖場景中更新QXXXView(QTableView,QTreeView,...)元素的顯示工具提示

但是,由於數據更改,我沒有找到任何解決方案來更新顯示的/ 活動的工具提示。例如,場景是一些基於時間的工具提示或圖像工具提示,並在加載圖像時進行預覽。

我經歷了一段時間的研究解決方案,我想分享一個可能的答案以上問題。

編輯: 發射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; 
}; 
+0

你的模型在'roles'參數(或一個空的'roles')中是否用'Qt :: ToolTipRole'正確地發出'dataChanged()'信號?如果沒有,請先解決! –

+0

好點,我測試了你的建議,但它似乎沒有更新/替換活動的工具提示,如果我已經正確嘗試(請參閱更新的問題)。順便說一句,對於任何'QWidget'似乎都適用:調用'setToolTip(...)'似乎不會更新活動的工具提示(它需要'hideText' /'showText') – DomTomCat

+1

TBH,我懷疑一旦顯示就不可能改變,但我確實希望確保你至少可以嘗試。感謝您更新問題以顯示您所做的事情。 –

回答

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); 
} 
1

如果您使用的模型/視圖接近你需要做的是寫在模型中的數據相應的代碼的唯一的事()函數,即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); 
} 

因此,您的模型必須返回實際的工具提示文本。

+0

感謝您的回答。問題是,當顯示工具提示數據並且正在更改時 - 無需用戶移動鼠標,工具提示就不會更新。 – DomTomCat

+0

是的。這是因爲工具提示是一個靜態信息。它應該重新打開以顯示新的狀態。 – vahancho

+0

您還需要發出'dataChanged()',但它可能仍然是視圖不響應。 –