(项目实战)基于QT嵌入式ARM数据采集卡上位机(二)——页面布局
上一篇文章《基于 QT 嵌入式ARM数据采集卡上位机(一)》
下一篇文章《(项目实战)基于QT嵌入式ARM数据采集卡上位机(三)—— qwt和fft使用》
源代码 github仓库 https://github.com/xiaoliu-406/simpledata
这里,我将页面布局分为两个部分,一是页面整体布局也就是上中下布局,即menubar,widget,statusbar,三者;二是左右布局,即widget的左侧和右侧。本文的界面全部是代码编辑完成。
文章目录
(一)界面的效果图如下:
(二)代码展示
1. 上中下布局
(1) mainwidow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QApplication>
#include <QDesktopWidget>
#include <QRect>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include <QDebug>
#include <QTabWidget>
#include "./gui/menubar/menubar.h"
#include "./gui/statustate/statustate.h"
#include "./gui/baseplot/baseplot.h"
#include "./gui/functionUI/functionui.h"
#define UIselect 0
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
InitGui();
QRect deskrect = QApplication::desktop()->availableGeometry();
int weight = deskrect.width();
int height = deskrect.height();
this->resize(weight,height);
this->setGeometry(0,0,weight,height);
qDebug() << weight << height;
this->setStyleSheet("background: rgb(250, 250, 240);");
centralWidget()->setStyleSheet("background: rgb(230, 230, 220);");
qDebug() <<"mainthread"<< QThread::currentThreadId();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::InitGui()
{
menubar().MenubarGui(menuBar());
statustate().StatustateGui(statusBar());
functionui *baseplot = new functionui();//first widget
QWidget *function = new QWidget();// second widget
baseplot->setStyleSheet("background: rgb(230, 230, 220);");
QTabWidget *maintablewidget = new QTabWidget();//table widget
maintablewidget->setAttribute(Qt::WA_StyledBackground);
maintablewidget->setAutoFillBackground(true);
maintablewidget->insertTab(0,baseplot,QStringLiteral("base"));
maintablewidget->insertTab(1, function,QStringLiteral("function"));
QVBoxLayout *mainlayout1 = new QVBoxLayout();
mainlayout1->addWidget(maintablewidget);
centralWidget()->setLayout(mainlayout1);
}
(2) statustate.cpp 状态栏(statusbar)布局
#include "statustate.h"
#include <QLabel>
statustate::statustate(QObject *parent) : QObject(parent)
{
}
void statustate::StatustateGui(QStatusBar *statustate)
{
QLabel *leftlabel = new QLabel("this is my state");
statustate->addWidget(leftlabel);
QLabel *per3 = new QLabel("Ready3");
QLabel *per2 = new QLabel("Ready2");
// statustate->addWidget(per3);
statustate->addPermanentWidget(per2);
statustate->addPermanentWidget(per3);
statustate->setStyleSheet(QString("QStatusBar::item{border: 0px}"));
}
(3) menubar.cpp 菜单栏的设置和布局
#include "menubar.h"
#include <QMenu>
menubar::menubar(QObject *parent) : QObject(parent)
{
}
void menubar::MenubarGui(QMenuBar *mennubar)
{
QMenu *menu = mennubar->addMenu("window");
menu->addAction("save");
}
菜单栏和状态栏没有添加相应的动作,有需要这里可以利用connect进行添加相应的函数。
2. 左右布局
这里左右布局,即为对baseplot进行布局,上述(1)中InitGui()函数,中的baseplot.
对应文件为functionui.cpp,以下内容全为functionui.cpp中内容,如不是,会有注明。
(1)左右整体布局
void functionui::UI_init()
{
QGraphicsDropShadowEffect *shadow_effect = new QGraphicsDropShadowEffect(this);
shadow_effect->setOffset(-10, 10);
//阴影颜色
shadow_effect->setColor(Qt::gray);
//阴影半径
shadow_effect->setBlurRadius(100);
QFrame *frame = new QFrame();
frame->setFrameShape(frame->Box);
frame->setFrameShadow(QFrame::Raised);
frame->setLineWidth(1);
frame->setLayout(leftwidget());
//main layouot
//main layout
QFrame *widget2 = new QFrame();
widget2->setLayout( rightwidget());
widget2->setFrameStyle(QFrame::Panel | QFrame::Sunken);
widget2->setLineWidth(1);
QHBoxLayout *hlayout = new QHBoxLayout(this);
hlayout->addWidget(frame,1);
hlayout->addWidget(widget2,3);
hlayout->setSpacing(5);
}
这里没有用widget,使用的是Qframe,可以使窗口界面具有立体感。
(2)左侧界面布局
QVBoxLayout *functionui::leftwidget()
{
//select layout
QLabel *protoco = new QLabel("Potoco Select");
QComboBox *potoco_select = new QComboBox();
potoco_select->addItem("UDP");
potoco_select->addItem("TCP_SERVER");
potoco_select->addItem("TCP_CLICK");
QHBoxLayout *selct_layout = new QHBoxLayout();
selct_layout->addWidget(protoco);
selct_layout->addWidget(potoco_select);
selct_layout->setStretchFactor(protoco,1);
selct_layout->setStretchFactor(potoco_select,1);
//ip and port ui
QLabel *ip_label = new QLabel("IP");
ip_label->setAlignment(Qt::AlignCenter);
QLabel *port_label = new QLabel("PORT");
port_label->setAlignment(Qt::AlignCenter);
ip_linedit = new QLineEdit("239.0.0.2");//local physical ip:192.168.3.99
port_linedit = new QLineEdit("8080");
// ip & port layout
QHBoxLayout *ip_port_layout = new QHBoxLayout();
ip_port_layout->addWidget(ip_label);
ip_port_layout->addWidget(ip_linedit);
ip_port_layout->addWidget(port_label);
ip_port_layout->addWidget(port_linedit);
ip_port_layout->setSpacing(1);
ip_port_layout->setStretchFactor(ip_label,1);
ip_port_layout->setStretchFactor(ip_linedit,4);
ip_port_layout->setStretchFactor(port_label,1);
ip_port_layout->setStretchFactor(port_linedit,2);
//simple rate
QHBoxLayout *ratesimple = new QHBoxLayout();
ratesimple = simpleratelayout();
//test pushbutton size
testbutton = new QPushButton("RUN",this);
testbutton->setIcon(QIcon(":/icon/redclose.png"));
// testbutton->sizeHint();
// testbutton->setChecked(true);
testbutton->setAutoExclusive(true);
testbutton->setCheckable(true);
testbutton->setStyleSheet("QPushButton:checked{background-color: green;}");
QHBoxLayout *testlayout = new QHBoxLayout();
testlayout->addWidget(testbutton);
testlayout->setAlignment(Qt::AlignHCenter);
//ui -- left layout
//ui -- left layout
// QWidget *blank = new QWidget(this);
showtext = new QTextEdit(this);
QVBoxLayout *leftlayout = new QVBoxLayout(this);
leftlayout->addLayout(selct_layout);
leftlayout->addLayout(ip_port_layout);
leftlayout->addLayout(ratesimple);
// leftlayout->addLayout(channellayout);
leftlayout->addLayout(testlayout);
leftlayout->addWidget(showtext);
leftlayout->setStretchFactor(selct_layout,1);
leftlayout->setStretchFactor(ip_port_layout,1);
leftlayout->setStretchFactor(ratesimple,1);
// leftlayout->setStretchFactor(channellayout,1);
leftlayout->setStretchFactor(testlayout,1);
leftlayout->setStretchFactor(showtext,1);
leftlayout->setSpacing(5);
leftlayout->setContentsMargins(0,5,0,0);
connect(testbutton,SIGNAL(clicked()),this,SLOT(GetLocalIpandPort()));
return leftlayout;
}
左侧采样率选择——这里为默认1000,如需要,请自行增加Connect添加动作。
QHBoxLayout *functionui::simpleratelayout()
{
QLabel *ratelabel = new QLabel("SimpleRate");
ratelabel->setAlignment(Qt::AlignCenter);
QComboBox *SimpleRate = new QComboBox();
QStringList stringlist = {"1000","2000","3000"};
SimpleRate->addItems(stringlist);
QLineEdit *simpleline = new QLineEdit("1000");
QHBoxLayout *simplelayout = new QHBoxLayout();
simplelayout->addWidget(ratelabel);
simplelayout->addWidget(simpleline);
simplelayout->setStretchFactor(ratelabel,1);
simplelayout->setStretchFactor(simpleline,1);
return simplelayout;
}
(3) 右侧布局
QVBoxLayout *functionui::rightwidget()
{
QWidget *widget = new QWidget;
signalplot = new BasePlot("signal");
fftplot = new BasePlot("fft");
QHBoxLayout *selectplot = new QHBoxLayout();
QCheckBox *fftbox = new QCheckBox("addfft");
selectplot = chanellayout(fftbox);
QVBoxLayout *vboxlayout = new QVBoxLayout;
vboxlayout->addLayout(selectplot);
vboxlayout->addWidget(signalplot);
vboxlayout->addWidget(fftplot);
fftplot->hide();
// the model of thread with slot
sigthread = new signafftthread;
sll_udp = new SLL_UDP;
thread = new QThread(this);
udpthread = new QThread(this);
sll_udp->moveToThread(udpthread);
sigthread->moveToThread(thread);
// qDebug() <<"mainthread"<< QThread::currentThreadId();
qRegisterMetaType<QVector<double>>("QVector<double>");
qRegisterMetaType<quint16>("quint16");
qRegisterMetaType<QString>("QString");
qRegisterMetaType<bool>("bool");
connect(this,&functionui::startthread,sigthread,&signafftthread::simpletest);
connect(this,&functionui::startudpthread,sll_udp,&SLL_UDP::dealmsgthread);
fft = new sllFFT(1000);
connect(this,SIGNAL(fftsignal(QVector<double>,QVector<double>)),this,SLOT(pushfftdata(QVector<double>, QVector<double>)));
connect(fft,SIGNAL(processCompleted(QVector<double>,QVector<double>)),this,SLOT(fftslot(QVector<double>,QVector<double>)));
connect(this,SIGNAL(destroyed()),this,SLOT(threaddestroy()));
connect(this,SIGNAL(udpthreadstop(bool)),this,SLOT(udpthreadstopfun(bool)));
connect(sll_udp,SIGNAL(sll_UdpMsg(QString)),this,SLOT(texteditshow(QString)));
connect(sll_udp,SIGNAL(sll_UdpMsg(QVector<double>)),this,SLOT(texteditshow(QVector<double>)));
emit startthread();
thread->start();
return vboxlayout;
}
右侧checkbox设置
```c++
QHBoxLayout *functionui::chanellayout(QCheckBox *fftbox)
{
QHBoxLayout *returnlayout = new QHBoxLayout();
QHBoxLayout *channellayout = new QHBoxLayout();
// channel layout
QCheckBox *chanelbox = new QCheckBox("chanel 1");
checkboxstyle(chanelbox);
channellayout->addWidget(chanelbox);
channellayout->setAlignment(Qt::AlignRight);
QHBoxLayout *addfftlayout = new QHBoxLayout;
checkboxstyle(fftbox);
addfftlayout->addWidget(fftbox);
addfftlayout->setAlignment(Qt::AlignRight);
QCheckBox *chanel2box = new QCheckBox("chanel 2");
QCheckBox *chanel3box = new QCheckBox("chanel 3");
checkboxstyle(chanel2box);
checkboxstyle(chanel3box);
returnlayout->addWidget(chanelbox);
returnlayout->addWidget(chanel2box);
returnlayout->addWidget(chanel3box);
returnlayout->addWidget(fftbox);
returnlayout->setAlignment(Qt::AlignLeft);
connect(fftbox,&QCheckBox::stateChanged,this ,[=]{
if(!fftbox->isChecked()) fftplot->hide();
else fftplot->show();
});
connect(chanel3box,&QCheckBox::stateChanged,this ,[=]{
if(chanel3box->isChecked()){
curve = new QwtPlotCurve("curve");
signalplot->AttachPlotCurve(curve,QPen(Qt::red));
curve->show();
showchanel1sign = true;
qDebug() << "curve chanel1 show";
}
else {
showchanel1sign = false;
curve->hide();
delete curve;
qDebug() << "curve chanel1 hide";
}
});
connect(chanel2box,&QCheckBox::stateChanged,this ,[=]{
if(chanel2box->isChecked()){
chanel2curve = new QwtPlotCurve("chanel 2");
signalplot->AttachPlotCurve(chanel2curve,QPen(Qt::green));
chanel2curve->show();
showchanel2sign = true;
qDebug() << "curve chanel2 show";
}
else {
showchanel2sign = false;
chanel2curve->hide();
delete chanel2curve;
qDebug() << "curve chanel2 hide";
}
});
connect(chanelbox,&QCheckBox::stateChanged,this ,[=]{
if(chanelbox->isChecked()){
chanel3curve = new QwtPlotCurve("chanel 1");
signalplot->AttachPlotCurve(chanel3curve,QPen(Qt::blue));
chanel3curve->show();
showchanelsign = true;
qDebug() << "curve chanel show";
}
else {
showchanelsign = false;
chanel3curve->hide();
delete chanel3curve;
qDebug() << "curve chanel hide";
}
});
chanelbox->setChecked(true);
chanel2box->setChecked(true);
chanel3box->setChecked(true);
return returnlayout;
}
void functionui::checkboxstyle(QCheckBox *box)
{
box->setStyleSheet("QCheckBox::indicator {width: 22px; height: 22px;}"
"QCheckBox::indicator:checked {image: url(:/icon/redselct.jpg);}");
}