QT入门知识回顾

1 QT简介

1.1 Qt模块:

  • Qt Core模块: 是QT类库的核心,所有其他模块都依赖这个模块

  • Qt Gui模块: 提供GUI程序的基本功能

  • Qt Network模块:提供跨平台的网络功能

  • Qt Widgets模块:提供创建用户界面的功能

1.2Qt的signal/slot机制

任何一个类只要类体前部书写 Q_OBJECT即可使用Qt的信号/槽机制。

信号和槽的本质是函数

当一个Qt对象的内部状态发生变化的时候,就会发出一个信号,信号起始也是一个函数 当Qt对象收到信号以后,自动去执行对应的函数,这个自动执行的函数就是槽函数

信号与槽之间需要建立连接,才能够将信号与槽函数关联起来 对于信号与槽之间的连接,需要明确以下信息: 是哪个对象发出信号 发出了哪个信号 由谁来接收这个信号 接收到信号以后怎么处理

信号与槽是通过 connect 函数来建立连接的 所以,connect函数的常规参数如下: connect(sender,SIGNAL(信号函数的函数名(参数类型)),receiver,SLOT(槽函数的函数名(参数类型)));

1.2.1 写法一
private slots:void button_clicked_slot();void Widget::button_clicked_slot()
{qDebug()<<"按键被点击";
}
​
QPushButton *button=new QPushButton(this);
button->setText("OK");
connect(button,&QPushButton::clicked,this,&Widget::button_clicked_slot);
    // 传统Qt是连接方式// 传统Qt4连接方式为 信号发送者,信号,信号接受者,处理函数QObject::connect(ui->pushButton,SIGNAL(clicked(bool)),this,SLOT(qT4_slot()));

    //Qt5连接方式//其实这么写的方式和Qt4没有啥却别,只是在Qt4 中引用了信号槽,在简单的使用时没有问题,但是在庞大的工程中,信号和曹 仅仅是宏替换,在编译的时候没有安全监测//Qt5的新方法,在编译的时候就会有监测,如果我们手误操作失误,就会出现问题QObject::connect(ui->pushButton_2,&QPushButton::clicked,this,&Widget::qT5_slot);

1.2.2 写法二
直接在ui设计里面生成一个按钮,然后转到对应的槽,写入要操作的内容,即可

1.2.3 写法三
//Qt5 Lambda表达式//这里需要注意 Lambda表达式是C++ 11 的内容,所以,需要再Pro项目文件中加入 CONFIG += C++ 11QObject::connect(ui->pushButton_3,&QPushButton::clicked,[=](){qDebug()<<"lambda 表达式";});

1.3 自定义信号和槽函数

signals:void windowClose(QString);//声明一个自定义信号private slots:void m_on_windowClose(QString);//自定义槽函数,alt+enter 可以快速生成函数定义//手动连接信号与槽
connect(this,SIGNAL(windowClose(QString)),this,SLOT(m_on_windowClose(QString)));//槽函数
void m_on_windowClose(QString)
{this->close();//关闭主页面
}
​
//发送信号
QString str{"你好"};
emit windowClose(str);

声明槽函数注意点:

  1. 如果是自己的定义的槽函数,建议不要以 on_ 开头,因为以 "on_" 开头,Qt会认为这个是它自动生成的槽函数,在它自己声明的参函数列表中又找不到这个声明,那么就会报警告!

  2. 槽函数一旦声明了,就一定要实现!!!否则就会报错!

信号与槽的连接方式: 信号与槽有两种连接方式:自动连接、手动接连

信号与槽的连接方式: 信号与槽有两种连接方式:自动连接、手动连接

自动连接:在UI设计器中,右键选择对象,选择转到槽,然后选择对应的信号, 那么就会在类中自动添加一个槽函数的声明以及在源文件(.cpp)文件中自动添加一个槽函数的定义,这个槽函数会自动和对应的信号连接

手动连接:手动调用connect函数来完成对应的信号与槽函数的连接

1.4 QT图片类型

QT图片的类型有4种,QPixmap,QImage,QBitmap,QPicture

QPixmap:

  1. 在加载图片的时候,是将图片加载到显存里面,如果图片太大可能会加载失败

  2. 在显示图片的时候,可以在不修改图片数据的前提下对图片进行缩放或者放大显示

  3. 在不同的系统下,显示图片的效果可能会不相同

  4. label->setPixmap(QPixmap(filename));

QImage:

  1. 在加载图片的时候,是将图片加载到内存中

  2. 在显示图片的时候,以原图显示

  3. 在不同的系统下,显示图片的效果是相同的

    显示图片://直接使用文件的路径ui->label->setPixmap(QPixmap("../showpic/image/caixukun.png"));ui->label->setScaledContents(true); //让图片自动适应控件大小//使用资源文件中的文件QPixmap pix{":/image/caixukun.png"};ui->label->setPixmap(pix);ui->label->setScaledContents(true); //让图片自动适应控件大小
​显示动图或者视频:QMovie *mov = new QMovie{":/image/caixukun.gif"};ui->label->setMovie(mov);ui->label->setScaledContents(true); //让图片自动适应控件大小mov->start();    显示图片://直接使用文件的路径ui->label->setPixmap(QPixmap("../showpic/image/caixukun.png"));ui->label->setScaledContents(true); //让图片自动适应控件大小//使用资源文件中的文件QPixmap pix{":/image/caixukun.png"};ui->label->setPixmap(pix);ui->label->setScaledContents(true); //让图片自动适应控件大小
​显示动图或者视频:QMovie *mov = new QMovie{":/image/caixukun.gif"};ui->label->setMovie(mov);ui->label->setScaledContents(true); //让图片自动适应控件大小mov->start();

