待解决问题:
在收银点餐系统之UI的基本实现中,我们实现了本系统中最基本的UI。这一个UI是静态的,不能够动态添加按钮(关于如何添加见参考资料);也不能实现点击不同的分类,出现不同的界面等。前者的逻辑通过代码很好实现,故不赘述;后者则需要用到一个布局管理器——QStackedLayout。
本文将在UI基本实现的基础上,添加两个新的功能:
1.实现点击不同的分类标签,能够切换到不同的界面;
2.在中间的展示部分,添加滚动条。
一、实现后的UI展示
二、代码
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>
#include <QStackedLayout>
class goodsList : public QMainWindow
{
Q_OBJECT
public:
explicit goodsList(QWidget *parent = 0);
~goodsList();
private:
void createCategoryAndGoodslist(); //左侧category的布局
void createInfo(); //右侧Info的布局
void createWholeLayout(); //主窗口布局
//在中间goodsList区域创建可滑动区域
QScrollArea* create_area(int);
enum {NUMGOODS = 20,NUMBUTTONS = 4};
QGroupBox *categoryGroupBox;
QGroupBox *infoGroupBox;
QStackedLayout *goodsDisplayLayout; //存放三个QScrollArea,并实现与存放在categoryListWidget的分类标签关联
QListWidget *categoryListWidget;
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)
{
createCategoryAndGoodslist();
// createGoodsList();
createInfo();
createWholeLayout();
}
void goodsList::createCategoryAndGoodslist()
{
//准备左侧category
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);
//准备中间goodsList并把三个widget添加入stackedLayout中
goodsDisplayLayout = new QStackedLayout();
for(int i = 0; i < 3;i++){
QScrollArea *area = create_area(i);
goodsDisplayLayout->addWidget(area);
}
//将category和goodsList关联起来
connect(categoryListWidget,SIGNAL(currentRowChanged(int)),goodsDisplayLayout,SLOT(setCurrentIndex(int)));
categoryListWidget->setCurrentRow(0);
}
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));
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->addLayout(goodsDisplayLayout);
wholeLayout->addWidget(infoGroupBox);
//设置拉伸因子
wholeLayout->setStretchFactor(categoryGroupBox,1);
wholeLayout->setStretchFactor(goodsDisplayLayout,3);
wholeLayout->setStretchFactor(infoGroupBox,2);
//这部分要有,否则主窗口不会有显示
QWidget *widget = new QWidget(this) ;
widget->setLayout(wholeLayout);
this->setCentralWidget(widget);
setWindowTitle(tr("收银点餐系统"));
}
QScrollArea* goodsList::create_area(int index){
int NUM = 50;
//布局管理器的准备:将button放入gridLayout中
QGridLayout *layout = new QGridLayout();
for(int i = 0; i < NUM; i++){
QPushButton *pb = new QPushButton(QString::number(index+1));
layout->addWidget(pb,i/4,i%4);
}
// //直接将layout放在scrollArea中——不会出现滚动条
// QScrollArea *area = new QScrollArea();
// area->setLayout(layout);
//scrollArea里面放一个widget,将layout放在widget里面——出现滚动条
QWidget *wg = new QWidget();
wg->setLayout(layout);
QScrollArea *area = new QScrollArea();
area->setWidget(wg);
return area;
}
goodsList::~goodsList()
{
}
三、代码中的注意点
1.如何使分类标签与滚动面板一一对应起来?
connect(categoryListWidget,SIGNAL(currentRowChanged(int)),goodsDisplayLayout,SLOT(setCurrentIndex(int)));
2.QScrollArea的使用
// //直接将layout放在scrollArea中——不会出现滚动条
// QScrollArea *area = new QScrollArea();
// area->setLayout(layout);
//scrollArea里面放一个widget,将layout放在widget里面——出现滚动条
QWidget *wg = new QWidget();
wg->setLayout(layout);
QScrollArea *area = new QScrollArea();
area->setWidget(wg);
对于第二种方式可以用下图理解:
3.关于QStackedLayout和QStackedWidget(?)
在首次开发的时候,使用QStackedLayout,在点击非按钮之外的区域,会报错;使用QStackedWidget则不会。而运行上面贴出的代码(QStackedLayout),并没有出现这样的问题。待解决。
参考资料:
Qt之QStackedLayout:http://www.mamicode.com/info-detail-1373381.html
拓展用Qt Designer实现:
QStackedWidget界面的操作步骤:https://jingyan.baidu.com/article/ed15cb1b71c1051be369819b.html
浅谈控件提升之stacked Widget: http://blog.csdn.net/li235456789/article/details/50790042
Qt窗口控件的动态添加和删除:http://blog.csdn.net/u013399898/article/details/51811970