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.mzph.cn/diannao/22173.shtml

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

相关文章

香港移民政策放开了,2024拿香港身份的8种方式,申请条件解读

​香港移民政策放开了&#xff0c;2024拿香港身份的8种方式&#xff01; 都2024年了&#xff0c;香港身份还受欢迎吗&#xff1f; 当然受欢迎&#xff0c;我们从数据上就能看出来&#xff0c;去年有超过24万人通过各类人才引入计划申请来港&#xff0c;其中超过14万获批&…

静态网页实现-人脸识别-案例(web)

&#x1f933;人脸识别&#xff08;web) 基于开源大模型&#xff0c;将人脸识别功能整合到网页中&#xff0c;提供用户友好的界面和强大的功能。 核心功能 人脸轮廓识别&#xff1a; 通过深度学习算法&#xff0c;精确识别人脸的轮廓&#xff0c;包括眼睛、鼻子、嘴巴等关键部…

在QML中调用 C++ 函数的方法(四)

文章目录 前言一、qml 和 c++ 交互的官方文档介绍二、QML 中调用 C++ 实现的函数的方法1. Exposing Attributes of C++ Types to QML1.1 暴露 Properties1.2 暴露 Methods(槽函数和Q_INVOKABLE 修饰的函数)1.3 暴露 Signals2. Defining QML Types from C++3. 代码实例3.1 创建一…

【OpenHarmony】ArkTS 语法基础 ③ ( @Component 自定义组件生命周期回调函数 | @Entry 页面生命周期回调函数 )

文章目录 一、ArkTS Component 自定义组件生命周期1、自定义组件生命周期2、aboutToAppear 函数执行时机和作用3、aboutToDisappear 函数执行时机和作用4、代码示例 二、ArkTS Entry 页面生命周期1、Entry 页面生命周期2、onBackPress 和 onPageHide 回调函数无关联 三、代码示…

文化若想挣钱,真的很可怕吗?

文化若想挣钱&#xff0c;真的很可怕吗&#xff1f; 近日&#xff0c;我看到受人尊敬的静思有我先生的一个音频作品《会挣钱&#xff0c;遇上有文化&#xff0c;这个地方很可怕》&#xff0c;把这个标题在网上搜一搜&#xff0c;在它下面就跟着有这样一篇文章--商人不可怕&…

vscode 1.85安装remote-ssh后左侧没有图标

vscode安装remote-ssh插件后左侧没有图标。 解决方法 想要左侧有图标&#xff0c;是另一个插件起作用&#xff1a;Remote Explorer 但是这个插件最新版需要1.87&#xff0c;可以switch to Pre-release version之后就能用了。 其实&#xff0c;最后再switch to Release Versio…

动静态库【Linux】

文章目录 静态库的打包动态库的打包 静态库的打包 把我们提供的方法&#xff0c;给别人用: 1、把源文件直接给别人 2、把源代码打包成库库.h 例如 &#xff1b;有a.c b.c c.c d.c ,四个.c文件 &#xff0c; 将a.c 形成a.o ,b.c形成b.o c.c形成c.o d.c形成d.o文件&#xff0c;…

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

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

【力扣刷题 动态规划】LeetCode 139 单词拆分、LeetCode 300 最长递增子序列 ✌

文章目录 1. 单词拆分2. 最长递增子序列 1. 单词拆分 题目链接 &#x1f34e; 解题思路&#xff1a; class Solution {bool dp[310] {false};public:bool wordBreak(string s, vector<string>& wordDict) {unordered_set<string> myset;for(auto& str :…

《欢乐钓鱼大师》新手攻略大全!新手逆袭之路!

《欢乐钓鱼大师》是一款趣味十足的模拟钓鱼游戏&#xff0c;适合各类玩家&#xff0c;从钓鱼新手到钓鱼高手都能在游戏中找到乐趣。为了帮助新手玩家更快地掌握游戏技巧&#xff0c;提高钓鱼水平&#xff0c;我们准备了一些实用的攻略和技巧&#xff0c;帮助大家轻松入门&#…

PDF 文件的解析

