如果您愿意接受无耻的黑客攻击,可以这样做:-)
假设以下代码...
QFileDialog fd;
使用fd.findChildren<QListView *>() 检查fd 发现它有两个子代,要么是QListView,要么继承自QListView...
- QListView 命名为 listView
- QSidebar 命名为侧边栏
(其中 Qsidebar 是 Qt 私有的)。
假设名为listView 的QListView 是您感兴趣的小部件,您可以将回调连接到其选择模型...
QFileDialog fd;
for (const auto &i: fd.findChildren<QListView *>("listView")) {
auto *sm = i->selectionModel();
QObject::connect(sm, &QItemSelectionModel::selectionChanged,
[sm](const QItemSelection &selected, const QItemSelection &deselected)
{
/*
* Here we pass a hard-coded max selected items
* value of 5 to the real callback/slot.
*/
handle_selection_updated(5, sm, selected, deselected);
});
}
这里handle_selection_updated有如下定义...
void handle_selection_updated (int selection_max, QItemSelectionModel *sm,
const QItemSelection &selected,
const QItemSelection &deselected)
{
/*
* We need to remember the last valid selection. The following
* is declared static in this simple case but would generally be
* a class member in `real' code.
*/
static QItemSelection last_selected;
/*
* Because we update the selection model `sm' from within this
* slot this function will recurse which will cause problems if
* we don't detect it and take appropriate action.
*/
static bool recursing = false;
if (recursing)
return;
/*
* If the number of rows selected is greater than the value
* specified by `selection_max' then revert to the last valid
* selection as specified by `last_selected'.
*/
if (sm->selectedRows().size() > selection_max) {
/*
* The following call to QItemSelectionModel::clearSelection
* will result in a recursive call to this function. Set
* `recursing' to true to catch this and avoid associated
* problems.
*/
recursing = true;
/*
* Now clear the selection and reset it to the items from
* `last_selected'.
*/
sm->clearSelection();
for (const auto &i: last_selected.indexes()) {
sm->select(i, QItemSelectionModel::Select);
}
recursing = false;
}
/*
* Update `last_selected'.
*/
last_selected = sm->selection();
}
我只是简单地测试了上面的代码,但它的行为似乎符合要求。