1.5 setStyleSheet()

样式-英文参数样式-中文
color:white rgb(110,110,110) #eb7350前景颜色,字体颜色
background:transparent背景为透明
background-color:white rgb(110,110,110) #eb7350背景颜色
background-position:left right center top bottom设定图片的位置
background-image:url()./img/back.jpg背景图片 ,不缩放图片大小
border-image:url()./img/back.jpg背景图片,会对图片进行拉伸,平铺
border-style:outset inset边框样式,按下是inset
border-width:px边框大小
border-radius:px边框弧度
border:3px solid redpx color边框宽度以及颜色
border-color: rgba(255, 225, 255, 30);color边框颜色
font-family微软雅黑设定字体所属家族
font: bold 14pxbold px字体大小并加粗
font-size:px字体大小
font-style:inset字体样式
font-weight:px字体深浅
selection-color:color设定选中时候的颜色
eg: ui->pushButton->setStyleSheet("border-image: url(:/images/Coin0001.png);");

1.6 QT样式表ui设计

1.6.1 方法一

img

img

样式表常见设置

//加上#对象,则里面属性设置只针对于该对象
QWidget#centralWidget
{background-image: url(:/bg2.jpg);//直接设置背景图片,但是图片大小不会自适应//border-image: url(:/bg2.jpg);图片大小会自适应centralWidget大小
}
QPushButton#btn_test2
{border-image: url(:/caixukun.png);  
}
​
QPushButton#btn_test:hover//当鼠标落在按钮上面时设置一种颜色
{background-color: rgb(87, 174, 201);
}
​
QPushButton#btn_test:pressed//当鼠标点击按钮上面时设置一种颜色
{background-color: rgb(87, 174, 201);
}
​
QPushButton#btn_test:!hover//当鼠标离开按钮时
{background-color: rgb(137, 194, 227);   
}
​
QPushButton#btn_test
{border-width:2px;border-color: rgb(243, 78, 20);border-style:solid;border-radius:50px;//border-radius 允许你设置元素的外边框圆角color: rgb(239, 41, 41);//设置字体颜色
}

1.6.2 方法二

MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);//可以看到在代码中设置样式,为了方便阅读,使用了繁琐的Tab和换行//因此除了特殊地方需要在代码追加修改样式,项目里一般建议在文本文件内写样式表ui->btn2->setStyleSheet("QPushButton{\background:#EE6AA7;\border:1px solid #8B7E66;\border-radius:5px;\color:white;\}\QPushButton:hover{\background:#FF6EB4;\}\QPushButton:pressed{\background:#CD6090; \}");
}

1.7 QT定时器

Qt中的定时器能够实现定时执行某个函数 Qt中的定时器是通过 QTimer 来实现的 在使用 QTimer 之前需要添加头文件 #include <QTimer>

先实例化一个QTimer的定时器对象QTimer timer(this);
​
设置定时器的间隔时间(定时时长)timer.setinterval(int msecs);   //单位是 毫秒!
​
定时器会定时产生信号 timout()
所以,需要将该信号与对应的槽函数连接起来connet(&timer,SIGNAL(timout()),this,SLOT(槽函数()));
​
连接以后,定时器不会自动启动(开始计时),需要手动调用start()函数来启动
以及通过 stop() 函数来停止timer.start();  //启动定时器timer.stop();   //停止定时器

定时器案例

void Dialog::timer_init()
{//实例化一个定时器对象timer = new QTimer(this);//设置定时的间隔时间(1秒钟=1000毫秒)timer->setInterval(1000);//连接定时器的定时信号和对应的槽函数connect(timer,SIGNAL(timeout()),this,SLOT(m_on_timeout()));
}
​
void Dialog::m_on_timeout()
{//获取系统时间QDateTime dateTime = QDateTime::currentDateTime();QString time = dateTime.toString("yyyy-MM-dd HH:mm:ss");//显示到界面ui->label->setText(time);
}
​
void Dialog::on_btn_start_clicked()
{//启动定时器timer->start();
}
​
void Dialog::on_btn_stop_clicked()
{//停止定时器timer->stop();
}
​

单singleShot,表示它只会触发一次,发出一次信号,然后来执行槽函数。

QTimer::singleShot(2000, this, [this]()
{//等待2s之后运行里面的程序
});

1.8 Qt的文件操作

Qt对文件的操作是通过Qt的文件对象来实现的 在Qt中 QFile 就是文件类型 在使用这个类型的时候需要加头文件 #include <QFile>

  1. 先实例化一个Qt文件对象:

    QFile file;
    QFile file{文件路径名};
  2. 打开文件:

    file.open(文件打开标志);
    文件打开标志:
    QIODevice::NotOpen
    QIODevice::ReadOnly
    QIODevice::WriteOnly
    QIODevice::ReadWrite
    QIODevice::Append
    QIODevice::Truncate
    QIODevice::Text
  3. 读取数据:

    file.read();
    ​
    qint64 read(char *data, qint64 maxSize)
    QByteArray read(qint64 maxSize)
    QByteArray readAll()
    qint64 readLine(char *data, qint64 maxSize)
    QByteArray readLine(qint64 maxSize = 0)
  4. 写入数据:

    file.write();
    ​
    qint64 write(const char *data, qint64 maxSize)
    qint64 write(const char *data)
    qint64 write(const QByteArray &byteArray)
  5. 关闭文件:

     file.close();
  6. 案例介绍

    #include <QFileDialog>
    void Dialog::on_pushButton_clicked()
    {QString file_path = QFileDialog::getOpenFileName(this,"打开文件","../","*.txt *.h *.c *.cpp");//实例化一个文件对象QFile file{file_path,this};//打开文件bool ok = file.open(QIODevice::ReadOnly);if(!ok){//文件打开失败qDebug() << "open file error!";return;}//读取数据while(!file.atEnd()){QString text = file.readLine();//将读到的数据添加到listWidget这个控件中去ui->listWidget->addItem(text);}//关闭文件file.close();
    }

