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");//对位服务器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重新诠释

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/54265.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【LeetCode 75】第十六题(1004)最大连续1的个数

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码运行结果&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 给一个只有0和1的数组&#xff0c;可以将K个0变成1&#xff0c;问最大能得到的全是1的子数组的长度是多少。 这算是很经典的滑动…

小研究 - 主动式微服务细粒度弹性缩放算法研究(二)

微服务架构已成为云数据中心的基本服务架构。但目前关于微服务系统弹性缩放的研究大多是基于服务或实例级别的水平缩放&#xff0c;忽略了能够充分利用单台服务器资源的细粒度垂直缩放&#xff0c;从而导致资源浪费。为此&#xff0c;本文设计了主动式微服务细粒度弹性缩放算法…

vscode设置远程登录和免密登录

首先&#xff0c;我们去官网下载VScode 安装过程比较简单&#xff0c;大家自行安装即可&#xff0c;注意建议安装在除C盘外的其他盘中。 安装完成后&#xff0c;打开我们下载好的VScode&#xff0c;点击左侧的Extensions选项&#xff0c;搜索Remote&#xff0c;Install第一项R…

初识Linux

今天简单了解了关于操作系统的发展史&#xff0c;学习了在Linux中如何远程连接云服务器的指令&#xff0c;以及在Linux中创建多个用户的指令。 1. ssh root 服务器远程地址 作用是用来连接XShell与云服务器&#xff0c;输入该指令后会自动生成输入密码的窗口&#xff0c;如…

MACOM EDI 需求分析

MACOM 是一家全球性半导体公司&#xff0c;专注于设计和制造高性能射频、微波和光电元件&#xff0c;其产品被广泛应用于通信、航空航天、国防、工业和医疗等领域。随着 MACOM 的不断发展&#xff0c;传统数据传输方式效率较低&#xff0c;无法满足 MACOM 的需求。为了提高企业…

玩转Tomcat:从安装到部署

文章目录 一、什么是 Tomcat二、Tomcat 的安装与使用2.1 下载安装2.2 目录结构2.3 启动 Tomcat 三、部署程序到 Tomcat3.1 Windows环境3.2 Linux环境 一、什么是 Tomcat 一看到 Tomcat&#xff0c;我们一般会想到什么&#xff1f;没错&#xff0c;就是他&#xff0c;童年的回忆…

web前端框架Javascript之JavaScript 异步编程史

早期的 Web 应用中&#xff0c;与后台进行交互时&#xff0c;需要进行 form 表单的提交&#xff0c;然后在页面刷新后给用户反馈结果。在页面刷新过程中&#xff0c;后台会重新返回一段 HTML 代码&#xff0c;这段 HTML 中的大部分内容与之前页面基本相同&#xff0c;这势必造成…

[ 华为云 ] 云计算中Region、VPC、AZ 是什么,他们又是什么关系,应该如何抉择

前几天看到一个问答帖&#xff0c;我回答完了才发现这个帖子居然是去年的也没人回复&#xff0c;其中他问了一些华为云的问题&#xff0c;对于其中的一些概念&#xff0c;这里来总结讲解一下&#xff0c;希望对学习华为云的小伙伴有所帮助。 文章目录 区域&#xff08;Region&a…

nodejs安装及多版本安装与TS环境搭建

nodejs安装及多版本安装与TS环境搭建 方法一&#xff1a; 普通安装nodejs,确定只能安装一个。网址&#xff1a;链接: 官网 不同系统下安装&#xff1a;不同系统下的nodejs 方法二&#xff1a; 借助工具nvm&#xff0c;安装多个nodejs&#xff0c;随时切换nodejs版本 什么是…

网络面试合集

传输层的数据结构是什么&#xff1f; 就是在问他的协议格式&#xff1a;UDP&TCP 2.1.1三次握手 通信前&#xff0c;要先建立连接&#xff0c;确保双方都是在线&#xff0c;具有数据收发的能力。 2.1.2四次挥手 通信结束后&#xff0c;会有一个断开连接的过程&#xff0…

Android水波纹按压效果(不按时透明)

按压后的效果&#xff08;左边"Cancle"是不按压的效果&#xff09; button_water_ripple_bg.xml <?xml version"1.0" encoding"utf-8"?> <ripple xmlns:android"http://schemas.android.com/apk/res/android"android:colo…

Java-API简析_java.io.FileReader类(基于 Latest JDK)(浅析源码)

【版权声明】未经博主同意&#xff0c;谢绝转载&#xff01;&#xff08;请尊重原创&#xff0c;博主保留追究权&#xff09; https://blog.csdn.net/m0_69908381/article/details/132038537 出自【进步*于辰的博客】 因为我发现目前&#xff0c;我对Java-API的学习意识比较薄弱…

Appium+python自动化(三十五)- 命令启动appium之 appium服务命令行参数(超详解)

简介 前边介绍的都是通过按钮点击启动按钮来启动appium服务&#xff0c;有的小伙伴或者童鞋们乍一听可能不信&#xff0c;或者会问如何通过命令行启动appium服务呢&#xff1f;且听一一道来。 一睹为快 其实相当的简单&#xff0c;不看不知道&#xff0c;一看吓一跳&#xf…

linux_进程状态

目录 一. 概念铺设 状态是什么&#xff1f; 传统操作系统的状态转换图 二. 传统操作系统状态 1. 运行 2. 阻塞 3. 挂起 三. linux 中的进程状态 1. 总体介绍 2. R 3. S 4. D kill -9 D vs S 5. T kill T vs S 6. Z 什么是僵尸状态&#xff1f; 僵尸进程的危害 …

详解Mybatis之自动映射 自定义映射问题

编译软件&#xff1a;IntelliJ IDEA 2019.2.4 x64 操作系统&#xff1a;win10 x64 位 家庭版 Maven版本&#xff1a;apache-maven-3.6.3 Mybatis版本&#xff1a;3.5.6 文章目录 一、Mybatis中的自动映射是什么&#xff1f;二、Mybatis中的自定义映射是什么&#xff1f;三、为什…

Spring的创建及使用

文章目录 什么是SpringSpring项目的创建存储Bean对象读取Bean对象getBean()方法 更简单的读取和存储对象的方式路径配置使用类注解存储Bean对象关于五大类注解使用方法注解Bean存储对象Bean重命名 Bean对象的读取 使用Resource注入对象Resource VS Autowired同一类型多个bean对…

租赁固定资产管理

智能租赁资产管理系统可以为企业单位提供RFID资产管理系统。移动APP资产管理&#xff0c;准确总结易损耗品和固定资金&#xff0c;从入库到仓库库存实时跟踪&#xff0c;控制出库和入库的全过程。同时&#xff0c;备件和耗材与所属资产设备有关&#xff0c;便于备件的申请和管理…

express学习笔记3 - 三大件

便于统一管理router&#xff0c;创建 router 文件夹&#xff0c;创建 router/index.js&#xff1a; const express require(express)// 注册路由 const router express.Router() router.get(/,function(req,res){res.send(让我们开始express之旅) }) /*** 集中处理404请求的…

【雕爷学编程】MicroPython动手做(27)——物联网之掌控板小程序3

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…

python与深度学习(十二):CNN和猫狗大战二

目录 1. 说明2. 猫狗大战的CNN模型测试2.1 导入相关库2.2 加载模型2.3 设置保存图片的路径2.4 加载图片2.5 图片预处理2.6 对图片进行预测2.7 显示图片 3. 完整代码和显示结果4. 多张图片进行测试的完整代码以及结果 1. 说明 本篇文章是对上篇文章猫狗大战训练的模型进行测试。…