QT学习之旅 - 一个QT的基本项目

定时器(时间)

//TitleDialogOne.cpp
//用new的方式创建一个QTimer对象
timer = new QTimer(this); //QTimer *timer;
//将定时器的溢出信号连接到自定义的槽函数。
connect(timer,&QTimer::timeout,this,&TitleDialogOne::onNowTimeOut);
timer->start(1000);
//TitleDialogOne.cpp
void TitleDialogOne::onNowTimeOut(){
    QString dt = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
    ui->labelNowTime->setText(dt);
}

位置信息

QTableWidget用cellwidget添加控件

//单元格添加样式
ui->tableWidgetTop->setCellWidget(0, 1, new QSpinBox);

//单元格读取
getTop1 = (QSpinBox *)ui->tableWidgetTop->cellWidget(0,1);//QSpinBox* getTop1;

//#define TOP_CHL_COUNT         (16)      /* 通道数量 */
getTop1->setRange(0,TOP_CHL_COUNT); //设置可选范围
getTop1->setValue(5); //设置初始值为5
隐藏QTableWidget的滚动条
ui->tableWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//隐藏横向滚动条
ui->tableWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//隐藏纵向滚动条
自动调整适应大小
ui->tableWidgetTop->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
ui->tableWidgetTop->horizontalHeader()->setStretchLastSection(true);

UDP

UDP Client
// QUdpSocket *myUdpSocket;//UDP套接字对象
// QHostAddress myGroupAddress;//组播地址
myUdpSocket = new QUdpSocket;//初始化socket
myGroupAddress.setAddress("239.2.2.222");//设置组播地址
myUdpSocket->bind(8080);//绑定端口号
if(myType == 2){ //myType: 只是一个int类型的变量,来区分是单播(一对一)还是多播(组播,一对多)
	//组播的数据的生存期,数据报没跨1个路由就会减1.表示多播数据报只能在同一路由下的局域网内传播
    myUdpSocket->setSocketOption(QAbstractSocket::MulticastTtlOption,1);
}

使用定时器每个1秒发送

void UDPClient::InitTimer(){
    myTimer = new QTimer;//初始化定时器
    connect(myTimer,&QTimer::timeout,this,[=]{
        SendData();
    });
    myTimer->start(1000);//开启定时器,每1秒发送一次数据
}
//发送
void UDPClient::SendData(){
    QByteArray _data = "hello";
    if(myType == 0){//单播
        QHostAddress _peerHostAddress = QHostAddress("my_test_ip");//对位服务器IP
        quint16 _port = my_test_port;//对位服务器端口(int)
        if(-1 !=myUdpSocket->writeDatagram(_data.data(),_data.size(),_peerHostAddress,_port))
        {
            qDebug()<< "单播 ==> Send data : "<< _data<<endl;
        }
        myUdpSocket->flush();
    }else if(myType == 1){ //广播
        quint16 _port = project_port;//广播端口(int)
         if(-1 !=myUdpSocket->writeDatagram(_data.data(),QHostAddress::Broadcast,_port))
         {
            qDebug()<< "广播 ==> Send data : "<< _data<<endl;
         }
         myUdpSocket->flush();
    }else if(myType == 2){//组播
        quint16 _port = project_port;//组播端口(int)
        if(-1 != myUdpSocket->writeDatagram(_data.data(),myGroupAddress,_port))
        {
            qDebug()<< "组播 ==> Send data : "<< _data<<endl;
        }
        myUdpSocket->flush();
    }else{
        qDebug() << "mType is error! "<<endl;
        return;
    }
}
  • 单播(一对一): 需要获取服务端的ip和端口号
    • myUdpSocket->writeDatagram写入成功后可以输出查看值
  • 广播(一对所有的通信方式):确认服务端端口发起请求
    • myUdpSocket->writeDatagram写入成功后可以输出查看值
  • 多播(组播,一对多): 需要获取服务端的端口号发起请求
    • myUdpSocket->writeDatagram写入成功后可以输出查看值