1、文本 PDF 的解析 1.1、文本的提取 进行文本提取的 Python 库包括&#xff1a;pdfminer.six、PyMuPDF、PyPDF2 和 pdfplumber&#xff0c;效果最好的是 PyMuPDF&#xff0c;PyMuPDF 在进行文本提取时能够最大限度地保留 PDF 的阅读顺序&#xff0c;这对于双栏 PDF 文件的抽…

MyBatis3.4全集笔记

MyBatis 1. MyBatis 简介 MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code&#xff0c;并且改名为MyBatis 。2013年11月迁移到Github。 iBATIS一词来源于“internet”和“abatis”的组合&#xff0c;是一个基于Ja…

SpringSecurity6从入门到实战之SpringSecurity整合自动装配详解(源码级讲解,耐心看完)

SpringSecurity6从入门到实战之SpringSecurity整合自动装配详解 这里我先引出问题然后再来一步步进行剖析,SpringSecurity到底是如何实现引入依赖后所有请求都需要进行认证并且会弹出login登录表单页面. 接下来会对SpringBoot的自动装配进行详解,SpringSecurity也是通过自动装配…

AI绘画Stable Diffusion 制作幻术光影字:使用Brightness亮度控制模型,超简单!

大家好&#xff0c;我是灵魂画师向阳。 今天给大家分享的教程是利用AI工具Stable Diffusion 制作光影文字。这是一种通过模拟自然光线照射和阴影效果&#xff0c;使文字看起来具有立体感和逼真感的设计风格。 它的主要目的是让文字自然的融合在场景中。 先来看组实例图。 …

【机器学习数据挖掘】基于ARIMA 自回归积分滑动平均模型的销售价格库存分析报告 附完整python代码

资源地址&#xff1a;Python数据分析大作业 4000字 图文分析文档 销售分析 完整python代码 ​ 完整代码分析 同时销售量后1000的sku品类占比中&#xff08;不畅销产品&#xff09;如上&#xff0c;精品类产品占比第一&#xff0c;达到66.7%&#xff0c;其次是香化类产品&#…

【赠书活动】好书推荐—《详解51种企业应用架构模式》

导读&#xff1a; 企业应用包括哪些&#xff1f;它们又分别有哪些架构模式&#xff1f;世界著名软件开发大师Martin Fowler给你答案。 01 什么是企业应用 我的职业生涯专注于企业应用&#xff0c;因此&#xff0c;这里所谈及的模式也都是关于企业应用的。&#xff08;企业应用…

逐步掌握最佳Ai Agents框架-AutoGen 八 开源模型

前言 本篇文章&#xff0c;我们来探索下AutoGen使用其它LLM大模型。主要原因是AutoGen在使用chatgpt3.5/chatgpt 4等付费模型时&#xff0c;token开销比较大。如果我们的业务&#xff0c;社区里的开源模型就能搞定&#xff0c;那当然就开冲了。 接下来就让我们看下&#xff0…

书籍《钱从哪里来5:微利社会》观后感

样例 前几周看完了这本书&#xff0c;《钱从哪里来5&#xff1a;微利社会》&#xff0c;这应该算是&#xff0c;作者香帅在“得到”出的第5本书了。个人来看&#xff0c;或者说尽自己而言&#xff0c;现在并不是对财理相关话题&#xff0c;有很大兴趣&#xff0c;只是在跨年的时…

有哪些好用的ai工具,可以提升科研、学习、办公等效率?

最近&#xff0c;Sora的诞生为AI再添了一把火。 据介绍&#xff0c;这款“文生视频”的Sora可以直接输出长达60秒的视频&#xff0c;并且包含高度细致的背景、复杂的多角度镜头&#xff0c;以及富有情感的多个角色。 不仅能准确呈现细节&#xff0c;还能理解物体在物理世界中…

指针的认识(野指针、规避野指针、assert宏断言)

目录 a.野指针成因 1.指针未初始化 2.指针越界访问 3.指针指向的空间释放 b.规避野指针 1.指针初始化 2.小心指针越界 3.指针变量不再使用时&#xff0c;及时置NULL&#xff0c;指针使用之前检查有效性 4.避免返回局部变量的地址 c.assert宏断言的使用 概念&#xff1…