我使用的是Qt 5.6.1。QTableWidget有多个表,理论上它们代表一个表--它们位置很近,行上的数据是相互连接的,但它们应该作为单独的widget呈现。它们的选择标志是SelectList,ExtendedSelection mod。**我如何为它们进行通用选择?**假设您选择了第一个表中的几行,并在其他表中选择了相同的行。所选内容应相应地删除。表具有不同的列数。
我尝试用这种方式处理selectionModel表中的selectionChanged
信号:
void wSpisokActive::selectionChangedMain(const QItemSelection &selected, const QItemSelection &deselected)
{
permission_to_changed_main_ = false; // flag to exit a similar slot in another table
if (permission_to_changed_monitoring_) { // select row
QModelIndexList selected_list = selected.indexes();
for (QModelIndex model_index: selected_list) {
ui->tbMonitoring->selectRow(model_index.row());
}
QModelIndexList deselected_list = deselected.indexes();
int last_row = -1;
for (QModelIndex model_index: deselected_list) { // deselect row
if (last_row == model_index.row()) continue;
last_row = model_index.row();
for (int i = 0; i < ui->tbMonitoring->columnCount(); ++i) {
ui->tbMonitoring->selectionModel()->select(ui->tbMonitoring->model()->index(last_row, i), QItemSelectionModel::Deselect);
}
}
}
permission_to_changed_main_ = true;
}
字符串
但是这样通过Ctrl键的选择处理不正确。而且,当选择几行时,只有最后一行被高亮显示-我试着在选择行之前设置ui->tbMonitoring->setSelectionMode(QAbstractItemView::MultiSelection);
,然后设置ui->tbMonitoring->setSelectionMode(QAbstractItemView::ExtendedSelection);
。但是它没有帮助。
1条答案
按热度按时间x0fgdtte1#
正如这个帮助页面所解释的(我的重点):
视图中所选项目的相关信息存储在QItemSelectionModel类的示例中。这将维护单个模型中项目的模型索引,并且独立于任何视图。由于模型上可能有许多视图,因此可以在视图之间共享选择,从而允许应用程序以一致的方式显示多个视图。
您感兴趣的方法成对出现:
model
/setModel(QAbstractItemModel*)
selectionModel()
/setSelectionModel(QItemSelectionModel*)
对于最后一个,请花一分钟仔细阅读文档中的内容,即:
请注意,如果在此函数之后调用setModel(),则给定的selectionModel将被视图创建的selectionModel替换。
如果不再需要旧的选择模型,则由应用程序来删除[...]
生成的代码看起来像这样(假设这是在你的主线程上):
字符串
**编辑:**关于QTBUG-49966,@musicamante在评论中指出。
开门见山:是,每个视图有一个选择模型(更确切地说,视图的头视图有一个选择模型)将保留在内存中,直到视图沿着它的头一起被删除。
然而,如果你只做我上面提到的事情,那么每个视图只有一个选择模型“泄漏”(这应该是一个非常小的数字),当你删除视图时,它会被删除。
如果你正在实现一个
setModel
被调用任意次数的窗口(例如,请参阅@musicamante在评论中描述的场景),你可以做几件事作为缓解措施:如果你确保小部件被删除(确保在关闭窗口时清除所有内容的最简单方法是调用
myWindow->setAttribute(Qt::WA_DeleteOnClose);
),这些未使用的选择模型将不会比你的视图更持久。mySelectionModel->setParent(nullptr);
。只要所有的选择模型都有一个视图作为它们的父视图,它们就会和视图一起被删除。
您必须确保每个视图调用
setModel()
不超过一次:以
QSqlTableModel
为例:修改加载的SQL表应该不通过创建一个新模型来替换现有模型来完成。相反,请执行以下操作:型
QIdentityProxyModel
进行更改。代理模型的目的不应该是这个,但它在这里派上了用场。模型可以在视图上更改(至少,这是它在视觉上的样子),而无需调用
setModel
。它是通过执行以下操作启动的:
型
然后,可以将新模型附加到视图中:
型
瞧!不再在同一视图上多次调用
setModel
。在一个相关的说明中,如果我可以做一个快速的(可选的)建议:
QListView
,QTableView
,QTreeView
,而不是QxxxxxWidget
。虽然
QTableWidget
是初学者的首选类,简化了许多必要的工作,但它对灵活性的限制远远超过了优点。QStandardItemModel
(注意QxxxxxWidget
类都使用自己的内部独立模型)。如果您的应用程序已经有一些内部结构来存储屏幕上显示的数据,通常将其Map到
QAbstractItemModel
的自定义子类中比将其复制到QStandardItemModel
等独立模型中更有效。您越早习惯于创建自己的模型类,您的生活就越容易。
在你的例子中,你正在使用表,你可以从
QAbstractTableModel
开始你的学习之旅。它应该是一个足够容易访问的起点,一般来说,与QAbstractItemModel
相比,它更容易子类化。