UDP Server
void UDPServer::InitSocket()
{
    //初始化socket,设置组播地址
    mUdpSocket = new QUdpSocket;
    mGroupAdress.setAddress(project_zubo_address);
    if(mType == 0 || mType == 1)
    {
        //绑定本地IP和端口号
        mUdpSocket->bind(my_test_server_port);
    }
    else if(mType == 2)
    {
        if(mUdpSocket->bind(QHostAddress::AnyIPv4,my_test_server_port,QUdpSocket::ShareAddress))
        {
            //加入组播地址
            mUdpSocket->joinMulticastGroup(mGroupAdress);
            qDebug()<<("Join Multicast Adrress [")<<mGroupAdress.toString()
                   <<("] Successful!")<<endl;
        }
    }
    else
    {
        qDebug()<< "mType is error! "<<endl;
        return;
    }

    connect(mUdpSocket,&QUdpSocket::readyRead,this,[=]{
        ReadPendingDataframs();
    });
}



void UDPServer::ReadPendingDataframs()
{
    QByteArray _data;
    _data.resize(mUdpSocket->pendingDatagramSize());
    if(mType == 0)//Unicast
    {
        QHostAddress *_peerHostAddress = new QHostAddress(my_test_ip);
        quint16 _port = my_test_port;
        while(mUdpSocket->hasPendingDatagrams())
        {
            mUdpSocket->readDatagram(_data.data(),_data.size(),_peerHostAddress,&_port);//接收指定IP和端口的udp报文
            qDebug()<<"Unicast ==> Receive data : "<<QString::fromLatin1(_data)<<endl;
        }
    }
    else if(mType == 1)//Broadcast
    {
        QHostAddress _peerHostAddress;
        quint16 _port;
        while(mUdpSocket->hasPendingDatagrams())
        {
            mUdpSocket->readDatagram(_data.data(),_data.size(),&_peerHostAddress,&_port);//接收同一子网的udp报文
            qDebug()<<"Broadcast ==> Receive data : "<<QString::fromLatin1(_data)<<endl;
        }
    }
    else if(mType == 2)//Multicast
    {
        QHostAddress _peerHostAddress;
        quint16 _port;
        while(mUdpSocket->hasPendingDatagrams())
        {
            mUdpSocket->readDatagram(_data.data(),_data.size(),&_peerHostAddress,&_port);//接收同组的udp报文
            qDebug()<<"Multicast ==> Receive data : "<<QString::fromLatin1(_data)<<endl;
        }
    }
    else
    {
        qDebug()<< "mType is error! "<<endl;
        return;
    }
}
UDP udpSocket.readDatagram
udpSocket.hasPendingDatagrams()

在这里插入图片描述
QUdpSocket类的readDatagram()函数用于从UDP套接字中读取数据报。它的函数原型如下:

QHostAddress QUdpSocket::readDatagram(char *data, qint64 maxSize, QHostAddress *address = nullptr, quint16 *port = nullptr)

参数解释:

  • data:指向用于存储接收数据的缓冲区的指针。
  • maxSize:缓冲区的最大大小,即可以接收的最大数据量。
  • address:可选参数,用于返回发送方的IP地址。
  • port:可选参数,用于返回发送方的端口号。

使用readDatagram()函数可以将接收到的数据存储到指定的缓冲区中,并返回接收到的数据大小。以下是一个示例:

QUdpSocket udpSocket;

// 绑定到指定的IP地址和端口
udpSocket.bind(QHostAddress::Any, 1234);

// 监听是否有数据可读
QObject::connect(&udpSocket, &QUdpSocket::readyRead, [&udpSocket]() {
    while (udpSocket.hasPendingDatagrams()) {
        QByteArray datagram;
        datagram.resize(udpSocket.pendingDatagramSize());

        QHostAddress senderAddress;
        quint16 senderPort;

        // 读取数据报
        udpSocket.readDatagram(datagram.data(), datagram.size(), &senderAddress, &senderPort);

        // 处理接收到的数据
        QString receivedData = QString::fromUtf8(datagram);
        qDebug() << "Received data:" << receivedData;
        qDebug() << "Sender address:" << senderAddress.toString();
        qDebug() << "Sender port:" << senderPort;
    }
});