1.9 QT网络编程

TCP协议只需要用两个类 QTcpServer、QTcpSocket

在Qt中如果需要用到网路,就需要在项目的项目管理文件(.pro)文件中添加网络模块:

QT += network

QTcpServer QTcpServer是Qt中的一个类型,它提供了基于TCP协议的服务器编程接口,可以实现服务器端的网络通信。通过QTcpServer这个类型,我们可以很方便、快速地创建一个TCP服务器, 接收来自客户端的连接请求,并与客户端进行通信。

QTcpServer提供了一些信号,如:newConnection()、disconnected()、readyRead()等 用于通知这些事件的发生。 所以,在使用QTcpServer时,可以将对应的信号与槽函数连接,实现各种功能。

QTcpSocket QTcpSocket为Qt的TCP通信提供了套接字,服务器和客户端之间就是通过套接字来通信的

Tcp服务器的使用

1. 实例化一个服务器对象:QTcpServer tcpServer{this};
​
2. 服务器绑定IP地址和端口以及监听客户端的连接:tcpServer.listen(QHostAddress("192.168.110.233"),6666);
​
3. 当有客户端连接的时候,会发信号:newConnection();
​
4. 当监听到客户端连接请求信号,就去处理该连接connect(tcpServer,SIGNAL(newCConneciton()),this,SLOT(m_on_new_connevtion()));
​
5. 从连接列表中获取下一个连接对象QTcpSocket *nextTcpSocket = tcpServer->nextPendingConnection();
​
6. 获取对端(客户端)的IP地址和端口号QString clientIp = nextTcpSocket->peerAddress().toString();     //获取IP地址quint16 port = nextTcpSocket->peerPort();   //获取端口号

服务器和客户端传输数据

方法一:
写数据端:
char data[200]={0};
data[0]='a';
data[1]='b';
data[2]='c';
socket.write(data,3);
​
读数据端:
char data[200]={0};
socket.read(data,200);
data里面既有数据
方法二:
写数据端:// 发送响应数据给客户端QString message = "Hello, client!";clientSocket->write(message.toUtf8());
// 等待数据发送完成
clientSocket->waitForBytesWritten();
​
读数据端:// 等待接收服务器响应数据clientSocket.waitForReadyRead();QByteArray responseData = clientSocket.readAll();QString response = QString::fromUtf8(responseData);qDebug() << "Received from server:" << response;

1.10 串口

Qt5中的串口模块为 Qt Serial Port Qt5中新增了串口模块,如果需要用到Qt的串口模块,就需要在Qt项目的配置文件中加入一下命令: QT += serialport

该模块中包含两个类,QSerialPort和QSerialPortInfo 本项目中只用QSerialPort类即可

大致的使用步骤:

1.加载头文件#include <QSerialPort>
​
2.实例化一个串口对象QSerialPort * = new QSerialPort(this);
​
3.设置串口的属性//设置串口文件的路径名(/dev/ttySAC1)serial->setPortName("/dev/ttySAC1");//设置串口波特率:9600serial->setBaudRate(QSerialPort::Baud9600);//设置数据位:8位serial->setDataBits(QSerialPort::Data8);//设置奇偶校验位:无校验serial->setParity(QSerialPort::NoParity);//设置停止位:1位serial->setStopBits(QSerialPort::OneStop);//设置流控:无流控serial->setFlowControl(QSerialPort::NoFlowControl);在开发板的右上角有4排串口引脚,只有前三排能用,对应的串口文件的路径为:/dev/ttySAC1/dev/ttySAC2/dev/ttySAC3
​
4.连接信号与槽connect(serial,SIGNAL(readyRead()),this,SLOT(m_on_ready_read()));
​
5.打开串口serial->open(QIODevice::ReadWrite);
​
6.通过串口读写数据,和文件io是一样的了read()readAll()write()
​
•当串口外接的设备有数据可读的时候,串口对象serial会自动发送信号:readyRead()
•所以只要将这个信号关联起来,就可以在相应的槽函数中读到数据了
•写数据就通过write函数写就可以了!!!

1.11 线程

方法一:

#include <QDebug>
#include <QThread>
​
// 创建线程
QThread thread;
​
// 将线程对象移动到新线程中
thread.moveToThread(&thread);
​
// 连接线程的started信号到自定义的槽函数
QObject::connect(&thread, &QThread::started, [=]() 
{qDebug() << "Thread started";// 模拟耗时操作for (int i = 0; i < 5; i++) {QThread::sleep(1);qDebug() << "Thread working...";}qDebug() << "Thread finished";// 退出线程事件循环QCoreApplication::quit();
});
​
// 启动线程
thread.start();
​
// 等待线程完成
thread.wait();

方法二:

自定义对象创建线程

class MyThread : public QThread
{
public:void run() override {// 执行线程的工作for (int i = 0; i < 10; i++) {qDebug() << "Thread running" << i;sleep(1); // 暂停1秒}}
};
​
主程序:
MyThread thread;
thread.start();
// 等待线程完成
thread.wait();

2 控件

2.1 pushButton

#include <QPushButton>
int main(int argc,char *argv[])
{QApplication app(argc,argv);QPushButton helloButton("Hello QT!");helloButton.resize(100,30);helloButton.show();return app.exec;
}

常见信号

