在Qt Designer中使用会比代码中方便,但是代码中的布局会比较灵活。使用Qt布局类的一个重要原因是:他可以确保窗体能够自动适应不同的字体、语言、和系统平台。
主要类有QHBoxLayout、QVBoxLayout、QGridLayout和QStackLayout。可执行布局管理的类还有QSplitterr、QScrollArea、QMainWindow和QMidArea。
一、在窗口中摆放窗口部件
绝对位置法、人工布局法、布局管理器法。
绝对位置法:
FindFileDialog::FindFileDialog(QWidget *parent)
: QDialog(parent)
{
namedLabel->setGeometry(9, 9, 50, 25);
namedLineEdit->setGeometry(65, 9, 200, 25);
lookInLabel->setGeometry(9, 40, 50, 25);
lookInLineEdit->setGeometry(65, 40, 200, 25);
subfoldersCheckBox->setGeometry(9, 71, 256, 23);
tableWidget->setGeometry(9, 100, 256, 100);
messageLabel->setGeometry(9, 206, 256, 25);
findButton->setGeometry(271, 9, 85, 32);
stopButton->setGeometry(271, 47, 85, 32);
closeButton->setGeometry(271, 84, 85, 32);
helpButton->setGeometry(271, 199, 85, 32);
setWindowTitle(tr("Find Files or Folders"));
setFixedSize(365, 240);
}
像这种的直接设置控件的固定位置,缺点有很多,用户无法改变窗口的大小、容易出现文本截断现象、可能跨平台的时候布局出错、必须认为计算位置,否则极不好看。人工布局法:
尽管人工布局还是要放置绝对位置,但是可以设定和整个窗口的大小比例,币完全手写代码好很多哦。
FindFileDialog::FindFileDialog(QWidget *parent)
: QDialog(parent)
{
namedLabel = new QLabel(tr("&Named:"), this);
namedLineEdit = new QLineEdit(this);
namedLabel->setBuddy(namedLineEdit);
lookInLabel = new QLabel(tr("&Look in:"), this);
lookInLineEdit = new QLineEdit(this);
lookInLabel->setBuddy(lookInLineEdit);
subfoldersCheckBox = new QCheckBox(tr("Include subfolders"), this);
QStringList labels;
labels << tr("Name") << tr("In Folder") << tr("Size")
<< tr("Modified");
tableWidget = new QTableWidget(this);
tableWidget->setColumnCount(4);
tableWidget->setHorizontalHeaderLabels(labels);
messageLabel = new QLabel(tr("0 files found"), this);
messageLabel->setFrameShape(QLabel::Panel);
messageLabel->setFrameShadow(QLabel::Sunken);
findButton = new QPushButton(tr("&Find"), this);
stopButton = new QPushButton(tr("Stop"), this);
closeButton = new QPushButton(tr("Close"), this);
helpButton = new QPushButton(tr("Help"), this);
connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
setWindowTitle(tr("Find Files or Folders"));
setMinimumSize(265, 190);
resize(365, 240);
}
void FindFileDialog::resizeEvent(QResizeEvent * /* event */)
{
int extraWidth = width() - minimumWidth();
int extraHeight = height() - minimumHeight();
namedLabel->setGeometry(9, 9, 50, 25);
namedLineEdit->setGeometry(65, 9, 100 + extraWidth, 25);
lookInLabel->setGeometry(9, 40, 50, 25);
lookInLineEdit->setGeometry(65, 40, 100 + extraWidth, 25);
subfoldersCheckBox->setGeometry(9, 71, 156 + extraWidth, 23);
tableWidget->setGeometry(9, 100, 156 + extraWidth,
50 + extraHeight);
messageLabel->setGeometry(9, 156 + extraHeight, 156 + extraWidth,
25);
findButton->setGeometry(171 + extraWidth, 9, 85, 32);
stopButton->setGeometry(171 + extraWidth, 47, 85, 32);
closeButton->setGeometry(171 + extraWidth, 84, 85, 32);
helpButton->setGeometry(171 + extraWidth, 149 + extraHeight, 85,
32);
}在resizeEvent()在处理器中,将多余的空间留给了哪些希望变长或者变高的窗口部件。
即使这样也存在需要编写大量代码和出现文本截断现象。
布局管理器法:
最方便的方法就是使用布局管理器,布局管理器会充分考虑控件尺寸,也会自动改变空间大小以适应不同情况。
给出一个使用实例:
布局和效果如图:
findfiledialog.h
#include <QtGui>
#include "findfiledialog.h"
FindFileDialog::FindFileDialog(QWidget *parent)
: QDialog(parent)
{
namedLabel = new QLabel(tr("&Named:"));
namedLineEdit = new QLineEdit;
namedLabel->setBuddy(namedLineEdit);
lookInLabel = new QLabel(tr("&Look in:"));
lookInLineEdit = new QLineEdit;
lookInLabel->setBuddy(lookInLineEdit);
subfoldersCheckBox = new QCheckBox(tr("Include subfolders"));
QStringList labels;
labels << tr("Name") << tr("In Folder") << tr("Size")
<< tr("Modified");
tableWidget = new QTableWidget;
tableWidget->setColumnCount(4);
tableWidget->setHorizontalHeaderLabels(labels);
messageLabel = new QLabel(tr("0 files found"));
messageLabel->setFrameShape(QLabel::Panel);
messageLabel->setFrameShadow(QLabel::Sunken);
findButton = new QPushButton(tr("&Find"));
stopButton = new QPushButton(tr("Stop"));
closeButton = new QPushButton(tr("Close"));
helpButton = new QPushButton(tr("Help"));
connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
QGridLayout *leftLayout = new QGridLayout;
leftLayout->addWidget(namedLabel, 0, 0);
leftLayout->addWidget(namedLineEdit, 0, 1);
leftLayout->addWidget(lookInLabel, 1, 0);
leftLayout->addWidget(lookInLineEdit, 1, 1);
leftLayout->addWidget(subfoldersCheckBox, 2, 0, 1, 2);
leftLayout->addWidget(tableWidget, 3, 0, 1, 2);
leftLayout->addWidget(messageLabel, 4, 0, 1, 2);
QVBoxLayout *rightLayout = new QVBoxLayout;
rightLayout->addWidget(findButton);
rightLayout->addWidget(stopButton);
rightLayout->addWidget(closeButton);
rightLayout->addStretch();
rightLayout->addWidget(helpButton);
QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->addLayout(leftLayout);
mainLayout->addLayout(rightLayout);
setLayout(mainLayout);
setWindowTitle(tr("Find Files or Folders"));
}
findfiledialog.cpp
#include <QtGui>
#include "findfiledialog.h"
FindFileDialog::FindFileDialog(QWidget *parent)
: QDialog(parent)
{
namedLabel = new QLabel(tr("&Named:"));
namedLineEdit = new QLineEdit;
namedLabel->setBuddy(namedLineEdit);
lookInLabel = new QLabel(tr("&Look in:"));
lookInLineEdit = new QLineEdit;
lookInLabel->setBuddy(lookInLineEdit);
subfoldersCheckBox = new QCheckBox(tr("Include subfolders"));
QStringList labels;
labels << tr("Name") << tr("In Folder") << tr("Size")
<< tr("Modified");
tableWidget = new QTableWidget;
tableWidget->setColumnCount(4);
tableWidget->setHorizontalHeaderLabels(labels);
messageLabel = new QLabel(tr("0 files found"));
messageLabel->setFrameShape(QLabel::Panel);
messageLabel->setFrameShadow(QLabel::Sunken);
findButton = new QPushButton(tr("&Find"));
stopButton = new QPushButton(tr("Stop"));
closeButton = new QPushButton(tr("Close"));
helpButton = new QPushButton(tr("Help"));
connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
QGridLayout *leftLayout = new QGridLayout;
leftLayout->addWidget(namedLabel, 0, 0);
leftLayout->addWidget(namedLineEdit, 0, 1);
leftLayout->addWidget(lookInLabel, 1, 0);
leftLayout->addWidget(lookInLineEdit, 1, 1);
leftLayout->addWidget(subfoldersCheckBox, 2, 0, 1, 2);
leftLayout->addWidget(tableWidget, 3, 0, 1, 2);
leftLayout->addWidget(messageLabel, 4, 0, 1, 2);
QVBoxLayout *rightLayout = new QVBoxLayout;
rightLayout->addWidget(findButton);
rightLayout->addWidget(stopButton);
rightLayout->addWidget(closeButton);
rightLayout->addStretch();
rightLayout->addWidget(helpButton);
QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->addLayout(leftLayout);
mainLayout->addLayout(rightLayout);
setLayout(mainLayout);
setWindowTitle(tr("Find Files or Folders"));
}
main.cpp
#include <QApplication>
#include "findfiledialog.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
FindFileDialog dialog;
dialog.show();
return app.exec();
}
布局管理器为我们提供很多额外的好处,添加或移除(即使是hide()或者show()也可以)窗口部件,布局都会自动适应这些布局。
一个窗口布局的大小策略(QSizePolicy)会告诉布局系统应该如何对部件进行拉伸或者压缩。
一个QSizePolicy既包含水平分量也包含垂直分量。最常用取值如下:
二、分组布局
QStackedLayout类可以对一组子窗口部件进行摆放,或者对他们进行分页,并且一次显示一个。
这种东西和QTabWidget很像,替换一下也是可以的看你喜欢哪一种了
使用方法就是把你自己的QWidget放在你的QStackedLayout中就可以了;
QWidget *appearancePage;
stackedLayout = new QStackedLayout;
stackedLayout->addWidget(appearancePage);
preferencedialog.h
#ifndef PREFERENCEDIALOG_H
#define PREFERENCEDIALOG_H
#include <QDialog>
#include <QCheckBox>
#include <QDialogButtonBox>
#include <QGroupBox>
#include <QLabel>
#include <QLineEdit>
#include <QListWidget>
#include <QRadioButton>
#include <QStackedLayout>
class PreferenceDialog : public QDialog
{
Q_OBJECT
public:
PreferenceDialog(QWidget *parent = 0);
private:
void createAppearancePage();
void createWebBrowserPage();
void createMailAndNewsPage();
void createAdvancedPage();
QStackedLayout *stackedLayout;
QListWidget *listWidget;
QWidget *appearancePage;
QWidget *webBrowserPage;
QWidget *mailAndNewsPage;
QWidget *advancedPage;
QDialogButtonBox *buttonBox;
QGroupBox *openGroupBox;
QCheckBox *webBrowserCheckBox;
QCheckBox *mailEditorCheckBox;
QCheckBox *newsgroupCheckBox;
QGroupBox *toolbarsGroupBox;
QRadioButton *picturesAndTextRadioButton;
QRadioButton *picturesOnlyRadioButton;
QRadioButton *textOnlyRadioButton;
QCheckBox *tooltipsCheckBox;
QCheckBox *webSiteIconsCheckBox;
QCheckBox *resizeImagesCheckBox;
QGroupBox *displayGroupBox;
QRadioButton *blankRadioButton;
QRadioButton *homeRadioButton;
QRadioButton *lastRadioButton;
QGroupBox *homeGroupBox;
QLabel *locationLabel;
QLineEdit *locationLineEdit;
QGroupBox *webButtonsGroupBox;
QCheckBox *bookmarksCheckBox;
QCheckBox *goCheckBox;
QCheckBox *homeCheckBox;
QCheckBox *searchCheckBox;
QCheckBox *printCheckBox;
QGroupBox *generalGroupBox;
QCheckBox *confirmCheckBox;
QCheckBox *rememberCheckBox;
QGroupBox *mailButtonsGroupBox;
QCheckBox *fileCheckBox;
QCheckBox *nextCheckBox;
QCheckBox *stopCheckBox;
QCheckBox *junkCheckBox;
QGroupBox *featuresGroupBox;
QCheckBox *javaCheckBox;
QCheckBox *ftpCheckBox;
QLineEdit *ftpLineEdit;
};
#endif
preferencedialog.cpp
#include <QtGui>
#include "preferencedialog.h"
PreferenceDialog::PreferenceDialog(QWidget *parent)
: QDialog(parent)
{
createAppearancePage();
createWebBrowserPage();
createMailAndNewsPage();
createAdvancedPage();
buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok
| QDialogButtonBox::Cancel);
listWidget = new QListWidget;
listWidget->addItem(tr("Appearance"));
listWidget->addItem(tr("Web Browser"));
listWidget->addItem(tr("Mail & News"));
listWidget->addItem(tr("Advanced"));
stackedLayout = new QStackedLayout;
stackedLayout->addWidget(appearancePage);
stackedLayout->addWidget(webBrowserPage);
stackedLayout->addWidget(mailAndNewsPage);
stackedLayout->addWidget(advancedPage);
connect(listWidget, SIGNAL(currentRowChanged(int)),
stackedLayout, SLOT(setCurrentIndex(int)));
QGridLayout *mainLayout = new QGridLayout;
mainLayout->setColumnStretch(0, 1);
mainLayout->setColumnStretch(1, 3);
mainLayout->addWidget(listWidget, 0, 0);
mainLayout->addLayout(stackedLayout, 0, 1);
mainLayout->addWidget(buttonBox, 1, 0, 1, 2);
setLayout(mainLayout);
connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
setWindowTitle(tr("Preferences"));
listWidget->setCurrentRow(0);
}
void PreferenceDialog::createAppearancePage()
{
appearancePage = new QWidget;
openGroupBox = new QGroupBox(tr("Open at startup"));
webBrowserCheckBox = new QCheckBox(tr("Web browser"));
mailEditorCheckBox = new QCheckBox(tr("Mail editor"));
newsgroupCheckBox = new QCheckBox(tr("Newsgroups"));
toolbarsGroupBox = new QGroupBox(tr("Show toolbars as"));
picturesAndTextRadioButton = new QRadioButton(tr("Pictures and "
"text"));
picturesOnlyRadioButton = new QRadioButton(tr("Pictures only"));
textOnlyRadioButton = new QRadioButton(tr("Text only"));
tooltipsCheckBox = new QCheckBox(tr("Show tooltips"));
webSiteIconsCheckBox = new QCheckBox(tr("Show web site icons"));
resizeImagesCheckBox = new QCheckBox(tr("Resize large images to "
"fit in the window"));
QVBoxLayout *openLayout = new QVBoxLayout;
openLayout->addWidget(webBrowserCheckBox);
openLayout->addWidget(mailEditorCheckBox);
openLayout->addWidget(newsgroupCheckBox);
openGroupBox->setLayout(openLayout);
QVBoxLayout *toolbarsLayout = new QVBoxLayout;
toolbarsLayout->addWidget(picturesAndTextRadioButton);
toolbarsLayout->addWidget(picturesOnlyRadioButton);
toolbarsLayout->addWidget(textOnlyRadioButton);
toolbarsGroupBox->setLayout(toolbarsLayout);
QVBoxLayout *pageLayout = new QVBoxLayout;
pageLayout->setMargin(0);
pageLayout->addWidget(openGroupBox);
pageLayout->addWidget(toolbarsGroupBox);
pageLayout->addWidget(tooltipsCheckBox);
pageLayout->addWidget(webSiteIconsCheckBox);
pageLayout->addWidget(resizeImagesCheckBox);
pageLayout->addStretch();
appearancePage->setLayout(pageLayout);
webBrowserCheckBox->setChecked(true);
mailEditorCheckBox->setChecked(true);
picturesAndTextRadioButton->setChecked(true);
tooltipsCheckBox->setChecked(true);
webSiteIconsCheckBox->setChecked(true);
}
void PreferenceDialog::createWebBrowserPage()
{
webBrowserPage = new QWidget;
displayGroupBox = new QGroupBox(tr("Display on startup"));
blankRadioButton = new QRadioButton(tr("Blank page"));
homeRadioButton = new QRadioButton(tr("Blank page"));
lastRadioButton = new QRadioButton(tr("Last page visited"));
homeGroupBox = new QGroupBox(tr("Home Page"));
locationLabel = new QLabel(tr("Location:"));
locationLineEdit = new QLineEdit;
webButtonsGroupBox = new QGroupBox(tr("Select the buttons you want "
"in the toolbar"));
bookmarksCheckBox = new QCheckBox(tr("Bookmarks"));
goCheckBox = new QCheckBox(tr("Go"));
homeCheckBox = new QCheckBox(tr("Home"));
searchCheckBox = new QCheckBox(tr("Search"));
printCheckBox = new QCheckBox(tr("Print"));
QVBoxLayout *displayLayout = new QVBoxLayout;
displayLayout->addWidget(blankRadioButton);
displayLayout->addWidget(homeRadioButton);
displayLayout->addWidget(lastRadioButton);
displayGroupBox->setLayout(displayLayout);
QHBoxLayout *homeLayout = new QHBoxLayout;
homeLayout->addWidget(locationLabel);
homeLayout->addWidget(locationLineEdit);
homeGroupBox->setLayout(homeLayout);
QGridLayout *webButtonsLayout = new QGridLayout;
webButtonsLayout->addWidget(bookmarksCheckBox, 0, 0);
webButtonsLayout->addWidget(goCheckBox, 1, 0);
webButtonsLayout->addWidget(homeCheckBox, 2, 0);
webButtonsLayout->addWidget(searchCheckBox, 0, 1);
webButtonsLayout->addWidget(printCheckBox, 1, 1);
webButtonsGroupBox->setLayout(webButtonsLayout);
QVBoxLayout *pageLayout = new QVBoxLayout;
pageLayout->setMargin(0);
pageLayout->addWidget(displayGroupBox);
pageLayout->addWidget(homeGroupBox);
pageLayout->addWidget(webButtonsGroupBox);
pageLayout->addStretch();
webBrowserPage->setLayout(pageLayout);
homeRadioButton->setChecked(true);
locationLineEdit->setText("http://www.trolltech.com/");
bookmarksCheckBox->setChecked(true);
homeCheckBox->setChecked(true);
searchCheckBox->setChecked(true);
printCheckBox->setChecked(true);
}
void PreferenceDialog::createMailAndNewsPage()
{
mailAndNewsPage = new QWidget;
generalGroupBox = new QGroupBox(tr("General settings"));
confirmCheckBox = new QCheckBox(tr("Warn when moving folders to "
"the Trash"));
rememberCheckBox = new QCheckBox(tr("Remember the last selected "
"message"));
mailButtonsGroupBox = new QGroupBox(tr("Select the buttons you "
"want in the toolbar"));
fileCheckBox = new QCheckBox(tr("File"));
nextCheckBox = new QCheckBox(tr("Next"));
stopCheckBox = new QCheckBox(tr("Stop"));
junkCheckBox = new QCheckBox(tr("Junk"));
QVBoxLayout *generalLayout = new QVBoxLayout;
generalLayout->addWidget(confirmCheckBox);
generalLayout->addWidget(rememberCheckBox);
generalGroupBox->setLayout(generalLayout);
QGridLayout *mailButtonsLayout = new QGridLayout;
mailButtonsLayout->addWidget(fileCheckBox, 0, 0);
mailButtonsLayout->addWidget(nextCheckBox, 1, 0);
mailButtonsLayout->addWidget(stopCheckBox, 0, 1);
mailButtonsLayout->addWidget(junkCheckBox, 1, 1);
mailButtonsGroupBox->setLayout(mailButtonsLayout);
QVBoxLayout *pageLayout = new QVBoxLayout;
pageLayout->setMargin(0);
pageLayout->addWidget(generalGroupBox);
pageLayout->addWidget(mailButtonsGroupBox);
pageLayout->addStretch();
mailAndNewsPage->setLayout(pageLayout);
confirmCheckBox->setChecked(true);
rememberCheckBox->setChecked(true);
nextCheckBox->setChecked(true);
junkCheckBox->setChecked(true);
}
void PreferenceDialog::createAdvancedPage()
{
advancedPage = new QWidget;
featuresGroupBox = new QGroupBox(tr("Features that help "
"interpret web pages"));
javaCheckBox = new QCheckBox(tr("Enable Java"));
ftpCheckBox = new QCheckBox(tr("Use this email address for "
"anonymous FTP:"));
ftpLineEdit = new QLineEdit;
connect(ftpCheckBox, SIGNAL(toggled(bool)),
ftpLineEdit, SLOT(setEnabled(bool)));
QGridLayout *featuresLayout = new QGridLayout;
featuresLayout->addWidget(javaCheckBox, 0, 0, 1, 2);
featuresLayout->addWidget(ftpCheckBox, 1, 0, 1, 2);
featuresLayout->addWidget(ftpLineEdit, 2, 1);
featuresGroupBox->setLayout(featuresLayout);
QVBoxLayout *pageLayout = new QVBoxLayout;
pageLayout->setMargin(0);
pageLayout->addWidget(featuresGroupBox);
pageLayout->addStretch();
advancedPage->setLayout(pageLayout);
javaCheckBox->setChecked(true);
ftpLineEdit->setEnabled(false);
}
main.cpp
#include <QApplication>
#include "preferencedialog.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
PreferenceDialog dialog;
dialog.show();
return app.exec();
}
三、切分窗口
QSplitter就是一个可以包含一些其他窗口部件。在切分窗口中的这些窗口部件会通过切分条分隔开,用户可以改变切分窗口的大小,好处就是切分窗口可以作为布局管理器的替代品,用户可以有更多的控制权。
给出一个简单的例子:
main.cpp
#include <QApplication>
#include <QtGui>
#include <QTextEdit>
#include <QSplitter>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QTextEdit *editor1 = new QTextEdit;
QTextEdit *editor2 = new QTextEdit;
QTextEdit *editor3 = new QTextEdit;
QSplitter splitter(Qt::Horizontal);
splitter.addWidget(editor1);
splitter.addWidget(editor2);
splitter.addWidget(editor3);
editor1->setPlainText(QStringLiteral("我是窗口1"));
editor2->setPlainText(QStringLiteral("我是窗口2"));
editor3->setPlainText(QStringLiteral("我是窗口3"));
splitter.setWindowTitle(QObject::tr("Splitter"));
splitter.show();
return app.exec();
}
在自己的QSplitter里面addWidget就行了,QStringLiteral("我是窗口1")是为了解决中文乱码问题。显示效果如下:
再给一个复杂一点的例子,里面有一些QTreeWidget之类的使用方法,也就顺便学一下。
mailclient.h
#ifndef MAILCLIENT_H
#define MAILCLIENT_H
#include <QMainWindow>
#include <QIcon>
#include <QSplitter>
#include <QTextEdit>
#include <QTreeWidget>
#include <QMenuBar>
#include <QStatusBar>
class MailClient : public QMainWindow
{
Q_OBJECT
public:
MailClient();
protected:
void closeEvent(QCloseEvent *event);
private:
void addFolder(const QIcon &icon, const QString &name);
void addMessage(const QString &subject, const QString &from,
const QString &date);
void readSettings();
void writeSettings();
QSplitter *mainSplitter;
QSplitter *rightSplitter;
QTreeWidget *foldersTreeWidget;
QTreeWidget *messagesTreeWidget;
QTextEdit *textEdit;
};
#endif
mailclient.cpp
#include <QtGui>
#include "mailclient.h"
MailClient::MailClient()
{
QIcon folderIcon(style()->standardPixmap(QStyle::SP_DirClosedIcon));
QIcon trashIcon(style()->standardPixmap(QStyle::SP_FileIcon));
QStringList folderLabels;
folderLabels << tr("Folders");
foldersTreeWidget = new QTreeWidget;
foldersTreeWidget->setHeaderLabels(folderLabels);
addFolder(folderIcon, tr("Inbox"));
addFolder(folderIcon, tr("Outbox"));
addFolder(folderIcon, tr("Sent"));
addFolder(trashIcon, tr("Trash"));
QStringList messageLabels;
messageLabels << tr("Subject") << tr("Sender") << tr("Date");
messagesTreeWidget = new QTreeWidget;
messagesTreeWidget->setHeaderLabels(messageLabels);
addMessage(tr("Happy New Year!"),
tr("Grace K. <grace@software-inc.com>"),
tr("2006-12-31"));
addMessage(tr("Radically new concept!"),
tr("Grace K. <grace@software-inc.com>"),
tr("2006-12-22"));
addMessage(tr("Accounts"),
tr("pascale@nospam.com"),
tr("2006-12-31"));
addMessage(tr("Expenses"),
tr("Joe Bloggs <joe@bloggs.com>"),
tr("2006-12-25"));
addMessage(tr("Re: Expenses"),
tr("Andy <andy@nospam.com>"),
tr("2007-01-02"));
addMessage(tr("Re: Accounts"),
tr("Joe Bloggs <joe@bloggs.com>"),
tr("2007-01-03"));
addMessage(tr("Re: Accounts"),
tr("Andy <andy@nospam.com>"),
tr("2007-01-03"));
messagesTreeWidget->resizeColumnToContents(0);
messagesTreeWidget->resizeColumnToContents(1);
textEdit = new QTextEdit;
textEdit->setReadOnly(true);
textEdit->setHtml("<table bolder=0>"
"<tr><td align=right><b>Subject:</b>"
"<td><p>Happy New Year!"
"<tr><td align=right><b>Date:</b>"
"<td><p>Sun, 31 Dec 2006"
"<tr><td align=right><b>From:</b>"
"<td><p>Grace K. <grace@software-inc.com>"
"<tr><td align=right><b>To:</b>"
"<td>all@software-inc.com"
"</table>"
"<br>I want to seize this occasion to thank "
"everybody for the year that has gone, and want "
"to wish you the best for next year. It has been "
"a pleasure to work with you all on the Hawk "
"project, and I'm sure we'll get concrete "
"results shortly."
"<br><br>Happy New Year!"
"<br>--Grace");
menuBar()->addMenu(tr("&File"));
menuBar()->addMenu(tr("&Edit"));
menuBar()->addMenu(tr("&View"));
menuBar()->addMenu(tr("F&older"));
menuBar()->addMenu(tr("&Message"));
menuBar()->addMenu(tr("&Settings"));
menuBar()->addMenu(tr("&Help"));
statusBar()->showMessage(tr("No new messages on server"));
rightSplitter = new QSplitter(Qt::Vertical);
rightSplitter->addWidget(messagesTreeWidget);
rightSplitter->addWidget(textEdit);
rightSplitter->setStretchFactor(1, 1);
mainSplitter = new QSplitter(Qt::Horizontal);
mainSplitter->addWidget(foldersTreeWidget);
mainSplitter->addWidget(rightSplitter);
mainSplitter->setStretchFactor(1, 1);
setCentralWidget(mainSplitter);
setWindowTitle(tr("Mail Client"));
readSettings();
}
void MailClient::closeEvent(QCloseEvent *event)
{
writeSettings();
event->accept();
}
void MailClient::addFolder(const QIcon &icon, const QString &name)
{
QTreeWidgetItem *root;
if (foldersTreeWidget->topLevelItemCount() == 0) {
root = new QTreeWidgetItem(foldersTreeWidget);
root->setText(0, tr("Mail"));
foldersTreeWidget->setItemExpanded(root, true);
} else {
root = foldersTreeWidget->topLevelItem(0);
}
QTreeWidgetItem *newItem = new QTreeWidgetItem(root);
newItem->setText(0, name);
newItem->setIcon(0, icon);
if (!foldersTreeWidget->currentItem())
foldersTreeWidget->setCurrentItem(newItem);
}
void MailClient::addMessage(const QString &subject, const QString &from,
const QString &date)
{
QTreeWidgetItem *newItem = new QTreeWidgetItem(messagesTreeWidget);
newItem->setText(0, subject);
newItem->setText(1, from);
newItem->setText(2, date);
if (!messagesTreeWidget->currentItem())
messagesTreeWidget->setCurrentItem(newItem);
}
void MailClient::readSettings()
{
QSettings settings("Software Inc.", "Mail Client");
settings.beginGroup("mainWindow");
restoreGeometry(settings.value("geometry").toByteArray());
mainSplitter->restoreState(
settings.value("mainSplitter").toByteArray());
rightSplitter->restoreState(
settings.value("rightSplitter").toByteArray());
settings.endGroup();
}
void MailClient::writeSettings()
{
QSettings settings("Software Inc.", "Mail Client");
settings.beginGroup("mainWindow");
settings.setValue("geometry", saveGeometry());
settings.setValue("mainSplitter", mainSplitter->saveState());
settings.setValue("rightSplitter", rightSplitter->saveState());
settings.endGroup();
}
#include <QApplication>
#include "mailclient.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MailClient client;
client.show();
return app.exec();
}
四、滚动区域
QScrollArea类提供了一个可以滚动的视口和两个滚动条。这个比我们通过初始化QScrollBar滚动条然后再实现功能要简单得多。
QScrollArea使用方法就是对需要的设置滚动的窗口setWidget(),类把这个窗口自动重定义为该视口的父对象。
类的构建如下:
代码如下:(利用之前实现过的IconEditor类)
链接:http://blog.csdn.net/hellozex/article/details/78315327
#include <QApplication>
#include <QHBoxLayout>
#include <QScrollArea>
#include "iconeditor.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
IconEditor *iconEditor = new IconEditor;
iconEditor->setWindowTitle(QObject::tr("Icon Editor"));
iconEditor->setIconImage(QImage("mouse.png"));
QScrollArea scrollArea;
scrollArea.setWidget(iconEditor);
scrollArea.viewport()->setBackgroundRole(QPalette::Light);
scrollArea.viewport()->setAutoFillBackground(true);
scrollArea.setWindowTitle(QObject::tr("Icon Editor"));
scrollArea.show();
return app.exec();
}修改main函数。这里遇到个问题:
如果不是new IconEditor出来,而是直接 IconEditor iconEditor;在手动关闭窗口时会出现中断,初步估计是在它析构函数中出可问题。还未解决诶,可能用new会比较好吧。
scrollArea.setWidget(iconEditor);使用方法就是把需要的添加滚动的窗口加到你的QScrollArea上即可,再设置相关属性就OK啦。
默认情况是窗口小于view时才会显示滚动条,也可以设置总是可见。
scrollArea.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
scrollArea.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
五、停靠窗口和工具栏
停靠窗口(dock window)是指一些可以停靠在QMainWindow中或是浮动为独立窗口的窗口。
QMainWindow具有四个停靠位置,知道win10的靠边停靠功能吧,例如把你的某窗口拖到某一边边上,鼠标触碰到电脑显示器边界就会被靠边布局了。
Qt各个停靠窗口都是QDockWidget的实例。
早期Qt版本工具栏的停靠和窗口停靠一样,并且共享统一停靠区域。但是Qt4开始就独自占用停靠区域了,如果需要一个浮动工具栏,把他放进QDockWidget就行了。
QMainWindow窗口部件构成如下:
停靠区四个角可以设置成为相邻停靠区的一部分:
QMainWindow::setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea);
就是把左上角的停靠区设置为左停靠区。
本文详细介绍了Qt中的布局管理,包括QHBoxLayout、QVBoxLayout、QGridLayout等布局类的使用,以及QSplitter、QScrollArea等组件的应用。通过布局管理器,可以实现窗口部件的自动适应和灵活摆放,同时提供了分组布局、切分窗口和滚动区域的实现示例。
337

被折叠的 条评论
为什么被折叠?



