基于Qt的收银点餐系统之UI的改进——QStackedLayout和QScrollArea的使用

待解决问题:
收银点餐系统之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

采用C/S模式,完成一前台(服务器)对多客服端通讯,用Mysql数据库保存信息; 主要技术: 1.采用TCP/IP协议,容器完成服务端与多客户端的链接 服务端: server=new QTcpServer(this);建立端口 server->listen(QHostAddress::Any,PORT);监听端口 connect(server,SIGNAL(newConnection()),this,SLOT(accpetConnection()));等待用户链接 QTcpSocket* temp = server->nextPendingConnection();建立链接 client.push_back(temp);用户压栈 connect(temp,SIGNAL(readyRead()),this,SLOT(readData()));当端口有数据就读 读数据时先用迭代器遍历容器找到发送信息的客户端,再解析数据并响应 客户端: client=new QTcpSocket(this);建立端口 client->connectToHost(IP,PORT);链接主机 connect(client,SIGNAL(readyRead()),this,SLOT(readData()));端口有数据就读 2.界面布局 服务器 a.主菜单,预订,开台,换台,电子账单功能项采用QToolButton文字置于图片下面,水平布局 b.当前餐台信息与总餐台状态信息用QLabel垂直布局放于主窗体左侧 c.餐台信息采用QGraphicsView+QGraphicsScene+QGraphicsItem布局,view与item需要重写自己的类,Item包括图片与文本信息;将Item放入墙纸scene中,墙纸scene贴到墙view上完成显示。 客户端 a.选择桌号与人数用QLabel,对应的下拉选项用QComboBox,确认,呼叫与结账功能用QToolButton,这些控件水平布局放置于窗体最上方 b.左侧用QTabWidget其中加入特价菜单与我的菜单两个子窗体 c.中间为QGraphicsView+QGraphicsScene+QGraphicsItem布局,布局菜单图片与价格名称,菜单信息服务器发送至客户端与客户端的图片匹配起来。 d.右侧为菜单类型分类按键,采用垂直布局 3.信号与槽机制的运用 a.预订,开台,换台功能的实现:点击对应的按钮触发clicked()信号,与之对应的槽函数中QToolButton *btn = (QToolButton *)sender();区分信号源,弹出对应的子窗体让用户输入相应信息,按确定按钮修改SQL对应Table内容然后发送输入信息信号,主窗体接受到信号调用槽函数(相应窗体成员调用其布局函数重布局)重新布局整个界面(餐台信息与左侧总餐台状态同时更新) b.鼠标悬浮于餐台信息Item时图片放大:改写了QGraphicsSceneMouseEvent事件实现 c.主菜单与电子账单的显示采用QSqlTableModel+QTableView加载整个SQL中相应的Table显示Table内容
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值