在上面的代码中,我们创建了一个QUdpSocket对象,并使用bind()函数将其绑定到任意IP地址和端口1234。然后,使用readyRead信号来监听是否有数据可读。当有数据可读时,通过readDatagram()函数读取数据,并将其转换为QString类型进行处理。同时,还可以获取发送方的IP地址和端口号。这样,您就可以使用readDatagram()函数在Qt中监听UDP套接字接收到的数据了。

重要参数
// QUdpSocket *mUdpSocket;//UDP套接字对象
// QHostAddress mGroupAddress;//组播地址
mUdpSocket = new QUdpSocket; //实例化对象
mGroupAdress.setAddress("project_zubo_address");//确认组播的地址

mUdpSocket->bind(my_test_server_port);//绑定本地IP和端口号
mUdpSocket->bind(QHostAddress::AnyIPv4,my_test_server_port,QUdpSocket::ShareAddress);//绑定IPv4下的组播端口

使用多线程udp
  1. QMutex线程锁
  2. 将信号和槽的udp接收写在run函数中
//#include <QMutex>
//QMutex mutex;
void UdpThread::run(){
  mutex.lock(); //线程锁
  connect(udpServer->myUdpSocket,&QUdpSocket::readyRead,this,[=](){
    while (udpServer->myUdpSocket->hasPendingDatagrams()){//读取数据
      QByteArray datagram; //16进制
      datagram.resize(udpServer->myUdpSocket->pendingDatagramSize());
      udpServer->myUdpSocket->readDatagram(datagram.data(), datagram.size());
      //数据处理
    }
  })
  mutex.unlock();//线程解锁
}

若对传输速度有要求,就不要用到信号和槽

自定义信号和槽

//自定义信号
#include "signalclass.h"

extern QString globalStr;

SignalClass::SignalClass()
{
}


void SignalClass::setValueSet(const QString& data){
    emit setValue(data);
}

SignalClass::~SignalClass(){

}
//自定义槽
#include "slotclass.h"
#include <QDebug>

SlotClass::SlotClass()
{

}
void SlotClass::slotValue(const QString& data){
    qDebug() << data;
}

SlotClass::~SlotClass(){}

//引用
signalObj = new SignalClass;//SignalClass *signalObj 
slotObj = new SlotClass; //SlotClass *slotObj 
connect(signalObj,&SignalClass::setValue,slotObj,&SlotClass::slotValue);
UDP服务端接收数据(全局变量)
#include "udpserver.h"

extern QString globalStr;//这个定义在mainwindow.cpp中

const int project_port = 8880;
const QString zubo_address = "239.2.2.222";
const int my_test_server_port = 5500;
const QString my_test_ip = "192.168.1.191";
const int my_test_port = 5500;

UDPServer::UDPServer(){
    myType = 2;
    InitSocket();
}

