由於我未能在項目視圖中添加複選框,我實現了一個「哈克」解決方案。它在充當「ctrl」鍵的對話框中添加了一個額外的可檢查按鈕。當按鈕被選中時,可以選擇多個文件。這個解決方案有點難以理解,因爲它依賴於瞭解對話框的內部,但它完成了這項工作。
所以這裏是頭的代碼...
// file touchfiledialog.h
/*
Event filter that is used to add a shift modifier to left mouse button events.
This is used as a helper class for the TouchFileDialog
*/
class EventFilterCtrlModifier : public QObject
{
Q_OBJECT;
bool addCtrlModifier;
public:
EventFilterCtrlModifier(QObject* parent);
void setAddCtrlModifier(bool b);
protected:
virtual bool eventFilter(QObject* watched, QEvent* e);
};
/*
TouchDialog adds the possibility to select multiple files with touch input to the QFileDialog.
This is done by adding an extra button which can be used as control key replacement.
*/
class QTOOLS_API TouchFileDialog : public QFileDialog
{
Q_OBJECT
EventFilterCtrlModifier* listViewEventFilter;
EventFilterCtrlModifier* treeViewEventFilter;
bool initialized;
public:
TouchFileDialog(QWidget* parent);
protected:
virtual void showEvent(QShowEvent* e);
private slots:
void activateCtrlModifier(bool b);
private:
void initObjectsForMultipleFileSelection();
};
與實施...
// file touchfiledialog.cpp
#include "touchfiledialog.h"
EventFilterCtrlModifier::EventFilterCtrlModifier(QObject* parent)
: QObject(parent)
, addCtrlModifier(false)
{
}
void EventFilterCtrlModifier::setAddCtrlModifier(bool b)
{
addCtrlModifier = b;
}
bool EventFilterCtrlModifier::eventFilter(QObject* watched, QEvent* e)
{
QEvent::Type type = e->type();
if(type == QEvent::MouseButtonPress || type == QEvent::MouseButtonRelease)
{
if(addCtrlModifier)
{
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(e);
// Create and post a new event with ctrl modifier if the event does not already have one.
if(!mouseEvent->modifiers().testFlag(Qt::ControlModifier))
{
QMouseEvent* newEventWithModifier = new QMouseEvent(
type,
mouseEvent->pos(),
mouseEvent->globalPos(),
mouseEvent->button(),
mouseEvent->buttons(),
mouseEvent->modifiers() | Qt::ControlModifier
);
QCoreApplication::postEvent(watched, newEventWithModifier);
return true; // absorb the original event
}
}
}
return false;
}
//#######################################################################################
TouchFileDialog::TouchFileDialog(QWidget* parent)
: QFileDialog(parent)
, listViewEventFilter(NULL)
, treeViewEventFilter(NULL)
, initialized(false)
{
}
void TouchFileDialog::showEvent(QShowEvent* e)
{
// install objects that are needed for multiple file selection if needed
if(!initialized)
{
if(fileMode() == QFileDialog::ExistingFiles)
{
initObjectsForMultipleFileSelection();
}
initialized = true;
}
QFileDialog::showEvent(e);
}
void TouchFileDialog::initObjectsForMultipleFileSelection()
{
// install event filter to item views that are used to add ctrl modifiers to mouse events
listViewEventFilter = new EventFilterCtrlModifier(this);
QListView* listView = findChild<QListView*>();
listView->viewport()->installEventFilter(listViewEventFilter);
treeViewEventFilter = new EventFilterCtrlModifier(this);
QTreeView* treeView = findChild<QTreeView*>();
treeView->viewport()->installEventFilter(treeViewEventFilter);
QGridLayout* dialogLayout = static_cast<QGridLayout*>(layout()); // Ugly because it makes assumptions about the internals of the QFileDialog
QPushButton* pushButtonSelectMultiple = new QPushButton(this);
pushButtonSelectMultiple->setText(tr("Select multiple"));
pushButtonSelectMultiple->setCheckable(true);
connect(pushButtonSelectMultiple, SIGNAL(toggled(bool)), this, SLOT(activateCtrlModifier(bool)));
dialogLayout->addWidget(pushButtonSelectMultiple, 2, 0);
}
void ZFFileDialog::activateCtrlModifier(bool b)
{
listViewEventFilter->setAddCtrlModifier(b);
treeViewEventFilter->setAddCtrlModifier(b);
}
的TouchFileDialog
安裝一個事件過濾器,以該項目的意見,將增加一個ControlModifier當對話框中的相應按鈕被選中時,將鼠標指向視圖的鼠標事件。
隨意發佈其他解決方案,因爲這有點簡單。
你看過這些嗎? https://wiki.qt.io/QSortFilterProxyModel_subclass_to_add_a_checkbox http://www.qtcentre.org/threads/27253-QFileSystemModel-with-checkboxes – Miki
也許一個好的黑客會在你的QFileDialog中找到QListView/QTreeView(提示:'findChild ')並將其設置爲擴展選擇模式。 – peppe
CheckableProxyModel的鏈接看起來很有前途,因爲它似乎不需要與另一個模型交換模型。另一個鏈接需要實現派生的QFileSystemModel,它將取代視圖中的正常QFileSystemModel。但我試過了,它打破了模型與QFileDialog的QFileDialogPrivate對象之間的信號槽連接,我無法從外部恢復。 – Knitschi