在Qt - 選擇資料夾或特定的檔案的例子中,當使用者選擇檔案或資料夾後,會將其完整路徑放到QLineEdit裡面~
但是,若路徑過長,並不會調整整個視窗的大小,讓使用都可以完整的看到其路徑。
若要調整其視窗大小,必需要調整Layout的相關關係~~
在Qt裡面,若有受到Layout的控制的話,裡面的元件的大小會受到以下兩個因素影響
1. Qt Layout的限制
QLayout::SetDefaultConstraint
最小尺吋設定為minimumSize ()
QLayout::SetFixedSize
視窗為sizeHint (),且不能被改變大小。
QLayout::SetMinimumSize
視窗被設定為minimumSize ()且不能被變的更小
QLayout::SetMaximumSize
視窗被設定為maximumSize ()且不能被變的更大
QLayout::SetMinAndMaxSize
最小尺吋為minimumSize ()、最大尺吋是maximumSize ()
QLayout::SetNoConstraint
不受到Layout的控制
2. 子視窗本身也受到自己的size policies及其最大/最小值的影響
QSizePolicy::Fixed
sizeHint () - sizeHint ()
QSizePolicy::Minimum
sizeHint () - 無限大
QSizePolicy::Maximum
0 - sizeHint ()
QSizePolicy::Preferred
0 - 無限大
QSizePolicy::Expanding
0 - 無限大
QSizePolicy::MinimumExpanding
sizeHint () - 無限大
QSizePolicy::Ignored
0 - 無限大
以下就是由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 ();
void ChangeSelectFile (bool);
void AdjustMainWindowSize (const QString &);
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 <QSizePolicy>
#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);
//
// Set the width of QLineEdit from sizeHint () to max
//
myLineEdit->setSizePolicy (QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
//
// 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 main window to the sizeHint () and can not be changed
//
layout->setSizeConstraint (QLayout::SetFixedSize);
// layout->setSizeConstraint (QLayout::SetMinimumSize);
//
// 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)));
//
// When the content of QLineEdit changed, try to resize the Main Window
//
connect (myLineEdit, SIGNAL (textChanged (const QString &)), this, SLOT (AdjustMainWindowSize (const QString &)));
}
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 ();
// do nothing
} else {
myLineEdit->setText (TargetItem);
}
}
void MyWidget::ChangeSelectFile (bool checked) {
SelectFile = checked;
}
void MyWidget::AdjustMainWindowSize (const QString & text) {
QFont myFont;
QFontMetrics fm (myFont);
//
// Calculate the width pixel by the number of word
//
myLineEdit->setMinimumWidth (fm.width (myLineEdit->text ()));
//
// Readjust the main window size by new MinimumWidth
//
// resize (sizeHint ());
}
這裡有一些部分要特別注意~
myLineEdit->setSizePolicy (QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
設定QLineEdit自身的尺寸策略(size policies)
寬度是sizeHint () ~ 無窮大
高度是限制在sizeHint ()
layout->setSizeConstraint (QLayout::SetFixedSize);
設定主視窗的Layout的長寬為sizeHint (),且不能被改變~
myLineEdit->setMinimumWidth (fm.width (myLineEdit->text ()));
這裡是根據QLineEdit所輸入的內容來決定QLineEdit的最小寬度是多少,
另外,要注意的是,用text ().size ()是回傳有幾個字元,但是,setMinimumWidth是要輸入要幾個pixel,因此,必需由目前使用的字型來決定幾個字元需要多少個pixel。
本程式會把使用者輸入的字串長度轉成pixel,並且設定為QLineEdit的最小長度。
當最小長度大於原本的sizeHint的時候,sizeHint就會被重新設定為MinimumWidth的寬度。
而layout則是根據sizeHint來調整MyWidget的小大~
因此,QLineEdit的寬度會保持在
QLineEdit::sizeHint() ~ fm.width (myLineEdit->text ())
在還沒有輸入任何資料前的樣子
在選擇完檔案或資料夾時,主視窗會自動變大~
在經過這個sample code後,若某一個元件是有被Layout來管理的話,要調整他的大小,沒有辦法直接設定他的大小,必需
1. 設定Layout的policy
2. 設定Widget本身的policy,其最大、最小的寬度
那麼Qt layout manager就可以跟據這一些資料來調整Widget最適合的大小。
參考資料:
QFontMetrics Class Reference
Measuring text width in Qt
QBoxLayout與QWidget之間的關係