void UDPServer::InitSocket(){
    myUdpSocket = new QUdpSocket;
    myGroupAddress.setAddress(zubo_address);//设置组播地址
    if(myType == 0||myType == 1){
        //绑定本地IP和端口号
        myUdpSocket->bind(my_test_server_port);
    }else if(myType == 2){
        if(myUdpSocket->bind(QHostAddress::AnyIPv4,my_test_server_port,QUdpSocket::ShareAddress)){
            //加入组播地址
            myUdpSocket->joinMulticastGroup(myGroupAddress);
            qDebug()<<("Join Multicast Adrress [")<<myGroupAddress.toString()
                               <<("] Successful!")<<endl;
        }
    }else{
        qDebug()<< "mType is error! "<<endl;
        return;
    }
    //事件
    connect(myUdpSocket,&QUdpSocket::readyRead,this,&UDPServer::ReceiveHexData);
}
void UDPServer::ReceiveStrData(){
    globalStr = ReadPendingDataframs();
    qDebug() << "udp-globalUdpMessage:" << globalStr;
    testSendSetValue(globalStr);
}
void UDPServer::testSendSetValue(const QString &data){
    //connect(myUdpSocket,&UDPServer::setValue,this,&ConfigDialog::showTextEdit2,Qt::DirectConnection);
    emit setValue(data);
}
//读取udp传输过来的字符串信息
QString UDPServer::ReadPendingDataframs(){
    QString buffer;
    QByteArray _data;
    _data.resize(myUdpSocket->pendingDatagramSize());
    if(myType == 0)//Unicast
        {
            QHostAddress *_peerHostAddress = new QHostAddress(my_test_ip);
            quint16 _port = my_test_port;
            while(myUdpSocket->hasPendingDatagrams())
            {
                myUdpSocket->readDatagram(_data.data(),_data.size(),_peerHostAddress,&_port);//接收指定IP和端口的udp报文
                qDebug()<<"Unicast ==> Receive data : "<<QString::fromLatin1(_data)<<endl;
                buffer = QString::fromLatin1(_data);
            }
        }
        else if(myType == 1)//Broadcast
        {
            QHostAddress _peerHostAddress;
            quint16 _port;
            while(myUdpSocket->hasPendingDatagrams())
            {
                myUdpSocket->readDatagram(_data.data(),_data.size(),&_peerHostAddress,&_port);//接收同一子网的udp报文
                qDebug()<<"Broadcast ==> Receive data : "<<QString::fromLatin1(_data)<<endl;
                buffer = QString::fromLatin1(_data);
            }
        }
        else if(myType == 2)//Multicast
        {
            QHostAddress _peerHostAddress;
            quint16 _port;
            while(myUdpSocket->hasPendingDatagrams())
            {
                myUdpSocket->readDatagram(_data.data(),_data.size(),&_peerHostAddress,&_port);//接收同组的udp报文
                qDebug()<<"Multicast ==> Receive data : "<<QString::fromLatin1(_data)<<endl;
                buffer = QString::fromLatin1(_data);
            }
        }
        else
        {
            qDebug()<< "mType is error! "<<endl;
            buffer = "error";
        }
    //testSendSetValue(buffer);
    return buffer;
}
//读取接收到的16进制数
void UDPServer::ReceiveHexData(){ 
    while (myUdpSocket->hasPendingDatagrams()){
        // 读取数据
		QByteArray datagram;
        datagram.resize(myUdpSocket->pendingDatagramSize());
        myUdpSocket->readDatagram(datagram.data(), datagram.size());
        // 将数据转换为16进制字符串
//      QString hexData = QString(datagram.toHex());
        globalStr = QString(datagram.toHex()); //将接收到的16进制数据赋值给权全局变量
        // 打印16进制数据
        qDebug() << "udp-Hex-Received data: " << globalStr;
	}
}

UDPServer::~UDPServer(){
    delete myUdpSocket;
}

在另一个文件(UI文件)中也是connect(myUdpSocket,&QUdpSocket::readyRead,this,&UDPServer::ReceiveHexData);只不过形式变了

//...
extern QString globalStr;//这个定义在mainwindow.cpp中

ConfigDialog::ConfigDialog(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ConfigDialog)
{
    ui->setupUi(this);

    ui->textEdit_2->setReadOnly(true);

    //udp
    udpServer = new UDPServer;
    connect(udpServer->myUdpSocket,&QUdpSocket::readyRead,this,[=](){
        ui->textEdit_2->insertPlainText(globalStr += '\n'); //将全局变量中的数据显示出来(udp的接收到的数据)
    });
}

想法是: 当发生客户端UDP传输去读数据时,在俩个文件(ui文件和udp server)中都发生connect指令

QWT

设置标题
ui->qwtPlot->setTitle(QStringLiteral("这是标题"));

在这里插入图片描述

带属性设置标题

QwtText title;
title.setText(QStringLiteral("属性标题"));

// 设置字体 字体大小 加粗 斜体 字体颜色
QFont font;
font.setFamily("Microsoft YaHei UI Light");
font.setPointSize(20);
font.setBold(true);
font.setItalic(true);
title.setFont(font);
//设置字体颜色
title.setColor(Qt::red);
ui->qwtPlot_1->setTitle(title);
数轴相关
ui->qwtPlot->enableAxis(QwtAxis::YLeft,true);      // 左x轴
ui->qwtPlot->enableAxis(QwtAxis::YRight,true);     // 右x轴
ui->qwtPlot->enableAxis(QwtAxis::XTop,true);       // 顶部y轴
ui->qwtPlot->enableAxis(QwtAxis::XBottom,true);    // 底部y轴
设置坐标轴范围
//ui->qwtPlot->setAxisScale(坐标枚举,最小值,最大值,步长);
ui->qwtPlot->setAxisScale(QwtAxis::YLeft,0,50,10);
ui->qwtPlot->setAxisScale(QwtAxis::YRight,0,50,10);
ui->qwtPlot->setAxisScale(QwtAxis::XTop,0,50,10);
ui->qwtPlot->setAxisScale(QwtAxis::XBottom,0,150,30);

在这里插入图片描述

设置坐标轴备注
//ui->qwtPlot->setAxisTitle(坐标枚举,坐标名称);
ui->qwtPlot->setAxisTitle(QwtAxis::YLeft,"YLeft");
ui->qwtPlot->setAxisTitle(QwtAxis::YRight,"YRight");
ui->qwtPlot->setAxisTitle(QwtAxis::XTop,"XTop");
ui->qwtPlot->setAxisTitle(QwtAxis::XBottom,"XBottom");

在这里插入图片描述

设置坐标轴数值的字体
//QFont xtopFont(字体名称,字体大小)
QFont xtopFont("宋体",14);
xtopFont.setBold(true);
xtopFont.setItalic(true);
//ui->qwtPlot->setAxisFont(坐标枚举,QFont)
ui->qwtPlot->setAxisFont(QwtAxis::XTop,xtopFont);

在这里插入图片描述

添加数据
曲线图
//显示那个方位的坐标
ui->qwtPlot->enableAxis(QwtAxis::YLeft,true);      // 左x轴
ui->qwtPlot->enableAxis(QwtAxis::XBottom,true);    // 底部y轴
//设置坐标范围和步长
ui->qwtPlot->setAxisScale(QwtAxis::YLeft,0,10,1);
ui->qwtPlot->setAxisScale(QwtAxis::XBottom,0,10,1);

//添加数据(重点)
QwtPlotCurve *plotCurve = new QwtPlotCurve();//#include "qwt_plot_curve.h"
plotCurve->setCurveAttribute(QwtPlotCurve::Fitted);
double time[10]={1,2,3,4,5,6,7,8,9,10};
double val[10]={3, 5, 8, 7, 2, 0, 7, 9, 1,10};
//plotCurve->setSamples(x,y,x-valueNumber);(重点)
plotCurve->setSamples(time,val,5);
plotCurve->setStyle(QwtPlotCurve::CurveStyle::Lines);
//显示到控件上(重点)
plotCurve->attach(ui->qwtPlot);

在这里插入图片描述

注意点

使用setSamples的时候如果你的x轴数组<y轴数组会出现以下情况

在这里插入图片描述

源码:

Main->setAxisScale(QwtAxis::YLeft,0,1600,100);
Main->setAxisScale(QwtAxis::XBottom,0,200);

double x[200];
double y[1600];
for(int x1 = 0; x1<200;x1++){
	x[x1] = x1;
}
for(int y1 = 0; y1<1600;y1++){
	y[y1] = y1;
}
sine_main[0].c->setSamples(x,y,1600);

若只修改上面的x[200]x[1600]之后都不修改

在这里插入图片描述

可看出,超出没赋值部分就是默认为0

只有这样写,我们才能的到直线

Main->setAxisScale(QwtAxis::YLeft,0,1600,100);
Main->setAxisScale(QwtAxis::XBottom,0,1600);

double x[1600];
double y[1600];
for(int x1 = 0; x1<1600;x1++){
x[x1] = x1;
}
for(int y1 = 0; y1<1600;y1++){
y[y1] = y1;
}
sine_main[0].c->setSamples(x,y,1600);

在这里插入图片描述

可看出x轴一定要大于y轴,setSamples(x,y,显示大小)这个显示大小可以随x轴来获取

直方图
// 不设置这个属性,不会显示标签
//设置直方图
ui->qwtPlot->insertLegend(new QwtLegend()); //#include "qwt_legend.h"
ui->qwtPlot->setPalette(Qt::white);//设置背景
ui->qwtPlot->setAxisAutoScale(QwtAxis::XBottom,true);//自动设置轴
ui->qwtPlot->enableAxis(QwtAxis::XBottom,false);//取消方位坐标轴

QwtPlotMultiBarChart *plotMultiBarChart = new QwtPlotMultiBarChart(); //#include "qwt_plot_multi_barchart.h"
plotMultiBarChart->setLayoutPolicy(QwtPlotMultiBarChart::AutoAdjustSamples);
plotMultiBarChart->setSpacing(20);
plotMultiBarChart->setMargin(3);


static const char* colors[]={"DarkOrchid","SteelBlue","Gold"};//设置颜色数组
const int numSamples = 5; //设置通道
const int numBars = sizeof(colors)/sizeof(colors[0]);

// 设置标签文字
QList<QwtText> titleList;
titleList.append(QwtText("001"));//标签文字名称
titleList.append(QwtText("002"));//标签文字名称
titleList.append(QwtText("003"));//标签文字名称
plotMultiBarChart->setBarTitles(titleList); //设置进
plotMultiBarChart->setLegendIconSize(QSize(10,10));//标签图标大小

// 设置直方图属性
for(int i =0;i<numBars;i++){
	QwtColumnSymbol *symbol = new QwtColumnSymbol(QwtColumnSymbol::Box);
	symbol->setLineWidth(2);
    symbol->setFrameStyle(QwtColumnSymbol::NoFrame);
    symbol->setPalette(QPalette(colors[i]));
    plotMultiBarChart->setSymbol(i,symbol);
}
// 添加数据
QVector<QVector<double>> series;
for(int i=0;i<numSamples;i++){
	QVector<double> values;
	for(int j=0;j<numBars;j++){
		values+=(2+j%8); //这里进行大小的设置
    }
	series+=values;
}
// 显示到控件上
plotMultiBarChart->setSamples(series);
plotMultiBarChart->attach(ui->qwtPlot);

在这里插入图片描述

设置网格
QwtPlotGrid *gridTop = new QwtPlotGrid();
gridTop->setPen(Qt::gray, 0.0, Qt::DotLine);                //设置网格为灰色点线
gridTop->attach(ui->qwtPlot);

在这里插入图片描述

左键选中放大,右键恢复上级,CTRL+右键恢复原样
/* 默认左键选中放大,右键恢复上级,CTRL+右键恢复原样 */
//QwtPlotZoomer *zoomerTop;
zoomerTop = new MyZoomer(ui->qwtPlot->canvas());//plotTopLine->canvas()
zoomerTop->setMousePattern(QwtEventPattern::MouseSelect2, Qt::RightButton, Qt::ControlModifier);
zoomerTop->setMousePattern(QwtEventPattern::MouseSelect3, Qt::RightButton);
显示图标(一): QwtLegend
/*
Q_SIGNALS:
    void checked(const QVariant&,bool,int);
public slots:
    void legendChecked(const QVariant &, bool);
*/
QwtLegend *legend = new QwtLegend;
legend->setDefaultItemMode( QwtLegendData::Checkable );
ui->qwtPlot->insertLegend(legend,QwtPlot::RightLegend);
connect(legend,SIGNAL(checked(const QVariant&,bool,int)),SLOT(legendChecked( const QVariant &, bool )));

/*
//图例选择事件
void ChanOne::legendChecked(const QVariant &itemInfo, bool on){
    //获取曲线
    QwtPlotItem *plotItem = ui->qwtPlot->infoToItem(itemInfo);
    if(plotItem){
        plotItem->setVisible(on);
    }
    ui->qwtPlot->replot();
}
*/
显示图标(二): QwtPlotLegendItem
  • 前提提示,需要一下操作才可以显示
QwtPlotCurve *a = new QwtPlotCurve(tr("A"));//设置曲线对象和图标文字
a->setPen(Qt::red,1);				//设置颜色
a->attach(ui->qwtPlot);             //将曲线添加到图表
//...

简单的显示

QwtPlotLegendItem *d_legendItemTop = new QwtPlotLegendItem();
d_legendItemTop->attach( ui->qwtPlot );

在这里插入图片描述

设置最大列数

QwtPlotLegendItem *d_legendItemTop = new QwtPlotLegendItem();
d_legendItemTop->setRenderHint( QwtPlotItem::RenderAntialiased );
d_legendItemTop->attach( ui->qwtPlot );
d_legendItemTop->setMaxColumns(1); //设置最大列数

在这里插入图片描述

对齐方式

//QwtPlotLegendItem *d_legendItemTop = new QwtPlotLegendItem();
//d_legendItemTop->setRenderHint( QwtPlotItem::RenderAntialiased );
//d_legendItemTop->attach( ui->qwtPlot );
//d_legendItemTop->setMaxColumns(1);                                          //设置最大列数
d_legendItemTop->setAlignmentInCanvas( Qt::AlignRight | Qt::AlignTop );     //对齐方式(右上)

在这里插入图片描述

设置背景颜色

//QwtPlotLegendItem *d_legendItemTop = new QwtPlotLegendItem();
//d_legendItemTop->setRenderHint( QwtPlotItem::RenderAntialiased );
//d_legendItemTop->attach( ui->qwtPlot );
//d_legendItemTop->setMaxColumns(1);                                          //设置最大列数
//d_legendItemTop->setAlignmentInCanvas( Qt::AlignRight | Qt::AlignTop );     //对齐方式(右上)
d_legendItemTop->setTextPen(QPen(QColor(Qt::white)));                       //设置字体颜色
d_legendItemTop->setBackgroundBrush(QColor(192, 192, 192, 192));            //设置背景颜色
d_legendItemTop->setBorderPen(QPen(QColor(Qt::blue)));                      //设置边框颜色

在这里插入图片描述

设置边框半径(圆弧)

//QwtPlotLegendItem *d_legendItemTop = new QwtPlotLegendItem();
//d_legendItemTop->setRenderHint( QwtPlotItem::RenderAntialiased );
//d_legendItemTop->attach( ui->qwtPlot );
//d_legendItemTop->setMaxColumns(1);                                          //设置最大列数
//d_legendItemTop->setAlignmentInCanvas( Qt::AlignRight | Qt::AlignTop );     //对齐方式(右上)
//d_legendItemTop->setTextPen(QPen(QColor(Qt::white)));                       //设置字体颜色
//d_legendItemTop->setBackgroundBrush(QColor(192, 192, 192, 192));            //设置背景颜色
//d_legendItemTop->setBorderPen(QPen(QColor(Qt::blue)));                      //设置边框颜色
d_legendItemTop->setBorderRadius(5);                                        //设置边框半径(圆弧)

在这里插入图片描述

设置边距

//QwtPlotLegendItem *d_legendItemTop = new QwtPlotLegendItem();
//d_legendItemTop->setRenderHint( QwtPlotItem::RenderAntialiased );
//d_legendItemTop->attach( ui->qwtPlot );
//d_legendItemTop->setMaxColumns(1);                                          //设置最大列数
//d_legendItemTop->setAlignmentInCanvas( Qt::AlignRight | Qt::AlignTop );     //对齐方式(右上)
//d_legendItemTop->setTextPen(QPen(QColor(Qt::white)));                       //设置字体颜色
//d_legendItemTop->setBackgroundBrush(QColor(192, 192, 192, 192));            //设置背景颜色
//d_legendItemTop->setBorderPen(QPen(QColor(Qt::blue)));                      //设置边框颜色
//d_legendItemTop->setBorderRadius(5);                                        //设置边框半径(圆弧)
d_legendItemTop->setMargin( 4 );                                            //设置内边距(x轴)

在这里插入图片描述

d_legendItemTop->setSpacing(4);                                             //设置内边距(y轴)

在这里插入图片描述

d_legendItemTop->setItemMargin(10);                                         //设置项目边距

在这里插入图片描述

QWT + FFT

字符串截取

我们不是将获取到的数据放入全局变量中了吗?那个是转换成16进制后转换成QString来进行显示的,所以我们需要数据处理的时候最简单的就是字符串的截取了

//mid
//QString strbuff = str.mid(索引值,截取大小)
QString pageHead = globalStr.mid(0,2);//0索引开始,取2位
QString initState = globalStr.mid(64,4);//64索引开始,取4位

进制转换

QString转int
//QString转int
QString hexstr = "e02";
bool ok;
int hexnum = hexstr.toInt(&ok,16); // 表示以16进制方式读取字符串
qDebug()<<hexnum<<endl;

注:ok表示转换是否成功,成功则ok为true,失败则ok为false。

QString转QByteArray(16进制)
page_set_Node.chan1_Array.append(strAllArray[i].toLatin1());
QByteArray(16进制)转float
float temp = (float)bytebuff.toFloat(&ok); //bool ok:返回值存放的变量,0为成功
字符串转float
float temp = (float)strbuff.toFloat(&ok); //bool ok:返回值存放的变量,0为成功
Qhostaddress 与 Qstring互转
QHostAddress ip;
QString strIp = ip.toString();
QString strIp;
QHostAddress ip = QHostAddress(strIp);

2个uint8_t拼接
uint8_t a = 0xAB;
uint8_t b = 0xCD;

uint16_t result = ((uint16_t)a << 8) | b;

printf("拼接结果为: %04X\n", result);
3个uint8_t拼接

我们将它转QStringarg()

#include <iostream>
#include <QString>
#include <QDebug>

int main() {
    uint8_t value1 = 01;
    uint8_t value2 = 02;
    uint8_t value3 = 03;

    QString result = QString("%1%2%3").arg(value1).arg(value2).arg(value3);

    qDebug() << result.toStdString();//toStdString():转换成string类型

    return 0;
}

发现是123,但我们想要的先得到的是010203所以我们就要添加一些条件

#include <iostream>
#include <QString>
#include <QDebug>

int main() {
    uint8_t value1 = 01;
    uint8_t value2 = 02;
    uint8_t value3 = 03;

    QString result = QString("%1%2%3").arg(value1,2,10,QChar('0')).arg(value2,2,10,QChar('0')).arg(value3,2,10,QChar('0'));

    qDebug() << result.toStdString();//toStdString():转换成string类型

    return 0;
}

可以的到010203但是若是091011的数据会呈现出091617,原因是他是到十进制是就加一。18进制10在十进制中就是16所以0x11就是17没问题。但是我们的数据毕竟是不是091011所以我们要看QString("%1").arg(value1,2,10,QChar('0'))这参数是什么定义

QString("%1").arg(,宽度,转换的进制,填充数)

所以可以这样来写

#include <iostream>
#include <QString>
#include <QDebug>

int main() {
    uint8_t value1 = 09;
    uint8_t value2 = 10;
    uint8_t value3 = 11;

    QString result = QString("%1%2%3").arg(value1,2,16,QChar('0')).arg(value2,2,16,QChar('0')).arg(value3,2,16,QChar('0'));

    qDebug() << result.toStdString(); .//toStdString():转换成string类型

    return 0;
}

响应式控件改变位置

在这里插入图片描述

Qt:cannot open output file debug\XXX.exe: Permission denied

可能是软件未响应退出后,程序还运行着,之后你未关闭再次运行导致的错误

类型断言

静态类型断言
static_assert<数据类型>(实参)
reinterpret_cast

interpret解释,诠释,reinterpret重新诠释

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

结城明日奈是我老婆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值