QT 入门学习笔记

Qt 从入门到实战:项目创建、信号与槽、计算器与定时器实战、文件操作、事件、TCP 网络编程、多线程与 MySQL 数据库。

1.QT创建项目

1.1创建:

image-20250706145407471

image-20250706145442718

QMainWindow:窗口

QWidget:弹窗

QDialog:对话框

1.2文件体系:

image-20250706145955234

1.3UI控件

image-20250706150400621

layout:布局

V垂直,H水平,G网格,F表单(组合控件)

image-20250706150539864

spacers:弹簧(占位)

把控件挤一挤H水平,V垂直

image-20250706150748052

button:按键

P.T差不读 R单选框 C多选

image-20250706150848331

Item Views:单元视图(数据,显示分离)

Item Widgets:

Container:容器,容控件

Input:输入

Display:输出

2.信号与槽

如点击按键发出一个信号,对信号响应,执行一个函数,这个函数叫槽函数(事件和回调)

image-20250706153737334

image-20250706154516937

image-20250706163657876

三种连接方式

3.写计算器

设计ui

image-20250706190331034

添加槽函数

设计框尺寸,框标题、字体

image-20250706191635487

各按钮槽函数类推

按键插图片

image-20250706193648157

退格功能

image-20250706193704445

计算功能太难,跳过

4.定时器

QObject:

startTimer killTimer

启动定时器

image-20250706203351198

image-20250706203408679

标签显示图片

image-20250706205447485

轮换逻辑

image-20250706205507239

QTimer:

头文件

image-20250706212306386

启动定时器

image-20250706212322492

图片法二

image-20250706213249026

槽函数

image-20250706213315451

image-20250706213330314

image-20250706213348467

转换逻辑

image-20250706215101291

暂停

image-20250706215333265

5.QT文件操作

ui设计

image-20250706220550737

新建

添加槽函数

image-20250708002047710

实现槽函数

image-20250708002120089

连接功能

image-20250708002146473

打开

头文件

QFileDialog 开文件选择框

QMessageBox 开警告盒子

QDebug 输出文字到控制台

QFile 读取文件内容

image-20250708002225044

添加槽函数

image-20250708002447904

连接功能

image-20250708002602720

实现槽函数

void MainWindow::openActionSlot()
{
    //括号里的参数分别是:指定父类、标题、默认打开后显示的目录、右下角的文件过滤器。
    QString filename =
        QFileDialog::getOpenFileName(this,
        "选择一个文件",
        ".",
        "*.txt");
    qDebug() << filename;
    if(filename.isEmpty())
    {
        QMessageBox::warning(this,"警告","请选择一个文件");
    }
    else
    {
        qDebug()<<filename;
        QFile file(filename);
        file.open(QIODevice::ReadOnly);
        QByteArray array = file.readAll();	//读取文件所有内容
        ui->textEdit->setText(QString(array));
        file.close();
    }
}

保存

添加槽函数

image-20250708143207152

连接功能

image-20250708143223448

实现槽函数

void MainWindow::saveActionSlot()
{
    QString filename =
        QFileDialog::getSaveFileName(this,
                                     "选择一个文件",
                                     "."      //当前路径的话是QCoreApplicationFilePath()
                                     ); //不写就是所有文件
    if(filename.isEmpty())
    {
        QMessageBox::warning(this,"警告","请选择一个文件");
    }
    else
    {
        QFile file(filename);
        file.open(QIODevice::WriteOnly);
        QString str = ui->textEdit->toPlainText();
        QByteArray array = str.toLocal8Bit();
        //array.append(ui->textEdit->toPlainText());
        file.write(array);
        file.close();
    }
}

6.QT事件

键盘事件

ctrl+s实现保存,即打开保存原文件

重写键盘事件虚函数

#include

void keyPressEvent(QKeyEvent *k);

void MainWindow::keyPressEvent(QKeyEvent *k)
{
    if(k->modifiers() == Qt::ControlModifier) { // 如果按下了CTRL键
        if(k->key() == Qt::Key_S){
            qDebug()<<"CTRL + S";
            saveActionSlot();
        }
    }
}

鼠标事件

#include

void mousePressEvent(QMouseEvent *m);

void MainWindow::mousePressEvent(QMouseEvent *m)
{
    QPoint pt = m->pos();
    qDebug()<<pt;
    if(m->button() == Qt::LeftButton)
    {
        qDebug()<<"左键被按下";
    }
    if(m->button() == Qt::RightButton)
    {
        qDebug()<<"右键被按下";
    }
}

7.QT TCP

服务器客户端
socketsocket
bindconnect
listensend/recv
accept
send/recv

与网络相关的在工程里加network

image-20250708155251043

TCP前置

image-20250708155352062

image-20250708155438420

image-20250708155636868

客户端

UI设计

image-20250708155703484

编辑槽函数

#include

