[英]Limit amount of files user can select in QFileDialog
這里的代碼:
dialog = new QFileDialog(this);
dialog->setFileMode(QFileDialog::ExistingFiles);
connect(dialog, SIGNAL(currentChanged(const QString&)),
this, SLOT(dialogSelectionChanged(const QString&)));
void MainWindow::dialogSelectionChanged(const QString& file)
{
QStringList selected = dialog->selectedFiles();
}
問題是
fileSelected(const QString&)
和filesSelected(const QStringList&)
。currentChanged(const QString&)
只傳遞新選擇的文件selectedFiles()
在這種情況下返回我在上一步中選擇的文件。 對話框在發出currentChanged(const QString&)
后可能會更新文件。這就是為什么我不知道如何跟蹤當前選擇的文件。 另一個問題是,如果用戶超出允許選擇的限制,我目前不知道如何取消選擇最后選擇的文件。
我見過幾個例子,人們使用QProxyModel
或QFileDialog
的自定義實現來實現自定義功能,但我不確定什么最適合我的需求。
沒有辦法,但是一旦您的客戶完成選擇,您就可以通過調用方法selectedFiles來驗證操作
QStringList 的大小是否大於您的約束,您可以中止操作並顯示一些錯誤消息。
喜歡
void MainWindow::dialogSelectionChanged(const QString& file)
{
QStringList selected = dialog->selectedFiles();
if(selected.size()>LIMIT)
{
showErrorMsg("some helpful mesage");
}
}
如果您願意接受無恥的黑客攻擊,則可以這樣做:-)
假設以下代碼...
QFileDialog fd;
使用fd.findChildren<QListView *>()
檢查fd
表明它有兩個子代,它們要么是 QListView 要么繼承自QListView
...
(其中 Qsidebar 是 Qt 私有的)。
假設名為listView
的QListView
是感興趣的小部件,您可以將回調連接到其選擇 model ...
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();
}
我只是簡單地測試了上面的代碼,但它似乎以所需的方式運行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.