如何在 QStatusBar 中显示 QAbstractTableModel 的状态?
Posted
技术标签:
【中文标题】如何在 QStatusBar 中显示 QAbstractTableModel 的状态?【英文标题】:How to show QAbstractTableModel's status in a QStatusBar? 【发布时间】:2016-12-12 15:39:50 【问题描述】:我有 QAbstractTableModel 和 QSortFilterProxyModel 的自定义实现,用于过滤。该表显示在 QTableView 中。
我的 QTableView 的父对话框有一个 QStatusBar,带有一个只读的 QLineEdit 小部件。
在我的 QAbstractTableModel 的覆盖 data() 方法中,我正在为 Qt::StatusTipRole 角色设置相关值。
现在我缺少部分管道:如何让每个单元格的 StatusTipRole 数据显示在 QStatusBar 内的小部件中?
【问题讨论】:
假设您希望 QStatusBar 在鼠标单击时更新,您可以将 QTableView 的继承信号clicked
连接到获取文本并相应调用 QStatusBar::setText() 的函数
这个想法是根据鼠标悬停在哪个单元格上来更新状态栏。我已经设法通过为 TableView 的 mouseMoveEvent 信号设置一个插槽来实现此行为,但是在涉及过滤时会失败,并且那时我无法访问模型数据。
This thread 讨论过这个问题。
【参考方案1】:
无需覆盖视图小部件。 Qt 提供内置支持来显示模型中项目的状态提示。
通常,当role
为QStatusTipRole
时,您只需从模型的data()
返回一个QString
,当您将项目悬停时,QString
将显示在状态栏中。
您还需要为QTableView
开启mouse tracking,以便在不按下鼠标按钮的情况下获得状态栏更新。这是因为当鼠标跟踪被禁用时(默认情况下),小部件仅在按下鼠标按钮时接收鼠标移动事件。
现在,为了在您的QLineEdit
而非默认状态栏中显示这些状态提示,您可以覆盖主窗口的event
函数,拦截QStatusTipEvent
s,并在您的QLineEdit
中显示提示。
这是一个示例实现:
#include <QtWidgets>
//model to provide dummy data
class MyModel : public QAbstractTableModel
public:
explicit MyModel(QObject* parent= nullptr):QAbstractTableModel(parent)
~MyModel() = default;
int columnCount(const QModelIndex &parent) const
if(parent.isValid()) return 0;
return 4;
int rowCount(const QModelIndex &parent) const
if(parent.isValid()) return 0;
return 20;
QVariant data(const QModelIndex &index, int role) const
QVariant val;
switch(role)
case Qt::DisplayRole: case Qt::EditRole:
val= QString("Display (%1, %2)")
.arg(index.row(), 2, 10, QChar('0'))
.arg(index.column(), 2, 10, QChar('0'));
break;
case Qt::ToolTipRole:
val= QString("Tooltip (%1, %2)")
.arg(index.row(), 2, 10, QChar('0'))
.arg(index.column(), 2, 10, QChar('0'));
break;
case Qt::StatusTipRole:
val= QString("StatusTip (%1, %2)")
.arg(index.row(), 2, 10, QChar('0'))
.arg(index.column(), 2, 10, QChar('0'));
break;
return val;
;
class MainWindow : public QMainWindow
Q_OBJECT
public:
explicit MainWindow(QWidget* parent= nullptr):QMainWindow(parent)
//set up GUI
layout.addWidget(&lineEditFilter);
layout.addWidget(&tableView);
setCentralWidget(&cw);
lineEditStatusBar.setReadOnly(true);
statusBar()->addPermanentWidget(&lineEditStatusBar);
//set up models
filterModel.setSourceModel(&model);
tableView.setModel(&filterModel);
connect(&lineEditFilter, &QLineEdit::textChanged, this, &MainWindow::updateFilter);
//turn on mouse tracking for the table view
tableView.setMouseTracking(true);
~MainWindow()= default;
Q_SLOT void updateFilter(const QString& text)
filterModel.setFilterFixedString(text);
protected:
//in order to intercept QStatusTipEvents
//and show tips in the line edit instead of the normal status bar
bool event(QEvent *event)
if(event->type() != QEvent::StatusTip) return QMainWindow::event(event);
QStatusTipEvent* statusTipEvent= static_cast<QStatusTipEvent*>(event);
lineEditStatusBar.setText(statusTipEvent->tip());
statusTipEvent->ignore();
return true;
private:
QWidget cw;
QVBoxLayout layout&cw;
QLineEdit lineEditFilter;
QTableView tableView;
MyModel model;
QSortFilterProxyModel filterModel;
QLineEdit lineEditStatusBar;
;
int main(int argc, char *argv[])
QApplication a(argc, argv);
MainWindow mw;
mw.show();
return a.exec();
#include "main.moc"
【讨论】:
感谢您提供详细示例 - 这正是我想要的。在玩弄了您的示例代码之后,我意识到我的主对话框是 QDialog,而不是 QMainWindow。这是我无法控制的,所以我正在监听鼠标事件并手动调用 model->data(),这很不幸。 @jehuty ,您仍然可以对QDialog
子类使用相同的方法。如果我对您的问题的理解正确,here 就是将MainWindow
修改为QDialog
子类后的同一个示例。
"您还需要开启鼠标跟踪..."。谢谢!以上是关于如何在 QStatusBar 中显示 QAbstractTableModel 的状态?的主要内容,如果未能解决你的问题,请参考以下文章