2011年10月21日 星期五

Qt - 選擇資料夾或特定的檔案

目前打算做一個小程式,可以讓使用選擇特定的檔案或資料夾

main.cpp

#include <QApplication>
#include "MyWidget.h"

int main (
int argc,
char *argv[]
)
{
QApplication app (argc, argv);

MyWidget myWidget;

myWidget.show ();

return app.exec ();
}


MyWidget.h
#ifndef _MY_WIDGET_H_
#define _MY_WIDGET_H_

#include <QWidget>

class QLabel;
class QPushButton;
class QLineEdit;

class MyWidget : public QWidget {
Q_OBJECT

public:
MyWidget (QWidget *parent = 0);

private slots:
void browse ();

private:
QLabel *myLabel;
QPushButton *myPushButton;
QLineEdit *myLineEdit;
};

#endif //#ifndef _MY_WIDGET_H_


MyWidget.cpp
#include <QLabel>
#include <QPushButton>
#include <QLineEdit>
#include <QVBoxLayout>
#include <QFileDialog>

#include "MyWidget.h"

MyWidget::MyWidget (QWidget *parent) : QWidget (parent) {
// do nothing
myLabel = NULL;
myLineEdit = NULL;
myPushButton = NULL;

myLabel = new QLabel (tr ("Target Name"), this);

myLineEdit = new QLineEdit (this);

myPushButton = new QPushButton (tr ("&Browse..."), this);

connect (myPushButton, SIGNAL (clicked ()), SLOT (browse ()));

QHBoxLayout *layout = new QHBoxLayout (this);
layout->addWidget (myLabel);
layout->addWidget (myLineEdit);
layout->addWidget (myPushButton);

this->setLayout (layout);
}

void MyWidget::browse () {
// QString directory = QFileDialog::getExistingDirectory (this, tr ("Find Files"), QDir::currentPath ());

QFileDialog myFileDialog (this);
QString itemPath = myFileDialog.getOpenFileName (this, tr ("Open File"), QDir::currentPath (), tr ("All C++ files (*.cpp *.h)"));
if (itemPath.isEmpty ()) {
myLineEdit->setText (myFileDialog.directory ().absolutePath ());
} else {
myLineEdit->setText (itemPath);
}
}

結果如下圖所示


本來打算只利用QFileDialog::getOpenFileName ()就可以選擇檔案和資料夾~
就是當使用者沒有選擇檔案的時候,同時按下「開啟」,這樣就會選擇目前視窗的路徑~
但是,沒有選擇檔案的時候,按開啟並不會回傳值。所以,只好讓使用都可以選擇目前要選擇檔案還是資料夾。
sample code如下:
main.cpp
#include <QApplication>
#include "MyWidget.h"

int main (
int argc,
char *argv[]
)
{
QApplication app (argc, argv);

MyWidget myWidget;

myWidget.show ();

return app.exec ();
}

MyWidget.h
#ifndef _MY_WIDGET_H_
#define _MY_WIDGET_H_

#include <QWidget>

class QLabel;
class QPushButton;
class QLineEdit;

class MyWidget : public QWidget {
Q_OBJECT

public:
MyWidget (QWidget *parent = 0);

private slots:
void browse ();
void ChangeSelectFile (bool);

private:
QLabel *myLabel;
QPushButton *myPushButton;
QLineEdit *myLineEdit;
bool SelectFile;
};

#endif //#ifndef _MY_WIDGET_H_

MyWidget.cpp
#include <QLabel>
#include <QPushButton>
#include <QLineEdit>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QFileDialog>
#include <QGroupBox>
#include <QRadioButton>

#include "MyWidget.h"

MyWidget::MyWidget (QWidget *parent) : QWidget (parent) {

//
// init
//

myLabel = NULL;
myLineEdit = NULL;
myPushButton = NULL;

//
// Create Label component
//

myLabel = new QLabel (tr ("Target Name"), this);

//
// Create LineEdit component
//

myLineEdit = new QLineEdit (this);

//
// Create GroupBox and RadioButton component
//

QGroupBox *box = new QGroupBox (tr ("Select Type"));
QRadioButton *radio1 = new QRadioButton (tr ("File"));
QRadioButton *radio2 = new QRadioButton (tr ("Directory"));

//
// Set the default checked RadioButton for SelectFile
//

radio1->setChecked (true);
SelectFile = true;

//
// Set RadioButton into QHBoxLayout
// And set RadioButton into same GroupBox
//

QVBoxLayout *VLayout = new QVBoxLayout;
VLayout->addWidget (radio1);
VLayout->addWidget (radio2);
box->setLayout (VLayout);

//
// Create QPushButton component
//

myPushButton = new QPushButton (tr ("&Browse..."), this);

//
// Add all the components into QHBoxLayout
//

QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget (myLabel);
layout->addWidget (myLineEdit);
layout->addWidget (box);
layout->addWidget (myPushButton);

//
// Set the main Layout for MyWidget
//

this->setLayout (layout);

//
// Set the SIGNAL and SLOT for this component
//

connect (myPushButton, SIGNAL (clicked ()), SLOT (browse ()));
connect (radio1, SIGNAL (toggled (bool)), this, SLOT (ChangeSelectFile (bool)));
}

void MyWidget::browse () {

QString TargetItem;

QFileDialog myFileDialog (this);
if (SelectFile) {
TargetItem = myFileDialog.getOpenFileName (this, tr ("Open File"), QDir::currentPath (), tr ("All C++ files (*.cpp *.h)"));
} else {
TargetItem = myFileDialog.getExistingDirectory (this, tr ("Select Folder"), QDir::currentPath ());
}
if (TargetItem.isEmpty ()) {
// myLineEdit->setText (myFileDialog.directory ().absolutePath ());
// myLineEdit->clear ();
} else {
myLineEdit->setText (TargetItem);
}
}

void MyWidget::ChangeSelectFile (bool checked) {
SelectFile = checked;
}


設定為選擇File:

當按Browse後,會出現以下的視窗,並且選擇一個限定的副檔名的檔案

當按下開啟後,會把選擇的檔案的路徑放在QLineEdit component裡面


另外,若選擇Directory的話,並且選擇Browse,會跳出以下的視窗


當按下確定後,就會把資料夾的路徑放在QLineEdit裡面,如下圖所示


參考資料:
QFileDialog Class Reference
Widgets and Layouts
Qt 第二章 创建对话框--子类化QDialog
QRadioButton Class Reference
QAbstractButton Class Reference
QLineEdit Class Reference

沒有留言: