簡體   English   中英

QFileDialog:如何通過觸摸屏輸入選擇多個文件?

[英]QFileDialog: How to select multiple files with touch-screen input?

在使用Qt 4並支持觸摸輸入的應用程序中,我們使用帶有選項QFileDialog :: DontUseNativeDialog和QFileDialog :: ExistingFiles的QFileDialog。 第一個是必需的,因為我們設置了自己的樣式表,但不適用於本機對話框。 第二個是用於選擇多個文件的,這是我們想要做的。

問題在於,由於沒有可用的“ shift”或“ ctrl”鍵,因此無法在QFileDialog中通過觸摸輸入選擇多個文件。 在Windows中,可以通過在項目中添加復選框來解決該問題。 QFileDialog沒有復選框。

我試圖操縱Q​​FileDialog使其顯示項目的復選框,但失敗了。

我嘗試交換基礎QTreeView和QListView使用的QFileSystemModel,但這會中斷模型與對話框之間的信號插槽連接。 我找不到恢復它們的方法,因為它們被深埋在對話框的私有成員中。

目前,我能想到的唯一解決方案是編寫一個全新的對話框,但我想避免這種工作。

  • 那么有沒有一種方法可以將復選框添加到QFileDialog模型視圖中?
  • 您是否還有另一個想法可以選擇多個文件?
  • 問題在Qt 5中解決了嗎? 我們還是要更新。

謝謝您的幫助。

由於無法將復選框添加到項目視圖中,因此實現了“ 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM