QT学习之旅 - 一个QT的基本项目
文章目录
- 定时器(时间)
- 位置信息
- QTableWidget用cellwidget添加控件
- 隐藏QTableWidget的滚动条
- 自动调整适应大小
- UDP
- UDP Client
- UDP Server
- UDP udpSocket.readDatagram
- 重要参数
- 使用多线程udp
- 自定义信号和槽
- UDP服务端接收数据(全局变量)
- QWT
- 设置标题
- 数轴相关
- 设置坐标轴范围
- 设置坐标轴备注
- 设置坐标轴数值的字体
- 添加数据
- 曲线图
- 注意点
- 直方图
- 设置网格
- 左键选中放大,右键恢复上级,CTRL+右键恢复原样
- 显示图标(一): QwtLegend
- 显示图标(二): QwtPlotLegendItem
- QWT + FFT
- 字符串截取
- 进制转换
- QString转int
- QString转QByteArray(16进制)
- QByteArray(16进制)转float
- 字符串转float
- Qhostaddress 与 Qstring互转
- 2个uint8_t拼接
- 3个uint8_t拼接
- 响应式控件改变位置
- Qt:cannot open output file debug\XXX.exe: Permission denied
- 类型断言
- 静态类型断言
- reinterpret_cast
定时器(时间)
//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");//对位服务器IPquint16 _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
- 加
QMutex线程锁 - 将信号和槽的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);//udpudpServer = 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拼接
我们将它转
QString的arg()
#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重新诠释
相关文章:
QT学习之旅 - 一个QT的基本项目
文章目录 定时器(时间)位置信息QTableWidget用cellwidget添加控件隐藏QTableWidget的滚动条自动调整适应大小 UDPUDP ClientUDP ServerUDP udpSocket.readDatagram重要参数使用多线程udp 自定义信号和槽UDP服务端接收数据(全局变量) QWT设置标题数轴相关设置坐标轴范围设置坐标…...
大数据课程D2——hadoop的概述
文章作者邮箱:yugongshiyesina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 了解hadoop的定义和特点; ⚪ 掌握hadoop的基础结构; ⚪ 掌握hadoop的常见命令; ⚪ 了解hadoop的执行流程; 一、简介 1…...
使用nginx和ffmpeg搭建HTTP FLV流媒体服务器(摄像头RTSP视频流->RTMP->http-flv)
名词解释 RTSP (Real-Time Streaming Protocol) 是一种网络协议,用于控制实时流媒体的传输。它是一种应用层协议,通常用于在客户端和流媒体服务器之间建立和控制媒体流的传输。RTSP允许客户端向服务器发送请求,如…...
揭秘APT团体常用的秘密武器——AsyncRAT
AsyncRAT 是 2019 年 1 月在 [GitHub](https://github.com/NYAN-x-CAT/AsyncRAT-C- Sharp)上开源的远控木马,旨在通过远程加密链接控制失陷主机,提供如下典型功能: 截取屏幕 键盘记录 上传/下载/执行文件 持久化 禁用 Windows Defender 关机/…...
Flutter Widget Life Cycle 组件生命周期
Flutter Widget Life Cycle 组件生命周期 视频 前言 了解 widget 生命周期,对我们开发组件还是很重要的。 今天会把无状态、有状态组件的几个生命周期函数一起过下。 原文 https://ducafecat.com/blog/flutter-widget-life-cycle 参考 https://api.flutter.dev/f…...
LeetCode面向运气之Javascript—第2600题-K件物品的最大和-94.68%
LeetCode第2600题-K件物品的最大和 题目要求 袋子中装有一些物品,每个物品上都标记着数字 1 、0 或 -1 。 四个非负整数 numOnes 、numZeros 、numNegOnes 和 k 。 袋子最初包含: numOnes 件标记为 1 的物品。numZeroes 件标记为 0 的物品。numNegOn…...
数学建模学习(4):TOPSIS 综合评价模型及编程实战
一、数据总览 需求:我们需要对各个银行进行评价,A-G为银行的各个指标,下面是银行的数据: 二、代码逐行实现 清空代码和变量的指令 clear;clc; 层次分析法 每一行代表一个对象的指标评分 p [8,7,6,8;7,8,8,7];%每一行代表一个…...
PHP之Smarty使用以及框架display和assign原理
一、Smarty的下载 进入Smarty官网下载,复制目录libs目录即可http://www.smarty.net/http://www.smarty.net/ 二、使用Smarty,创建目录demo,把libs放进去改名为Smarty 三、引入Smarty配置,创建目录,index.php文件配置 <?php…...
《TCP IP网络编程》第十一章
第 11 章 进程间通信 11.1 进程间通信的基本概念 通过管道实现进程间通信: 进程间通信,意味着两个不同的进程中可以交换数据。下图是基于管道(PIPE)的进程间通信的模型: 可以看出,为了完成进程间通信&…...
Folx Pro 5 最好用的Mac磁力链接BT种子下载工具
除了迅雷,还有哪个支持磁力链接下载?Mac电脑如何下载磁力链接?经常有小伙伴问老宅。今天,老宅给大家推荐Folx Pro For Mac,Mac系统超好用的磁力下载工具。 Folx是一款功能强大且易于使用的Mac下载管理器,并…...
Redis 数据库的高可用
文章目录 Redis 数据库的高可用一.Redis 数据库的持久化1.Redis 高可用概念2.Redis 实现高可用的技术2.1 持久化2.2 主从复制2.3 哨兵2.4 Cluster集群 3.Redis 持久化3.1 持久化的功能3.2 Redis 提供持久化的方式3.2.1 RDB 持久化3.2.2 AOF 持久化(append only file…...
elementPlus dialog组件设置可拖动,当内容高度大于视口高度拖动显示异常的解决办法
elementPlus UI的dialog弹框组件在设置了draggable属性后就可拖动弹框,但是当弹框的内容高度大于视口高度时去拖动弹框就会出现显示问题。 解决办法(修改源码) 去node_modules下面找到element-plus文件夹,按照以下路径修改onMou…...
亲测解决Git inflate: data stream error (incorrect data check)
Git inflate: data stream error (incorrect data check) error: unable to unpack… 前提是你的repository在github等服务器或者其他路径有过历史备份/副本,不要求是最新版本的,只要有就可能恢复你做的所有工作。 执行git fsck --full检查损坏的文件 在…...
Ansible 自动化运维工具
Ansible 简介 Ansible 自动化运维工具(机器管理工具)可以实现批量管理多台(成百上千)主机,应用级别的跨主机编排工具。现在也在自动化管理领域大放异彩。它融合了众多老牌运维工具的优点,Pubbet和Saltstac…...
node.js 爬虫图片下载
主程序文件 app.js 运行主程序前需要先安装使用到的模块: npm install superagent --save axios要安装指定版,安装最新版会报错:npm install axios0.19.2 --save const {default: axios} require(axios); const fs require(fs); const superagent r…...
VAE-根据李宏毅视频总结的最通俗理解
1.VAE的直观理解 先简单了解一下自编码器,也就是常说的Auto-Encoder。Auto-Encoder包括一个编码器(Encoder)和一个解码器(Decoder)。其结构如下: 自编码器是一种先把输入数据压缩为某种编码, 后仅通过该编…...
【LangChain】检索器之上下文压缩
LangChain学习文档 【LangChain】检索器(Retrievers)【LangChain】检索器之MultiQueryRetriever【LangChain】检索器之上下文压缩 上下文压缩 LangChain学习文档 概要内容使用普通向量存储检索器使用 LLMChainExtractor 添加上下文压缩(Adding contextual compression with an…...
uniapp 语音文本播报功能
最近uniapp项目上遇到一个需求 就是在接口调用成功的时候加上语音播报 , ‘创建成功’ ‘开始成功’ ‘结束成功’ 之类的。 因为是固定的文本 ,所以我先利用工具生成了 文本语音mp3文件,放入项目中,直接用就好了。 这里用到的工…...
腾讯云高IO型云服务器CPU型号处理器主频性能
腾讯云服务器高IO型CVM实例CPU处理器主频性能说明,高IO型云服务器具有高随机IOPS、高吞吐量、低访问延时等特点,适合对硬盘读写和时延要求高的高性能数据库等I/O密集型应用,腾讯云服务器网分享高IO型云服务器IT5和IT3的CPU处理器说明…...
【数据结构】实验八:树
实验八 树 一、实验目的与要求 1)理解树的定义; 2)掌握树的存储方式及基于存储结构的基本操作实现; 二、 实验内容 题目一:采用树的双亲表示法根据输入实现以下树的存储,并实现输入给定结点的双亲结点…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...
PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
【SpringBoot自动化部署】
SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一,能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时,需要添加Git仓库地址和凭证,设置构建触发器(如GitHub…...
【深度学习新浪潮】什么是credit assignment problem?
Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...
