Qt实战笔记-从零开始搭建一套库存管理系统-(三)UI框架搭建-02

在上一章节中,我们已经搭建了一个很简陋的框架,这一章节我们继续细化,重点是通过信号与槽函数实现一些动态效果。

1、登录窗口

因为咱们这个软件有登录和注册的功能。所以得单独建一个登录窗口,用户在主窗口点击登录按钮,就会弹出这个子窗口,供用户输入账号密码进行登录。

这里我们可以用一个QDialog类型的控件来创建登录窗口,原型设计如下:

Qt实战笔记-从零开始搭建一套库存管理系统-(三)UI框架搭建-02

QDidalog是一个对话框控件,我们通过继承这个类,来实现这个登录窗口。

点击Qt Creator的文件->新建文件或项目->文件和类->C++ Class,类命名为loginDialog,基本类选择<Custom>,即自定义。

Qt实战笔记-从零开始搭建一套库存管理系统-(三)UI框架搭建-02

新建完成后,点击logindialog.h头文件,编辑如下内容:

#ifndef LOGINDIALOG_H
#define LOGINDIALOG_H

#include <QDialog>


class loginDialog : public QDialog
{
    Q_OBJECT

public:
    loginDialog(QWidget *parent = nullptr);
    ~loginDialog();
};


#endif // LOGINDIALOG_H

我们在这里新建了一个继承自QDialog的自定义类,类里面暂时还没添加什么东西;

在logindialog.cpp源文件里面编辑好构造函数和析构函数;

#include "logindialog.h"

loginDialog::loginDialog(QWidget *parent)
    : QDialog(parent)
{

}
loginDialog::~loginDialog()
{

}

接下来,我们点开mainwindow的头文件,在MainWindow中添加一个loginDialog的成员,当然,这之前加上这个logindialog.h的头文件。

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QStackedWidget>
#include <QDialog>
#include "logindialog.h"


class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private:
    void creatMenu();
    void creatTool();
    void creatNaviBar();
    void creatStackWidget();

    QStackedWidget *stackWidget;
    loginDialog *myLoginDialog;

private slots:

};
#endif // MAINWINDOW_H

接着我们在mainwindow.cpp的creatTool()添加如下内容:

myLoginDialog = new loginDialog(this);
connect(loginAct,&QAction::triggered,myLoginDialog,&QDialog::show);

这里新建了登录窗口示例,并通过connect函数将loginAct动作按钮的触发信号和登录窗口的显示槽函数连接在一起,就是说只要登录按钮被点击,登录窗口就会显示。

再次运行,发现点击登录,会弹出一个空白的对话框窗口。

Qt实战笔记-从零开始搭建一套库存管理系统-(三)UI框架搭建-02

接下来我们将登录对话框补充完整,按照原型设计,这个对话框包含两个标签,两个文本输入框,两个按钮,整体布局也很规整,但最后一行的列宽和前两行的列宽不一致,所以不能简单的通过表格布局来完成,我们可以通过QGridLayout,QHboxLayout,QVboxLayout综合使用进行布局。

整个页面可以切分成2*4的一个表格,如下所示:

Qt实战笔记-从零开始搭建一套库存管理系统-(三)UI框架搭建-02

在logindialog.h中声明所有的子控件,包括两个标签,两个文本框,两个按钮,代码如下:

#ifndef LOGINDIALOG_H
#define LOGINDIALOG_H

#include <QDialog>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>

class loginDialog : public QDialog
{
    Q_OBJECT

public:
    loginDialog(QWidget *parent = nullptr);
    ~loginDialog();

    QLabel *nameLabel;
    QLabel *passwordLabel;
    QLineEdit *nameEdit;
    QLineEdit *passwordEdit;
    QPushButton *loginButton;
    QPushButton *registButton;
};

#endif // LOGINDIALOG_H

在logindialog.cpp中的构造函数中,补充如下内容:

