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)掌握树的存储方式及基于存储结构的基本操作实现; 二、 实验内容 题目一:采用树的双亲表示法根据输入实现以下树的存储,并实现输入给定结点的双亲结点…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案
这个问题我看其他博主也写了,要么要会员、要么写的乱七八糟。这里我整理一下,把问题说清楚并且给出代码,拿去用就行,照着葫芦画瓢。 问题 在继承QWebEngineView后,重写mousePressEvent或event函数无法捕获鼠标按下事…...
vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...
