在我们使用Qt 4并支持触摸输入的应用程序中,我们使用QFileDialog和QFileDialog :: DontUseNativeDialog和QFileDialog :: ExistingFiles选项。 第一个是需要的,因为我们设置了自己的样式表,但这不适用于本机对话框。第二个是选择多个文件所需的,这是我们想要做的。
问题是在QFileDialog中无法选择带触摸输入的多个文件,因为我们没有“shift”或“ctrl”-key可用。在Windows中,通过向项添加复选框来解决问题。 QFileDialog没有复选框。
我试图操纵QFileDialog以显示项目的复选框,但我失败了。
我尝试交换底层QTreeView和QListView使用的QFileSystemModel,但这会破坏模型和对话框之间的信号槽连接。我无法找到恢复它们的方法,因为它们深埋在对话框的私人空间中。
此时我能想象的唯一解决方案是编写一个全新的对话框,但我想避免这种努力。
感谢您的帮助。
答案 0 :(得分:0)
由于我没有在项目视图中添加复选框,因此我实施了一个" hacky"变通。它为对话框添加了一个额外的可检查按钮,用作" ctrl" -key。选中该按钮后,可以选择多个文件。解决方案有点难看,因为它依赖于了解对话框的内部,但它完成了工作。
所以这是标题的代码......
// 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添加到视图的鼠标事件中。
随意发布其他解决方案,因为这有点即兴。