  1. clicked() 点击

  2. pressed() 按下

  3. release() 释放

2.2 QIcon和QPixmap

QIcon testIcon("\\blankProject\\temp.bmp");
->setIcon(testIcon);
​
->setIcon(QIcon("\\blankProject\\temp.bmp"));
->setIconSize(QSize(200,200));

QPixmap dlg(":/picture/dialog.png");
->setFixedSize(dlg.size());
->setPixmap(dlg);

2.3 QWidget常见槽函数

QWidget:close()                         关闭窗口show()                          显示窗口hide()                          隐藏窗口setVisible(bool visible)        设置窗口是否可见repaint()                       重新绘制界面(控件),相当于刷新update()                        刷新setEnabled(bool)                控制界面(控件)是否接收输入事件setStyleSheet(const QString &styleSheet)    设置样式规则

2.4 QStackedWidget 控件

  1. 添加页面

    img

  1. 页面切换插入第三页

    img

  2. 代码跳转页面

    切记:stackedWidget的页面是从第0面开始

    //方法一:自定义连接函数,采用lambda表达式方式
    connect(ui->pushButton, &QPushButton::clicked, [=]() {
    ui->stackedWidget->setCurrentIndex(0);});connect(ui->pushButton_2, &QPushButton::clicked, [=]() {
    ui->stackedWidget->setCurrentIndex(1);});connect(ui->pushButton_3, &QPushButton::clicked, [=]() {
    ui->stackedWidget->setCurrentIndex(2);});}

     //方法二:void MainWindow::switchPage(){QPushButton *button = qobject_cast<QPushButton*>(sender());//当QPushButton发出一个信号时就记录发出这个信号的对象,sender获取发出信号的对象;if(button==ui->pushButton)ui->stackedWidget->setCurrentIndex(0);else if(button==ui->pushButton_2)ui->stackedWidget->setCurrentIndex(1);else if(button==ui->pushButton_3)ui->stackedWidget->setCurrentIndex(2);int i = 0;ui->stackedWidget->widget(i);
    }void MainWindow::on_pushButton_clicked()
    {switchPage();
    }void MainWindow::on_pushButton_2_clicked()
    {switchPage();
    }void MainWindow::on_pushButton_3_clicked()
    {switchPage();
    }

2.5 QMessageBox

2.5.1 写法一

 QMessageBox msgBox;msgBox.setText("The document has been modified.");msgBox.exec();

