Qt 制作一个界面

使用Qt制作一个界面在界面中添加相应的控件,绘制所需的图形,并从数据库中获取相应数据在图中绘制,具体界面如下:
在这里插入图片描述](https://img-blog.csdnimg.cn/20200729115539867.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODUxNjMwMg==,size_16,color_FFFFFF,t_70)![在这里插入图片描述

大致流程:

由上图来分析出此界面所经历的流程:
首先我是将整个界面分为三个部分,分别为顶部的标题Label;中间绘制的柱状图以及坐标轴;底部的提示框以及按钮、时间等控件。
首先在主界面利用网格布局QGridLayout设置五个QGroupBox,两个按钮:呼叫和返回,以及可编辑的时间QDateTimeEdit以及一个Qlabel放置日期。并在绘图事件中绘制按钮的边框以及产出次数和异常次数的值。代码如下:

#include "Bottomwidget.h"

BottomWidget::BottomWidget(QWidget *parent)
    : QWidget(parent)
{
    this -> resize(1600,900);
    pLabelShow = new LabelList(this);
    pTableShow = new ListTable(this);//两个指针分别是自定义QWidget类的指针。
    dateLabel =new QLabel(this);
    BtnCall = new QPushButton(QString::fromLocal8Bit("呼叫 call"),this);
    BtnReturn = new QPushButton(QString::fromLocal8Bit("返回《模具监视器》"),this);
    dateEdit = new QDateTimeEdit(QDate::currentDate(), this);
    QDateTime *dateTime = new QDateTime(QDateTime::currentDateTime());
    QFont font;
    QFont btnfont;
    QFont timefont;

    SNBox = new QGroupBox(QString::fromLocal8Bit("设备编号SN"),this);
    OutputBox = new QGroupBox(QString::fromLocal8Bit("产出次数 Output times"),this);
    NGBox = new QGroupBox(QString::fromLocal8Bit("异常次数 NG output"),this);
    CycleBox = new QGroupBox(QString::fromLocal8Bit("生产周期 Cycle"),this);
    NameBox = new QGroupBox(QString::fromLocal8Bit("当前生产(设备/产品)名称:"),this);
    QGridLayout *Layout = new QGridLayout(this);

    timefont.setPointSize(12);
    btnfont.setPointSize(15);
    font.setPointSize(25);

    SNBox -> setFixedSize(280,120);
    OutputBox -> setFixedSize(260,120);
    NGBox -> setFixedSize(280,120);
    CycleBox -> setFixedSize(240,120);
    NameBox -> setFixedSize(300,120);

    QString str = dateTime -> toString("yyyy-MM-dd hh:mm:ss ddd");
    dateLabel -> setText(str);
    dateLabel -> setFixedSize(250,60);
    dateLabel -> setFont(timefont);
    dateLabel -> show();

    dateEdit -> setMinimumDate(QDate::currentDate().addDays(-365));  // -365天
    dateEdit -> setMaximumDate(QDate::currentDate().addDays(365));  // +365天
    dateEdit -> setCalendarPopup(true);  // 日历弹出
    dateEdit -> setFixedSize(300,60);
    dateEdit -> setStyleSheet("background-color: rgb(236,236,236)");
    dateEdit -> setAlignment(Qt::AlignCenter);
    dateEdit -> setFont(font);

    BtnCall -> setStyleSheet("background-color: rgb(255,173,91)");
    BtnCall -> setFixedSize(400,60);
    BtnCall -> setFont(btnfont);
    BtnReturn -> setStyleSheet("background-color: rgb(0,255,64)");
    BtnReturn -> setFixedSize(400,60);
    BtnReturn ->setFont(btnfont);

    Layout -> addWidget(NameBox, 9,8,1,2,Qt::AlignLeft| Qt::AlignBottom);
    //Layout -> setMargin(12);
    Layout -> addWidget(pLabelShow,0,0,1,11,Qt::AlignTop);
    Layout -> addWidget(pTableShow,0,0,12,12);
    Layout -> addWidget(BtnCall,10,0,1,3,Qt::AlignLeft | Qt::AlignBottom);
    Layout -> addWidget(dateEdit,10,3,1,3,Qt::AlignBottom|Qt::AlignCenter);
    Layout -> addWidget(dateLabel,10,6,1,3,Qt::AlignCenter|Qt::AlignBottom);
    Layout -> addWidget(BtnReturn,10,9,1,3,Qt::AlignRight |Qt::AlignBottom);
    Layout -> addWidget(SNBox, 9,0,1,2,Qt::AlignLeft| Qt::AlignBottom);
    Layout -> addWidget(OutputBox, 9,2,1,2,Qt::AlignLeft| Qt::AlignBottom);
    Layout -> addWidget(NGBox, 9,4,1,2,Qt::AlignLeft| Qt::AlignBottom);
    Layout -> addWidget(CycleBox, 9,6,1,2,Qt::AlignLeft| Qt::AlignBottom);
    Layout -> setRowStretch(0,1);//行延展
    Layout -> setSpacing(5);//控件间距
    Layout -> setMargin(0);//边距
}

BottomWidget::~BottomWidget()
{

}

void BottomWidget::paintEvent(QPaintEvent *ev)
{
    QPainter p(this);
    QPen PenRect;

    PenRect.setWidth(2);
    PenRect.setColor(QColor(0,0,0));
    PenRect.setStyle(Qt::DotLine);
    p.setPen(PenRect);
    p.drawRect(dateEdit ->x(),dateEdit ->y(),300,60);
    p.drawRect(BtnCall -> x(),BtnCall -> y(),400,60);
    p.drawRect(BtnReturn ->x() ,BtnReturn->y(),400,60);//绘制按钮以及时间边框

    QFont font;
    font.setPointSize(25);
    QPen PenNum;
    PenNum.setColor(QColor(0,255,0));
    PenRect.setStyle(Qt::SolidLine);
    p.setPen(PenNum);
    p.setFont(font);
    int OPT_total = 0;//Output times,产出次数总数
    int NGT_total =0;//NG times,异常次数的总数
    for(int i = 0;i<24;i++)
    {
        OPT_total = OPT_total + pTableShow ->Output_times[i];
        NGT_total = NGT_total + pTableShow ->NG_times[i];
    }
    QString str = QString("%1").arg(OPT_total);
    p.drawText(OutputBox ->x()+90,OutputBox ->y()+80,str);
    p.setPen(QPen(QColor(255,0,0)));
    p.setFont(font);
    QString str1 = QString("%1").arg(NGT_total);
    p.drawText(NGBox ->x()+90,NGBox ->y()+80,str1);
}

void BottomWidget::resizeEvent(QResizeEvent *event)//当窗口发生变化时自动调用resizeEvent
{
    QWidget::resizeEvent(event);
    this -> update();//刷新图,间接调用paintevent
}

在LabelList中绘制顶部的标题等内容。

#include "Labellist.h"

LabelList::LabelList(QWidget *parent) : QWidget(parent)
{
    //this -> resize(1600,900);
    label1 = new QLabel(QString::fromLocal8Bit("24小时日志|白/夜班日志|"),this);
    label2 = new QLabel(QString::fromLocal8Bit("模具监视器&生产看板"),this);
    label3 = new QLabel(QString::fromLocal8Bit("网络状态:已断开!"),this);
    label4 = new QLabel(QString::fromLocal8Bit("网络状态:运行中!"),this);
    label5 = new QLabel(QString::fromLocal8Bit("异常次数"),this);
    label6 = new QLabel(QString::fromLocal8Bit("产出次数"),this);
    pLayout = new QGridLayout(this);
    QFont font1;
    QFont font2;
    QFont font3("Microsoft YaHei",25,75);
    QPalette p1;
    QPalette p2;

    p1.setColor(QPalette::WindowText,Qt::red);
    p2.setColor(QPalette::WindowText,Qt::green);
    font1.setPointSize(25);
    font2.setPointSize(20);

    label1 -> setFont(font2);
    label1 -> setFixedWidth(380);
    label2 -> setFont(font3);
    label3 -> setPalette(p1);
    label3 -> setFixedWidth(150);
    label4 -> setPalette(p2);
    label4 -> setFixedWidth(150);

    init();

}

void LabelList::init()
{
    pLayout -> addWidget(label1,0,0,2,3,Qt::AlignLeft | Qt::AlignTop);
    pLayout -> addWidget(label2,0,5,2,4,Qt::AlignTop|Qt::AlignCenter);
    pLayout -> addWidget(label3,0,9,1,1,Qt::AlignBottom);
    pLayout -> addWidget(label4,1,9,1,1,Qt::AlignTop);
    pLayout -> addWidget(label5,1,11,1,1,Qt::AlignRight);
    pLayout -> addWidget(label6,1,12,1,1,Qt::AlignTop|Qt::AlignCenter);
    pLayout -> setRowStretch(0,1);
    pLayout -> setSpacing(5);
    this -> setLayout(pLayout);
}

void LabelList::paintEvent(QPaintEvent *)
{
    QPainter p(this);
    p.setBrush(QBrush(QColor(255,0,0)));
    p.drawRect(label5->x()-35,label5->y(),30,15);
    p.setBrush(QBrush(QColor(0,255,0)));
    p.drawRect(label6->x()-35,label6->y(),30,15);//画顶部异常次数和产出次数的框

}
void LabelList::resizeEvent(QResizeEvent *event)
{
    QWidget::resizeEvent(event);
    this -> update();
}

在ListTable中绘制中间的网格坐标以及柱状图:

```cpp
#include "listtable.h"

ListTable::ListTable(QWidget *parent) : QWidget(parent)
{
    pDataport = new DataPort(this);//自定义的QWidget类,即数据端口类
    max = 0;
    for(int i = 0;i<=24;i++)
    {
        Output_times[i] = pDataport ->Output_times[i];
        NG_times[i] = pDataport -> NG_times[i];//从数据端口类中获取数据库中的产出次数的值以及NG次数的值。
        if(max<(Output_times[i]+NG_times[i]))
        max = Output_times[i]+NG_times[i];//获取24小时中产出次数加NG次数的最大值
    }
}

void ListTable::paintEvent(QPaintEvent *)
{
    int m_w = width();
    int m_h = height();//获取窗口宽高
    QFont font;
    font.setBold(true);//设置粗体字
    QPainter p(this);
    QPen PenLine;
    PenLine.setWidth(2);
    PenLine.setColor(QColor(0,0,0));
    PenLine.setStyle(Qt::DotLine);
    p.setPen(PenLine);
    int LineNum = max/50;//设置x方向上的线条数,由于我设置的刻度为50一条线,所以先判断NG次数以及产出次数和的最大值,从而设置出x方向的线条数量。

    if(max % 50)
        LineNum = LineNum+1;

    if(LineNum <3 )
        LineNum = 3;当和小于150时,x方向的线条固定为4条(0,12,3for(int i=0;i<=LineNum;i++)
    {
        QString str = tr("%1").arg((LineNum-i)*50);
        p.drawText(10,m_h/5*3/LineNum*i+137,str);//绘制刻度值
        p.drawLine(40,m_h/5*3/LineNum*i+140,50+m_w/25*24,m_h/5*3/LineNum*i+140);//绘制横线
    }
    for(int i = 0;i<=24;i++)
    {
        QString str = tr("%1").arg(i);
        p.drawText(47+m_w/25*i,m_h/5*3+160,str);//绘制纵坐标刻度,即0-24小时
        p.drawLine(50+m_w/25*i,140,50+m_w/25*i,m_h/5*3+145);//绘制纵线
    }

    p.setPen(QPen(QColor(0,0,0)));
    for(int i = 24;i>=0;i--)//绘制柱状图
    {
        int OPT_Height = Output_times[24-i]/(LineNum*50)*3*m_h/5;
        int NGT_Height = NG_times[24-i]/(LineNum*50)*3*m_h/5;//从数据库中获取的值需要先转化成图上相应的比例的值。
        int j=0;//防止NG次数值的显示与产出次数值显示不重叠
        QString str = tr("%1").arg(Output_times[24-i]);
        QString str1 = tr("%1").arg(NG_times[24-i]);

        if(OPT_Height<12)
        {
            j=12;
        }

        if(i==24//当0点时绘制的柱状图比其余时间要更窄
        {
            p.setBrush(QBrush(QColor(0,255,0)));
            p.drawRect(40,m_h/5*3+140-OPT_Height,30,OPT_Height);
            p.setBrush(QBrush(QColor(255,0,0)));
            p.drawRect(40,m_h/5*3+140-OPT_Height-NGT_Height,30,NGT_Height);
            p.setPen(QPen(QColor(0,0,0)));
            p.setFont(font);
            p.drawText(43,(m_h/5*3+140)-OPT_Height-NGT_Height/2-j,str1);
            p.drawText(43,(m_h/5*3+140)-OPT_Height/2,str);
            continue;
        }

        if(i == 0)
            continue;
//绘制1-23小时的柱状图以及对应的值
        p.setBrush(QBrush(QColor(0,255,0)));
        p.drawRect(30+m_w/25*(24-i),m_h/5*3+140-OPT_Height,40,OPT_Height);
        p.setBrush(QBrush(QColor(255,0,0)));
        p.drawRect(30+m_w/25*(24-i),m_h/5*3+140-OPT_Height-NGT_Height,40,NGT_Height);
        p.setPen(QPen(QColor(0,0,0)));
        p.setFont(font);
        p.drawText(37+m_w/25*(24-i),(m_h/5*3+140)-OPT_Height-NGT_Height/2-j,str1);
        p.drawText(37+m_w/25*(24-i),(m_h/5*3+140)-OPT_Height/2,str);
    }
}

void ListTable::resizeEvent(QResizeEvent *event)
{
    QWidget::resizeEvent(event);
    this -> update();
}


在数据端口的类中实现模型与数据库信息的交互:

#include "dataport.h"

DataPort::DataPort(QWidget *parent) : QWidget(parent)
{
    init();
}

void DataPort::init()
{
    Data *pData = new Data(this);
    pData -> init();
    //QSqlDatabase::database().transaction();
    QSqlQuery query;
    query.exec("select * from DataValue");
//    int value_i = 0;
//    while(query.next())
//    {
//        Output_times[value_i] = query.value(1).toInt();
//        NG_times[value_i++] = query.value(2).toInt();
//    }
    double OPT_array[25] = {30,  1,  2,  3,  4,
                              5,  6,  7,  8,  9,
                             10, 11, 12, 13,
                             14, 15, 16, 17, 18,
                             19, 20, 21, 22, 0};
    double NGT_array[25] = { 55,  1,  2,  3,  4,
                              5,  6,  7,  8,  9,
                             10, 11, 12, 13, 14,
                             15, 16, 17, 18, 19,
                             20, 21, 22, 23, 0};//两个数组来设置产出次数和NG次数的值
    for(int i =0;i<25;i++)
    {
        Output_times[i] = OPT_array[i];
        NG_times[i] = NGT_array[i];
    }
    for(int i =0;i<25;i++)//将产出次数和NG次数的值赋给全局数组。
    {     
        QString OPT_str =QString("update DataValue set OutputValue = '%1' where id = %2").arg(Output_times[i]).arg(i);
        query.exec(OPT_str);
    }
    
}

设置数据库:

#include "Data.h"

Data::Data(QWidget *parent) : QWidget(parent)
{
    init();
}

void Data::init()
{
    QVariantList id;
    id<<0<<1<<2<<3<<4
      <<5<<6<<7<<8<<9
      <<10<<11<<12<<13<<14
      <<15<<16<<17<<18<<19
      <<20<<21<<22<<23<<24;
    QVariantList OutputValues;
    OutputValues<<100<<0<<2<<3<<4
                <<5<<6<<7<<8<<9
                <<10<<11<<12<<13<<14
                <<15<<16<<17<<18<<19
                <<20<<21<<22<<23<<24;
    QVariantList NGValues;
    NGValues<<10<<0<<2<<3<<4
            <<5<<6<<7<<8<<9
            <<10<<11<<12<<13<<14
            <<15<<16<<17<<18<<19
            <<20<<21<<22<<23<<24;
    QSqlDatabase db;
   //在Qt上使用SQLite的时候,如果第二次使用QSqlDatabase::addDatabase()方式时,就会出现以下错误提示:
   //QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
   //所以先判断一下这个默认的连接名是否存在,如果不存在才使用addDatabase()方法,如果存在则使用database()方法
    if(QSqlDatabase::contains("qt_sql_default_connection"))
      db = QSqlDatabase::database("qt_sql_default_connection");
    else
      db = QSqlDatabase::addDatabase("QSQLITE");

    db.setDatabaseName(":memory:");
    if(!db.open())
    {
        QMessageBox::warning(0,"error",db.lastError().text());
        return;
    }

    QSqlQuery query;
    query.exec("create table DataValue(id int primary key, OutputValue int, NGValue int)");//创建数据库
    query.prepare("insert into DataValue (id,OutputValue,NGValue) values (:id,:OutputValue,:NGValue)");//插入数据库的值
    query.bindValue(":id",id );
    query.bindValue(":OutputValue", OutputValues);
    query.bindValue(":NGValue", NGValues);
    query.execBatch();        //加入库中

}

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值