loginDialog::loginDialog(QWidget *parent)
    : QDialog(parent)
{
    nameLabel = new QLabel("用户名");
    passwordLabel = new QLabel("密码");
    nameEdit = new QLineEdit;
    passwordEdit = new QLineEdit;
    loginButton = new QPushButton("登录");
    registButton = new QPushButton("注册");

    QGridLayout *gridLayout = new QGridLayout;
    gridLayout->addWidget(nameLabel,0,0);
    gridLayout->addWidget(nameEdit,0,1);
    gridLayout->addWidget(passwordLabel,1,0);
    gridLayout->addWidget(passwordEdit,1,1);
    QHBoxLayout *hLayout = new QHBoxLayout;
    hLayout->addWidget(loginButton);
    hLayout->addWidget(registButton);
    QVBoxLayout *vLayout = new QVBoxLayout;
    vLayout->addLayout(gridLayout);
    vLayout->addLayout(hLayout);

    setLayout(vLayout);

}

运行一下,点击登录按钮,可以发现,现在这个登录界面已经基本成型了。

Qt实战笔记-从零开始搭建一套库存管理系统-(三)UI框架搭建-02

2、页面切换

上一个章节中,我们已经通过QStackedWidget添加了6个页面,下面我们将左侧的导航条的6个动作按钮和这6个页面关联在一起,点击不同的按钮,显示不同的页面。

我们把creatNaviBar()函数中那6个临时的动作按钮变成mainwindow的全局变量,在头文件中将它们声明好。

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private:
    void creatMenu();
    void creatTool();
    void creatNaviBar();
    void creatStackWidget();

    QStackedWidget *stackWidget;
    loginDialog *myLoginDialog;

    QAction *homeAction;
    QAction *supplierAction;
    QAction *goodsAction;
    QAction *stockAction;
    QAction *infoAction;
    QAction *userAction;

};

把creatNaviBar()修改为:

void MainWindow::creatNaviBar()
{
    QToolBar *naviBar = new QToolBar("导航",this);
    addToolBar(Qt::LeftToolBarArea,naviBar);
    homeAction = new QAction("主页",this);
    naviBar->addAction(homeAction);
    supplierAction = new QAction("供应商管理",this);
    naviBar->addAction(supplierAction);
    goodsAction = new QAction("商品管理",this);
    naviBar->addAction(goodsAction);
    stockAction = new QAction("库存管理",this);
    naviBar->addAction(stockAction);
    infoAction = new QAction("信息管理",this);
    naviBar->addAction(infoAction);
    userAction = new QAction("用户管理",this);
    naviBar->addAction(userAction);
    naviBar->setMovable(false);
}

接下来,我们在其他地方也可以调用这些动作按钮啦。

我们在mainwindow中添加一个槽函数void switchPages(),在函数体中编辑如下内容:

void MainWindow::switchPages()
{
    QAction *action = qobject_cast<QAction *>(sender());
    if(action->text() == "主页")
        stackWidget->setCurrentIndex(0);
    if(action->text() == "供应商管理")
        stackWidget->setCurrentIndex(1);
    if(action->text() == "商品管理")
        stackWidget->setCurrentIndex(2);
    if(action->text() == "库存管理")
        stackWidget->setCurrentIndex(3);
    if(action->text() == "信息管理")
        stackWidget->setCurrentIndex(4);
    if(action->text() == "用户管理")
        stackWidget->setCurrentIndex(5);
}

这个函数的意思是,我先看下触发这个槽函数的信号发射者是谁,我把发射者转换为动作按钮,如果这个按钮名字和导航栏按钮的文字相符和,那么,堆栈容器就显示相应按钮对应的页面,注意,堆栈容器的索引是从0开始的。

我们在mainwindow的构造函数中将导航栏的6个按钮和这个槽函数连接在一起:

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    creatMenu();
    creatTool();
    creatNaviBar();
    creatStackWidget();
    connect(homeAction,&QAction::triggered,this,&MainWindow::switchPages);
    connect(supplierAction,&QAction::triggered,this,&MainWindow::switchPages);
    connect(goodsAction,&QAction::triggered,this,&MainWindow::switchPages);
    connect(stockAction,&QAction::triggered,this,&MainWindow::switchPages);
    connect(infoAction,&QAction::triggered,this,&MainWindow::switchPages);
    connect(userAction,&QAction::triggered,this,&MainWindow::switchPages);
}

运行一下,可以发现,点击不同的按钮,可以显示不同的页面。

Qt实战笔记-从零开始搭建一套库存管理系统-(三)UI框架搭建-02

3、按钮添加icon

导航栏现在还比较朴素,为了美观,我们为导航栏的每个按钮添加icon。

首先,我们用Photoshop或者sketch等绘图软件切出icon的png格式的文件,因为png可以支持透明背景。切好后的图标用图标代表的内容命名,比如主页按钮的图标,我命名为home.png,尽量命名规范一些,后续在代码中调用会方便一些。

我们把切好的图标放到项目文件目录中的一个文件夹中,文件夹命名为images,切图文件就准备好了。

Qt实战笔记-从零开始搭建一套库存管理系统-(三)UI框架搭建-02

Qt实战笔记-从零开始搭建一套库存管理系统-(三)UI框架搭建-02

然后,需要我们先为工程添加资源文件,点击文件->新建文件或项目->文件和类->Qt->Qt Resource File

Qt实战笔记-从零开始搭建一套库存管理系统-(三)UI框架搭建-02

名字我这里命名为resource。新建成功后,在项目文件窗口能看到项目中增加了一个resource.qrc文件。

Qt实战笔记-从零开始搭建一套库存管理系统-(三)UI框架搭建-02

我们点击添加->添加前缀,把前缀的输入框编辑为“/”

Qt实战笔记-从零开始搭建一套库存管理系统-(三)UI框架搭建-02

然后在项目窗口中选择resource.qrc,右键选择添加现有目录,在弹出的窗口中,勾选好刚才咱们准好的images目录,其他的项目文件不要勾。

Qt实战笔记-从零开始搭建一套库存管理系统-(三)UI框架搭建-02

然后,可以看到项目窗口中的qrc文件可以展开,包含了咱们刚才准备好的图标文件了,接下来我们就可以在项目中直接使用这些图标了。

在creatNaviBar()中,将代码修改如下:

void MainWindow::creatNaviBar()
{
    QToolBar *naviBar = new QToolBar("导航",this);
    naviBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
    addToolBar(Qt::LeftToolBarArea,naviBar);

    const QIcon homeIcon = QIcon::fromTheme("home", QIcon(":/images/home.png"));
    homeAction = new QAction(homeIcon,"主页",this);
    naviBar->addAction(homeAction);

    const QIcon supplierIcon = QIcon::fromTheme("supplier", QIcon(":/images/supplier.png"));
    supplierAction = new QAction(supplierIcon,"供应商管理",this);
    naviBar->addAction(supplierAction);

    const QIcon goodsIcon = QIcon::fromTheme("goods", QIcon(":/images/goods.png"));
    goodsAction = new QAction(goodsIcon,"商品管理",this);
    naviBar->addAction(goodsAction);

    const QIcon stockIcon = QIcon::fromTheme("stock", QIcon(":/images/stock.png"));
    stockAction = new QAction(stockIcon,"库存管理",this);
    naviBar->addAction(stockAction);

    const QIcon infoIcon = QIcon::fromTheme("info", QIcon(":/images/info.png"));
    infoAction = new QAction(infoIcon,"信息管理",this);
    naviBar->addAction(infoAction);

    const QIcon userIcon = QIcon::fromTheme("user", QIcon(":/images/user.png"));
    userAction = new QAction(userIcon,"用户管理",this);
    naviBar->addAction(userAction);

    naviBar->setMovable(false);
}

我们用QIcon这个控件将图标文件置入,然后在每个动作按钮中加入QIcon。记得最开始要把QToolBar的按钮风格设置为文字在图标下面。

运行一下,就可以看到导航栏的按钮已经加上图标啦。

Qt实战笔记-从零开始搭建一套库存管理系统-(三)UI框架搭建-02

好了,到这里,我们基本上把这个软件比较粗糙的UI大框架已经搭完了,虽然还是挺丑的,后续我们会单开一个章节把页面美化一下,现阶段先以实现功能为主。

 

上一篇:服务器部署-常用命令


下一篇:c – Qt将QAction连接到带参数的函数