2.5.2 写法二

  QMessageBox msgBox;msgBox.setText("The document has been modified.");msgBox.setInformativeText("Do you want to save your changes?");msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);msgBox.setDefaultButton(QMessageBox::Save);int ret = msgBox.exec();switch (ret) {case QMessageBox::Save:// Save was clickedbreak;case QMessageBox::Discard:// Don't Save was clickedbreak;case QMessageBox::Cancel:// Cancel was clickedbreak;default:// should never be reachedbreak;}

3 QT技巧

3.1 QString

#include<QDebug>        //输出头文件
qDebug()<<text;         //速出text
​
//Qstring的用法
//初始化字符串
QString s1;
s1 = "hello;            //赋值
QString s2("hello");    //赋值
s2.clear();             //清空s2
QString s3("123456");    
s3.size();              //计算s3的长度
s3.append(“789”);            //追加数据“789”
​
//字符串拼接加转换
int h=9,m=34,s=20;
QString s4 = Qstring::fromUtf8("当前时间是 %1:%2:%3").arg(h).arg(m).arg(s);
qDebug()<<s4;           //输出是:当前时间是 9:34:20//fromLocal8Bit 字符串转换为本地编码 也就是可以汉字显示QString{"insert into user(username,passwd) values('%1','%2');"}.arg(name).arg(passwd);
​
//字符串切割
QString str5("2023/3/1");
QStringList list = str5.split("/");        //List容器
for(int i = 0; i<list.size(); i++)
{qDebug()<<list[i];            
}
​
//判断字符串是否以指定的字符串结尾,判断后缀名
str6 = "1.bmp";
if(str6.endsWith(".bmp")qDebug()<<"is bmp";//字符串转换
//整形转换为字符串
int val = 123;
QString s7 = QString::number(val);
//将字符串转换为整数
int data = s7.toInt();
qDebug()<<data;
//字符串QString 与 char *之间的转换
QString s8("hello");
char *str = s8.toLocal8Bit().data();
qDebug()<<str;
​
//字符串QString 转换成 C++中的string
std::string s9 = s8.toStdString();
qDebug()<<s9.c_str();                //QT没有做C++的string的重载,所以要.c_str();
//迭代器进行遍历
for(QString::iterator it = s9.begin(); it!=s9.end(); it++)
{qDebug()<<*it;
}
​
//字符串查找或包含
QString str10 = hello 123;
QRegExp re([0-9]{3,});    //使用正则表达式 需要头文件#include<QRegExp>
if(str4.contains(re))qDebug()<<yes;
else qDebug()<<no;

QRegExp正则表达式解释

\d              任意一个数字,0~9 中的任意一个
\w              任意一个字母或数字或下划线,也就是 A~Z,a~z,0~9,_ 中任意一个
\s              包括空格、制表符、换页符等空白字符的其中任意一个
.               小数点可以匹配除了换行符(\n)以外的任意一个字符
​
[ab5@]          匹配 "a" 或 "b" 或 "5" 或 "@"
[^abc]          匹配 "a","b","c" 之外的任意一个字符
[f-k]           匹配 "f"~"k" 之间的任意一个字母
[^A-F0-3]       匹配 "A"~"F","0"~"3" 之外的任意一个字符
​
{n}             表达式重复n次,比如:"\w{2}" 相当于 "\w\w";"a{5}" 相当于 "aaaaa"
{m,n}           表达式至少重复m次,最多重复n次,比如:"ba{1,3}"可以匹配 "ba"或"baa"或"baaa"
{m,}            表达式至少重复m次,比如:"\w\d{2,}"可以匹配 "a12","_456","M12344"...
?               匹配表达式0次或者1次,相当于 {0,1},比如:"a[cd]?"可以匹配 "a","ac","ad"
+               表达式至少出现1次,相当于 {1,},比如:"a+b"可以匹配 "ab","aab","aaab"...
*               表达式不出现或出现任意次,相当于 {0,},比如:"\^*b"可以匹配 "b","^^^b"...
​
^                与字符串开始的地方匹配,不匹配任何字符
$                与字符串结束的地方匹配,不匹配任何字符
\b               匹配一个单词边界,也就是单词和空格之间的位置,不匹配任何字符

3.2 点击按钮弹出对话框/提示框

//这样的话当你点击按钮发送信号的时候会弹出一个提示框,提示内容就是括号里面内容
QMessageBox msgBox;
msgBox.setText("The document has been modified.");
msgBox.exec();
​
//扩展
QMessageBox msgBox;
msgBox.setText(QString::fromUtf8("注册成功"));
msgBox.setInformativeText("Do you want to save your changes?");
msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Save);
int ret = msgBox.exec();

image-20230613103831783

3.3 按钮设置成特定图片样子

    QPushButton *button=new QPushButton(this);
​QPixmap pix;bool ret=pix.load(":/images/Coin0001.png");if(!ret){qDebug()<<"图片加载失败";return;}//设置图片固定大小button->setFixedSize(pix.width(),pix.height());//设置不规则图片样式button->setStyleSheet("QPushButton{border:0px;}");//设置图标button->setIcon(pix);//设置图标大小button->setIconSize(QSize(pix.width(),pix.height()));

3.4 设置按钮点击动态方法

void MyPushButton::zoom1()
{QPropertyAnimation* animation = new QPropertyAnimation(this,"geometry");//animation动画制作//设置动画时间间隔animation->setDuration(200);//设置起始位置animation->setStartValue(QRect(this->x(),this->y()+10,this->width(),this->height()));//设置结束位置animation->setEndValue(QRect(this->x(),this->y(),this->width(),this->height()));//设置弹跳曲线animation->setEasingCurve(QEasingCurve::OutBounce);//执行动画animation->start();
}

3.5 自定义延时函数

#include<QTime>
​
//延时功能
void sleep(unsigned int msec){
//currnentTime 返回当前时间 用当前时间加上我们要延时的时间msec得到一个新的时刻QTime reachTime = QTime::currentTime().addMSecs(msec);//用while循环不断比对当前时间与我们设定的时间while(QTime::currentTime()<reachTime){//如果当前的系统时间尚未达到我们设定的时刻,就让Qt的应用程序类执行默认的处理,//以使程序仍处于响应状态。一旦到达了我们设定的时刻,就跳出该循环,继续执行后面的语句。QApplication::processEvents(QEventLoop::AllEvents,100);}
}
#include<QThread>
QThread::sleep(1);

3.6 mainWindow的常见设置

//设置固定大小
setFixedSize(500,900);
​
//设置图标
setWindowIcon(QIcon(":/resource/Coin0001.png"));
​
//设置标题
setWindowTitle("翻金币主场景");

3.7 利用Label标签显示图片

    //生成胜利图片在最上方QLabel *winLabel=new QLabel;QPixmap winpix;winpix.load(":/resource/LevelCompletedDialogBg.png");//或者 QPixmap winpix=QPixmap(":/resource/LevelCompletedDialogBg.png");winLabel->setGeometry(0,0,winpix.width(),winpix.height());//从窗体的(0,0)位置开始(即为最左上角的点),显示一个w*h的控件。即设置label标签的大小label->setScaledContents(true);//如果图片大小没有标签那么大,那么让图片大小自适应控件大小winLabel->setPixmap(winpix);winLabel->setParent(this);winLabel->move(winpix.width()/2,-winpix.height());

3.8 显示动图或者视频

#include<QMovie>
​
QLabel *label=new QLabel;
label->setParent(this);
label->setGeometry(0,0,200,200);
QMovie *movie=new QMovie(":/images/mov.gif");
label->setMovie(movie);
label->setScaledContents(true);
movie->start();

3.9 重写paintEvent函数实现画图

QWidget中的paintEvent事件处理器可以在子类中被重写来接收绘图事件,然后在指定区域完成图形的绘制。
首先在头文件的Widget子类中进行声明
void paintEvent(QPaintEvent *event);

void MainWindow::paintEvent(QPaintEvent *)
{//画背景色QPalette palette ;palette.setColor(QPalette::Background,QColor("#B1723C"));this->setAutoFillBackground(true);this->setPalette(palette);
​//画线painter.drawLine(0,0,100,100);//画圆形QBrush brush;brush.setStyle(Qt::SolidPattern);painter.setPen(Qt::NoPen);  //去掉pen,避免画出的棋子边缘带线条brush.setColor(Qt::black);painter.setBrush(brush);painter.drawEllipse(x0,y0,w,h);// 画图形QPainter painter(this);QPixmap pix;pix.load(":/resource/PlayLevelSceneBg.png");painter.drawPixmap(0,0,this->width(),this->height(),pix);this->update();//代码会自己调用一次这个函数,如果想要手动调用绘图事件,可以使用update()函数
}

3.10 Qt 定时器翻转金币

    timer1=new QTimer(this);
​connect(timer1,&QTimer::timeout,[=](){QPixmap pix;QString str=QString(":/resource/Coin000%1.png").arg(this->min++);pix.load(str);setCoinStyle(pix);//判断如果翻转完毕,则将Min置为1if(min>max){this->min=1;timer1->stop();}});timer->start(msec );

4 散乱知识点

4.1 创建Qt资源文件

4.1.1.第一步:打开工程目录文件夹

打开工程目录文件夹

4.1.2.第二步:在项目目录文件夹中创建一个 resource 文件夹。

创建好了resource文件夹后继续往这个文件夹 放文件。 在这里插入图片描述

4.1.3.第三步:创建Qt资源文件

在这里插入图片描述

在这里插入图片描述 将名称填号后,浏览路径,找到resource文件夹选择它,然后点下一步,下一步后继续点 确定 就好了。 在这里插入图片描述 创建成功后会发现项目树里多了一个资源出来哦。 在这里插入图片描述

4.1.4.第四步:然后添加前缀,相当于一个文件夹把,拿来分类资源的

在这里插入图片描述在这里插入图片描述

4.1.5 添加想要加入的资源路劲即可

4.2 文件过滤器

#include <QFileDialog>
#include <QDebug>
​
QString picPath=QFileDialog::getOpenFileName(this,"选择图片文件","*.bmp *.png *.jpg *.jpeg");
qDebug()<<picPath;

4.3 解决标签字体显示不完全问题

QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

在这里插入图片描述

###

二、QT数据库

1 数据库创建的基本步骤

数据库头文件:

#include <QSqlDatabase> #include <QSqlError> #include <QSqlQuery>

1.1 Qt中的数据库相关的类型以及接口放在一个单独的模块中,模块名为 sql

QT += sql

1.2 连接数据库

//初始化连接对象,使用静态成员函数addDatabase,参数是数据库的类型
//其中sqlite3 以及 更高的版本的类型名为 QSQLITEuserDb = QSqlDatabase::addDatabase("QSQLITE");
​
//设置数据库库名,建议带路径,如果数据库存在,则直接打开,如果数据不存在,则创建再打开
//使用成员函数setDatabaseName来设置数据库的名称userDb.setDatabaseName("../sql/user.db");

1.3 打开数据库

bool ok = userDb.open();
if(!ok)
{//打开数据库失败qDebug() << "Open userDb error:" << userDb.lastError().text();return;
}

1.4 创建表格user

//需要执行SQL的语句,需要先实例化一个SQL的语句对象,建议在用到该对象的时候再去实例化
QSqlQuery query(userDb);
//准备一条SQL的源语句,创建一个用户表
QString createTable = QString{"create table if not exists user(username varchar(20) primary key,passwd varchar(15));"};//执行SQL语句对象
if(!query.exec(createTable))
{//创建用户表失败qDebug() << "create user table error:" << query.lastError().text();return;
}

2 sqlite3知识

创建关系表:create create table "条件" 表名(列名1 数据类型 "约束",列名2 数据类型 "约束",...,列名3 数据类型 "约束"); 用双引号引来的部分表示可有可无

数据类型: ​ 整数: ​ integer(size) 整数,size用来表示数据最大值的位数 ​ int(size) ​ smallint(size) ​ ... ​ ​ 浮点数: ​ decimal(size,d) 十进制小数,size用来表示整数部分最大值的位数,d规定小数点后面的最大位数 ​ float(size,d) ​ double(size,d) ​ real(size,d) ​ ...

字符串: ​ char(size) 定长的字符串,size用来指定国定长度 ​ varchar(size) 可变字符串长度,size用来指定最大长度

约束: ​ not null 数据不能为空 ​ unique 数据唯一,不能重复 ​ primary key 主键,主键就是 not null + unique ​ 即 主键不能为空且不能重复 ​ foreign key 外键,表示这个字段在其他的表中是主键,表与表之间的联系就是通过外键来连接的 ​ check 检查数据的值是否满足条件(约束值的范围) ​ 如: ​ check(score >= 0 and score <= 100) ​ 如果数据超过了这个范围,就不符合条件就不能设置这个值

条件: ​ if not exists 如果表不存在,则创建,否则不创建

例子: ​ QString createTable = QString{"create table if not exists user(username varchar(20) primary key,passwd varchar(15));"};

删除关系表:drop drop table 表名;

修改关系表名:alter alter table 表名 rename to 新名;

添加字段(列):alter alter table 表名 add 字段名 字段数据类型 "约束";

插入一行记录(数据):insert into insert into 表名(字段1,字段2,...,字段n) values(值1,值2,...,值n); 如: intser into user(name,passwd,number,score) values("zhangsan","666666",19,99.5); 往user表中插入一行数据,指定插入的列为name,passwd,number,score,指定插入的值为"zhangsan","666666",19,99.5

查找数据:select 查找所有的行 select * from 表名; //列举出表格中所有的信息

查找指定列的数据
select 字段1,字段2,...,字段n from 表名 where 列名 运算符 值;运算符:=       等于<>      不等于>       大于<       小于between 值1 and 值2     值在值1和值2之间and     并且or      或者

修改一行数据:update update 表名 set 字段1=新值,字段2=新值,...; //将每一行的指定列的值都设置成指定的值

update 表名 set 字段1=新值,字段2=新值,... where 列名 运算符 值; //只有符合条件的行才修改数据

删除一行记录:delete delete from 表名 where 列名 运算符 值;

3 数据库的增删改查方法

方法一:

QSqlDatabase db;
​
// 建立数据库连接
QSqlDatabase createConnection()
{db = QSqlDatabase::addDatabase("QSQLITE");db.setDatabaseName("./database.db");
​if (!db.open()) {qDebug() << "无法打开数据库!";}
​return db;
}
​
// 创建表格
void createTable(QSqlDatabase db)
{QSqlQuery query(db);QString createTable = "CREATE TABLE IF NOT EXISTS student (""id INTEGER PRIMARY KEY AUTOINCREMENT,""name VARCHAR(20) NOT NULL,""age INTEGER NOT NULL)";query.exec(createTable);
}
​
// 插入数据
void insertData(QSqlDatabase db, const QString& name, int age)
{QSqlQuery query(db);query.prepare("INSERT INTO student (name, age) VALUES (:name, :age)");query.bindValue(":name", name);query.bindValue(":age", age);query.exec();
}
​
// 查询数据
void selectData(QSqlDatabase db)
{QSqlQuery query(db);query.exec("SELECT * FROM student");while (query.next()) {int id = query.value(0).toInt();QString name = query.value(1).toString();int age = query.value(2).toInt();qDebug() << "ID:" << id << "Name:" << name << "Age:" << age;}
}
​
// 更新数据
void updateData(QSqlDatabase db, int id, int age)
{QSqlQuery query(db);query.prepare("UPDATE student SET age = :age WHERE id = :id");query.bindValue(":age", age);query.bindValue(":id", id);query.exec();
}
​
// 删除数据
void deleteData(QSqlDatabase db, int id)
{QSqlQuery query(db);query.prepare("DELETE FROM student WHERE id = :id");query.bindValue(":id", id);query.exec();
}

方法二:

// 插入数据
void insertData(QSqlDatabase db, const QString& name, int age)
{QSqlQuery query(db);query.prepare("INSERT INTO student (name, age) VALUES (?, ?)");query.addBindValue(name);query.addBindValue(age);query.exec();
}
​
// 更新数据
void updateData(QSqlDatabase db, int id, int age)
{QSqlQuery query(db);query.prepare("UPDATE student SET age = ? WHERE id = ?");query.addBindValue(age);query.addBindValue(id);query.exec();
}
​
// 删除数据
void deleteData(QSqlDatabase db, int id)
{QSqlQuery query(db);query.prepare("DELETE FROM student WHERE id = ?");query.addBindValue(id);query.exec();
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

动手学深度学习4.8 数值稳定性和模型初始化-笔记练习(PyTorch)

以下内容为结合李沐老师的课程和教材补充的学习笔记&#xff0c;以及对课后练习的一些思考&#xff0c;自留回顾&#xff0c;也供同学之人交流参考。 本节课程地址&#xff1a;14 数值稳定性 模型初始化和激活函数【动手学深度学习v2】_哔哩哔哩_bilibili 本节教材地址&…

网易云音乐格式在线转换

应用分享&#xff1a;众所周知网易云下载的格式为 .NCM&#xff0c;只能在网易云音乐里播放。 今天提供在线转换为MP3格式 NCM TO MP3&#xff0c;无需安装&#xff0c;转换后就能在任意播放器使用。 使用地址&#xff1a; https://ncm.worthsee.com/ 网络研究观 数据泄露…

E: Unable to locate package ros-kinetic-usb-cam

mkdir -p USB/src && cd USB/src catkin_init_workspace git clone https://github.com/bosch-ros-pkg/usb_cam.git cd .. catkin_make source devel/setup.bash echo "source ~/USB/devel/setup.bash" >> ~/.bashrc source ~/.bashrc 编译过程报错&…

【机器学习】机器学习在深度学习领域中的作用:半监督学习的视角

&#x1f440;时空之门&#x1f440; &#x1f50d;引言&#x1f388;半监督学习概述&#x1f69d;机器学习在深度学习领域中的作用☘特征提取与表示学习&#x1f340;复杂任务建模❀结合半监督学习提升性能 &#x1f680;半监督学习在深度学习中的应用场景&#x1f4d5;图像识…

你每天都在用的APP,原来都是Python写的!

&#x1f446;点击关注 获取更多编程干货&#x1f446; 要说Python的用途&#xff0c;那可太多了&#xff0c;也许你不知道Python是什么&#xff0c;但你一定用过它开发的产品&#xff0c;就像你可能不了解汽车引擎的构造&#xff0c;但你每天都享受着汽车带来的便利一样。 比…

【ARM+Codesys案例】树莓派+Codesys软PLC方案在包装行业灌装旋盖机的应用

ARM系列支持&#xff1a;全志T3、RK3568、树莓派 机型定义&#xff1a;双工位旋盖机 旋盖机主要适用于不同规格的材质及不同规格的盖、旋&#xff08;轧&#xff09;盖。适用螺旋盖、防盗盖、防撞盖、压入盖等。压力可方便调整&#xff0c;根据瓶盖大小设置取盖位。结构紧凑、…

pdf拆分成有图和无图的pdf(方便打印)

pdf拆分成有图和无图的pdf(方便打印) 原因 打印图片要彩印&#xff0c;每次都要手动弄&#xff0c;打印的时候很麻烦&#xff1b; 随着打印次数的增加&#xff0c;时间就越来越多 为解决此问题&#xff0c;使用python写一个exe解决这个问题 历程 找一个python的GUI界面找到 t…

GPT注册、手机验证码、侧边栏、翻译、绘图和视频的安装与使用

侧边栏 下面这个侧边栏收费 效果不错 ## chrome自动翻译 沉浸式翻译效果最好&#xff0c;支持视频 沉浸式翻译 微软网页 https://designer.microsoft.com/image-creator https://www.yeschat.ai/zh-CN/assistants 字节AI网页 https://www.coze.com/store GPT注册 https:…

qt+ffmpeg 实现音视频播放(四)之音视频同步

在处理音视频数据时&#xff0c;解码音频的数据往往会比解码视频的数据比较慢&#xff0c;所以我们在播放音视频时&#xff0c;音频和视频的数据会出现渐渐对不上的情况。尤其在播放时间越长的时候&#xff0c;这种对不上的现象越明显。 为了解决这一问题&#xff0c;人们想出…

数据挖掘综合案例-家用热水器用户行为分析与事件识别

文章目录 1. 背景与挖掘目标2. 分析方法与过程3. 数据分析3.1 数据探索分析3. 2 数据预处理1. 属性约束2. 划分用水事件3. 确定单次用水事件时长阈值4. 属性构造5.筛选候选洗浴事件 3.3 模型构建3.4 模型检验 4. 思考总结 1. 背景与挖掘目标 随着国内大家电品牌的进入和国外品…

探索大模型技术及其前沿应用——TextIn文档解析技术

前言 中国图象图形大会&#xff08;CCIG 2024&#xff09;于近期在西安召开&#xff0c;此次大会将面向开放创新、交叉融合的发展趋势&#xff0c;为图像图形相关领域的专家学者和产业界同仁&#xff0c;搭建一个展示创新成果、展望未来发展&#xff0c;集高度、深度、广度三位…

Django 传递额外参数给视图函数

本书1-7章样章及配套资源下载链接: https://pan.baidu.com/s/1OGmhHxEMf2ZdozkUnDkAkA?pwdnanc 源码、PPT课件、教学视频等&#xff0c;可以从前言给出的下载信息下载&#xff0c;大家可以评估一下。 在Django框架中&#xff0c;URLconf模块还支持一种传递额外参数给视图函…

【前端Vue3】——JQuery知识点总结(超详细)

&#x1f3bc;个人主页&#xff1a;【Y小夜】 &#x1f60e;作者简介&#xff1a;一位双非学校的大二学生&#xff0c;编程爱好者&#xff0c; 专注于基础和实战分享&#xff0c;欢迎私信咨询&#xff01; &#x1f386;入门知识专栏&#xff1a;&#x1f387;【MySQL&#…

IDEA一键启动多个微服务

我们在做微服务项目开发的时候&#xff0c;每次刚打开IDEA&#xff0c;就需要把各个服务一个个依次启动&#xff0c;特别是服务比较多时&#xff0c;逐个点击不仅麻烦还费时。下面来说一下如何一键启动多个微服务。 操作步骤 点击Edit Configurations 2.点击“”&#xff0c;…

华为S5700交换机版本升级步骤

在用一台华为交换机。由于需要做目的镜像接口&#xff0c;在配置过程中超过一个双向流量观察口就会报错。从官方文档查到可以升级版本解决。记录一下升级过程。 首先确定设备型号S5700-28C-EI&#xff0c;系统版本&#xff1a; VRP (R) software, Version 5.150 (S5700 V200R00…

数学建模 —— 层次分析法(2)

目录 一、层次分析法&#xff08;AHP&#xff09; 二、构造比较判断矩阵 2.1 两两比较法 三、单准则下的排序及一致检验 3.1 单准则下的排序 3.2 一致性检验 四、层次总排序 4.1 层次总排序的步骤 4.2 总排序一致性检验 一、层次分析法&#xff08;AHP&#xff09; 方…

Nginx 1.26.0 爆 HTTP/3 QUIC 漏洞,建议升级更新到 1.27.0

据悉&#xff0c;Nginx 1.25.0-1.26.0 主线版本中涉及四个与 NGINX HTTP/3 QUIC 模块相关的中级数据面 CVE 漏洞&#xff0c;其中三个为 DoS 攻击类型风险&#xff0c;一个为随机信息泄漏风险&#xff0c;影响皆为允许未经身份认证的用户通过构造请求实施攻击。目前已经紧急发布…

Solidworks 提取模型中的零件,并组合成一个新的零件,放入特征库

对方发来一个STP文件&#xff0c;其中有模型的部分零件想为我所用。 Shift键鼠标左键 选取需要的零件 在选好零件上右键&#xff0c;选择“孤立” 左边找到部件&#xff0c;ctrl左键选中&#xff0c;选择“插入到新零件” 点 绿色 勾 就选择保存类型&#xff0c;完成 。 打开这…

python入门3

文章目录 前言一、函数为什么要使用函数&#xff1f;函数定义函数定义和调用定义函数返回值定义空函数函数参数传递传递实参位置实参关键词实参默认值实参等效函数调用实参可选传递任意数量的实参任意数量关键字实参任意参数*与** 的区别使用元组和字典传参如果既有实参又有任意…

liunx配置网络的命令

liunx配置网络的命令 文章目录 liunx配置网络的命令ifconfig命令查看路由表信息netstat命令ss命令lsof命令ping 命令nslookup命令 ifconfig命令 ifconfig:显示正在工作的网卡&#xff0c;启动的设备 ifconfig -a 展示所有设备 ens33: flags4163<UP,BROADCAST,RUNNING,MUL…