[英]QFileDialog: How to select multiple files with touch-screen input?
在使用Qt 4並支持觸摸輸入的應用程序中,我們使用帶有選項QFileDialog :: DontUseNativeDialog和QFileDialog :: ExistingFiles的QFileDialog。 第一個是必需的,因為我們設置了自己的樣式表,但不適用於本機對話框。 第二個是用於選擇多個文件的,這是我們想要做的。
問題在於,由於沒有可用的“ shift”或“ ctrl”鍵,因此無法在QFileDialog中通過觸摸輸入選擇多個文件。 在Windows中,可以通過在項目中添加復選框來解決該問題。 QFileDialog沒有復選框。
我試圖操縱QFileDialog使其顯示項目的復選框,但失敗了。
我嘗試交換基礎QTreeView和QListView使用的QFileSystemModel,但這會中斷模型與對話框之間的信號插槽連接。 我找不到恢復它們的方法,因為它們被深埋在對話框的私有成員中。
目前,我能想到的唯一解決方案是編寫一個全新的對話框,但我想避免這種工作。
謝謝您的幫助。
由於無法將復選框添加到項目視圖中,因此實現了“ hacky”變通方法。 它在對話框中添加了一個額外的可檢查按鈕,用作“ 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
將事件篩選器安裝到項目視圖, TouchFileDialog
中對話框中的相應按鈕時,會將ControlModifier添加到視圖的鼠標事件。
隨意發布其他解決方案,因為這是臨時的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.