void Widget::on_connectButton_clicked()
{
    //获取ip地址和端口号
    QString IP = ui->ipLineEdit->text();
    QString PORT = ui->portLineEdit->text();

    //连接服务器
    socket->connectToHost(QHostAddress(IP),PORT.toShort());

    //连接服务器成功,socket对象发出信号
    connect(socket,&QTcpSocket::connected,[this]()
            {
        QMessageBox::information(this,"连接提示","连接服务器成功");
    });

    //连接断开,socket也会发出信号
    connect(socket,&QTcpSocket::disconnected,[this](){
        QMessageBox::warning(this,"连接提示","连接异常 网络断开");
    });
}

服务器

UI设计

image-20250708164301580

头文件

#include #include

创建槽函数

image-20250708164357300

监听

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    server = new QTcpServer;

    server->listen(QHostAddress::AnyIPv4,PORT);

    //客户端发起连接,server发出信号
    connect(server,&QTcpServer::newConnection,this,&Widget::newClientHandler);
}

实现槽函数

void Widget::newClientHandler()
{
    //建立TCP连接
    QTcpSocket *socket = server->nextPendingConnection();
    //socket->peerAddress(); //获取客户端地址
    //socket->peerPort();//获取端口号
    ui->iplineEdit->setText(socket->peerAddress().toString());
    ui->portlineEdit->setText(QString::number(socket->peerPort()));
}

8.QT启动新窗口(接服务器,实现发数据)

客户端

对原串口对象连接成功后可以使用

this->hide();隐藏

在原界面头文件引入新界面对象头文件

#include <chat.h>

在原界面需要显示新界面的时候声明对象,像Widget w; w.show()一样

image-20250708165731756

但是新对象要使用socket,因此要传入

Chat *c =new Chat(socket);//堆空间创建

此时需要添加类Chat头文件和成员

#include <QTcpSocket>

image-20250708170221202

构造函数进行一个赋值

Chat::Chat(QTcpSocket *s,QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Chat)
{
    ui->setupUi(this);
    socket = s;
}

服务器

image-20250708171553246

实现槽函数

void Widget::clientInfoSlot()
{
    
    QTcpSocket *s = (QTcpSocket *)sender();//获取信号的发出者

    QString str = QString(s->readAll());
    ui->mainlineEdit->setText(str);
}

实现了客户端发送,服务器接收并显示

9.QT多线程

接TCP,实现服务器多线程,多客户端连接一个服务器

创建线程类

image-20250708194229897

image-20250708203427019

#include <QThread>
//继承自QThread
class my_thread : public QThread
{
}

启动线程

    //启动线程在widget.cpp
    my_thread *t = new my_thread(socket);//创建线程对象
    t->start();//开始线程

重写虚函数

public:
    explicit my_thread(QTcpSocket *s,QThread *parent = nullptr);
    //重写虚函数
    void run();

修改类

添加成员,修改构造函数参数,在构造函数进行赋值

.h

class my_thread : public QThread
{
    Q_OBJECT
public:
    explicit my_thread(QTcpSocket *s,QThread *parent = nullptr);
    //重写虚函数
    void run();
private slots:
    void clientInfoSlot();

private:
    QTcpSocket *socket;
};

.cpp
my_thread::my_thread(QTcpSocket *s,QThread *parent)
    : QThread{parent}
{
    socket = s;
}

实现虚函数和槽函数


void my_thread::run()
{
   connect(socket,&QTcpSocket::readyRead,this,&my_thread::clientInfoSlot);

}

void my_thread::clientInfoSlot()
{
    qDebug()<<socket->readAll();
}

10.自定义信号

继QT多线程

子线程

在my_thread类中创建自定义信号

signals:
	void sendToWidget(QByteArray b);
//my_thread.cpp

void my_thread::clientInfoSlot()
{
    //qDebug()<<socket->readAll();
    QByteArray ba = socket ->readAll();
    emit sendToWidget(ba);//发送信号
}

主线程

接收数据链接槽函数

image-20250708205723802

实现槽函数

image-20250708205757077

11.MySQL数据库

MySQL部分

1
2
3
4
5
6
7
8
9
create database mydatabase;

create table student(
    id integer unsigned primary key,
    name varchar(16) not null,
    birth date
)charset utf8;

select * from student;

QT部分

image-20250708213548476

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//.h

#include <QSqlDatabase>
#include <QMessageBox>

...
private:
	QSqlDatabase db;



//.cpp
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //连接数据库
    db = QSqlDatabase::addDatabase("QMYSQL");//加载MySQL数据库驱动
    db.setDatabaseName("mydatabase");
    db.setHostName("localhost");
    db.setUserName("root");
    db.setPassword("194910");
    if(db.open())
    {
        QMessageBox::information(this,"连接提示","连接成功");
    }
    else
    {
        QMessageBox::warning(this,"连接提示","连接失败");
    }
}
最后更新于 Tuesday, September 1, 2026
使用 Hugo 构建
主题 Stack 由 Jimmy 设计