在上一篇文章中,主要是从宏观上去探讨Qt中UI的实现方案;这一篇文章,将给出具体的代码。
实现结果:
一、实现思路
上一篇文章讲到,布局工作的特点为“区域划分”、“层层嵌套”,同时整个布局工作中,关键点也在于如何划分区域、如何找到层层嵌套的关系。
在这个例子中,我将划分和嵌套关系组织如下:
1.对于主窗口,被分为了三个部分:左侧category、中间goodsList、右侧Info;
2.对于左侧部分和中间部分,较为简单,直接将Label、TextBrowser等子控件添加入相应的布局管理器后,父控件将该布局管理器设置为其布局就可以实现;
3.对于右侧,从上到下又分为三个部分:label、button群、spinBox群。对于后两个部分,再次使用“控件将含有子控件的布局管理器设为其布局”的方式实现。
二、代码
1.goodsList.h
#ifndef GOODSLIST_H
#define GOODSLIST_H
#include <QMainWindow>
#include <QGroupBox>
#include <QScrollArea>
#include <QListWidget>
#include <QTextBrowser>
#include <QLabel>
#include <QPushButton>
#include <QSpinBox>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGridLayout>
#include <QWidget>
class goodsList : public QMainWindow
{
Q_OBJECT
public:
explicit goodsList(QWidget *parent = 0);
~goodsList();
private:
void createCategory(); //左侧category的布局
void createGoodsList(); //中间goodsList的布局
void createInfo(); //右侧Info的布局
void createWholeLayout(); //主窗口布局
enum {NUMGOODS = 20,NUMBUTTONS = 4};
QGroupBox *categoryGroupBox;
QScrollArea *goodsListScrollArea;
QGroupBox *infoGroupBox;
QListWidget *categoryListWidget;
QTextBrowser *goodsTextBrowser[NUMGOODS];
QLabel *priceLabel;
QPushButton *operationButton[NUMBUTTONS];
QSpinBox *countSpinBox[NUMGOODS];
QWidget *buttonsWidget;
QWidget *countWidget;
};
#endif // GOODSLIST_H
2.goodsList.cpp文件
#include "goodslist.h"
#include "QString"
goodsList::goodsList(QWidget *parent) :
QMainWindow(parent)
{
createCategory();
createGoodsList();
createInfo();
createWholeLayout();
}
void goodsList::createCategory()
{
categoryListWidget = new QListWidget;
categoryListWidget->addItem(tr("分类一"));
categoryListWidget->addItem(tr("分类二"));
categoryListWidget->addItem(tr("分类三"));
QVBoxLayout *categoryLayout = new QVBoxLayout;
categoryLayout->addWidget(categoryListWidget);
categoryGroupBox = new QGroupBox(tr("Category")); //不能直接向GroupBox里添加子控件,只能通过设置布局管理器来间接添加子控件
categoryGroupBox->setLayout(categoryLayout);
}
void goodsList::createGoodsList()
{
goodsListScrollArea = new QScrollArea();
QGridLayout *goodsListLayout = new QGridLayout;
for(int i = 0; i < NUMGOODS; i++)
{
goodsTextBrowser[i] = new QTextBrowser(); //怎么添加文字
goodsListLayout->addWidget(goodsTextBrowser[i],i/3,i%3); //addItem和 addWidget有什么区别
}
goodsListScrollArea->setLayout(goodsListLayout);
}
void goodsList::createInfo()
{
priceLabel = new QLabel(tr("total price:"));
//组装4个button
buttonsWidget = new QWidget;
QGridLayout *buttonsLayout = new QGridLayout;
for(int i = 0; i < NUMBUTTONS; i++)
{
operationButton[i] = new QPushButton(tr("Button %1").arg(i + 1)); //get技能:.arg()的用法
buttonsLayout->addWidget(operationButton[i]);
}
buttonsWidget->setLayout(buttonsLayout);
//组装购买商品信息
countWidget = new QWidget;
QGridLayout *countLayout = new QGridLayout;
for(int i = 0; i < 5; i++)
{
countSpinBox[i] = new QSpinBox;
countLayout->addWidget(countSpinBox[i],i / 2,i%2);
}
countWidget->setLayout(countLayout);
//Info部分的总布局
QVBoxLayout *infoLayout = new QVBoxLayout;
infoLayout->addWidget(priceLabel);
infoLayout->addWidget(buttonsWidget);
infoLayout->addWidget(countWidget);
infoGroupBox = new QGroupBox(tr("Info"));
infoGroupBox->setLayout(infoLayout);
}
//主窗口的布局
void goodsList::createWholeLayout()
{
QHBoxLayout *wholeLayout = new QHBoxLayout;
wholeLayout->addWidget(categoryGroupBox);
wholeLayout->addWidget(goodsListScrollArea);
wholeLayout->addWidget(infoGroupBox);
//设置拉伸因子
wholeLayout->setStretchFactor(categoryGroupBox,1);
wholeLayout->setStretchFactor(goodsListScrollArea,3);
wholeLayout->setStretchFactor(infoGroupBox,2);
//这部分要有,否则主窗口不会有显示
QWidget *widget = new QWidget(this) ;
widget->setLayout(wholeLayout);
this->setCentralWidget(widget);
setWindowTitle(tr("收银点餐系统"));
}
goodsList::~goodsList()
{
}
三、注意点
1.主窗口布局时,需要设置setCentralWidget()
首先,不能直接在对主窗口设置layout,需要在主窗口里面添加一个“主”Widget,并setCentralWidget(); 然后,将所有的东西放在这一个Widget中。
//这部分要有,否则主窗口不会有显示
QWidget *widget = new QWidget(this) ;
widget->setLayout(wholeLayout);
this->setCentralWidget(widget);
setWindowTitle(tr("收银点餐系统"));
参考资料:
Qt自带实例:Basic Layouts Example
Qt入门学习——Qt Creator 中 ui 文件和 Qt 代码关系:http://blog.youkuaiyun.com/tennysonsky/article/details/48030333
QT布局管理器(QVBoxLayout,QHBoxLayout)不同部分比例大小设置方法:
http://blog.youkuaiyun.com/qinpanke/article/details/50952621
主窗口setCentralWidget():
http://yebaoshan.blog.163.com/blog/static/20423116720126267524060/
在QMainWindow添加控件,无法显示问题 :
http://blog.chinaunix.net/uid-25147458-id-3325066.html
拓展(这部分实现并未用到的):
model/view、Delegate: http://bbs.qter.org/forum.php?mod=viewthread&tid=663