Qt快速入门-带你快速入门qt+小项目

按照类的功能来做笔记

基本内容: 基本控件、信号与槽、定时器、文件、网络、线程、自定义信号、数据库

1、qtcreator常用功能

1.1快捷键

常用: F1: 查看帮助 F2: 跳转到函数定义 F4: 头文件和源文件之间切换 F5: 开始调试 Ctrl+I: 自动对齐代码 Ctrl+/: 注释和取消注释行 设计页面> shift + alt + r 项目预览(不需要构建)

快捷键

功能

其他快捷键

F1

查看帮助

F2

跳转到函数定义

Ctrl+鼠标左键

F3

查找下一个

F4        

头文件和源文件之间切换

F5            

开始调试

F9            

设置和取消断点

F10         

单步前进

F11       

单步进入函数

Shift+F2 

声明和定义之间切换

Shift+F3 

查找上一个

Shift+F5   

停止调试

Shift+F11  

单步跳出函数

Ctrl+0    

编辑页面恢复默认字体

Ctrl+1    

欢迎模式

Ctrl+2    

编辑模式

Ctrl+3    

设计模式

Ctrl+4    

Debug模式

Ctrl+5    

项目模式    

Ctrl+6     

Analyze模式

Ctrl+7    

帮助模式

Ctrl+B    

编译(构建)工程

Ctrl+F      

查找替换当前选中的内容(按下Ctrl+F,会高亮显示所有和你选的内容一样的语句)

Ctrl+I        

自动对齐(自动对齐选中的行)

Ctrl+L        

跳到某一行(按下快捷键后会弹出一个输入框,直接输入要跳转的行数,例如:100)

Ctrl+M    

添加或删除标签

Ctrl+R    

运行工程

Ctrl+/        

注释行,取消注释行

Ctrl+[       

跳到代码块的头部

Ctrl+]        

跳到代码块的尾部

Ctrl+Space 

自动补全(会和输入法的切换中英文冲突,导致不起作用)

Ctrl+Shift+F  

查找内容

Ctrl+Shift+< 

折叠代码块

Ctrl+Shift+> 

展开代码块

Alt+0      

显示或者隐藏侧边条,编辑模式下起作用(有时写的函数太长,屏幕不够大,就用这个)

Alt+1      

显示或者隐藏问题窗口

Alt+2      

显示或者隐藏搜索结果(Search Results)窗口

Alt+3      

显示或者隐藏应用程序输出窗口

Alt+4      

显示或者隐藏编译输出窗口

Alt+5      

显示或者隐藏QML/JS Console窗口

Alt+6      

显示或者隐藏概要信息窗口

Alt+7      

显示或者隐藏Version Control窗口

ESc        

切换到编辑模式

1.2查看qtcreator版本

2、新建项目

2.1选择项目模板

Application   //应用项目
    Qt Widgets Application   //控件应用、窗口应用
Non-Qt Project   //空项目

2.2 选择编译系统

CMake 很常用,功能也很强大,许多知名的项目都是用它,比如 OpenCV 和 VTK,但它的语法繁杂。
qmake 是针对辅助 Qt 开发的,但也可以在非 Qt 项目使用,特点是语法简单明了,但功能也相对简单。
Qbs 因市场原因,弃用Qbs。

2.3 选择项目 主类

MainWindow    //带菜单栏
Widget    //不带菜单栏 - eg:登录页
Dialog    //对话框

2.4项目文件目录

以项目test01为例

介绍几个重要的
debug    - 测试项目 选择debug构建项目 产生的文件存放处
release  - 对外发布项目 选择release构建项目 产生的文件存放处
test01.pro    - 项目配置文件
test01.pro.user    - 记录自己电脑的配置(文件路径等)
test01.h    - 项目头文件
test01.cpp    - 项目源文件
test01.ui    - 项目界面文件 只允许test01类 使用
main.cpp    - 项目 启动原始路径

3、界面设计

界面设计 wiget控件介绍

Layout //布局方式
    Vertical Layout //水平布局
    Horizontal Layout //垂直布局
    Grid Layout //网格布局
    Form Layout //表单布局
Spacers //垫子(弹簧、间距)
    Horizontal Spacer //水平弹簧
    Vertival Spacer //垂直弹簧
Buttons 
    Push Button
    Tool Button
    Radio Button //单选框
    Check Box //复选框
    command Link Button
    Dialog Button Box
Item Views (Model-Based) //单元视图 - 数据显示分离 - 操作数据库
    List View //列表视图
    Tree View //树型视图
    Table View //表格视图
    Column View //列视图
    Undo View
Item Widgets (Item-Based) //单元控件 - 文件管理系统
    List Widget //列表控件
    Tree Widget //树型控件
    Table Widget //表格控件
Containers //容器 - 容纳存放别的控件
    Group Box
    Srcoll Area
    Tool Box
    tab Widget
    Stacked Widget
    Frame
    Widget
    MDI Area
    Dock Widget
    QAxWidget
Input Widgets //输入控件
    Combo Box
    Fon Combo Box
    Line Edit //行编辑控件
    Text Edit //文本编辑控件
    Plain Text Edit
    Spin Box
    Double Spin Box
    Time Edit
    Date Edit
    Date/Time Edit
    Dial
    Horizontal Scroll Bar
    Vertical Scroll Bar
    Horizontal Slider
    Vertical Slider
    Key Sequence Edit
Display Widgets //显示控件
    Label
    Text Browser
    Graphics View
    Calendar Widget //日历控件
    LCD Number //时钟显示
    Progress Bar
    Horizontal Line
    Vertical Line
    OpenGL Widget
    QQuickWidget

4、信号与槽

图为:自动绑 定信号与槽

//方式一:自动绑定 信号与槽
//设计页面->转到槽->编写函数执行内容
//按钮直接 触发 对应槽函数
#include <QProcess>    //进程头文件
void Widget::on_commitButton_clicked()
{
    //获取line Edit数据
    QString program = ui->lineEdit->text();
    //创建新的 程序进程
    QProcess *myProcess = new QProcess(this);
    myProcess->start(program);
}

//方式二:connect函数 手动绑定 信号和槽
//实现lineEdit回车 确定控件功能
//连接信号与槽 connect(谁发出信号 发出什么信号 谁处理信号 怎么处理)
connect(ui->lineEdit, SIGNAL(returnPressed()), this, SLOT(on_commitButton_clicked()));    //老Qt版本
connect(ui->cancelButton, &QPushButton::clicked, this, &Widget::on_cancelButton_clicked);
//点击“取消”按钮 关闭程序
void Widget::on_cancelButton_clicked(){
    this->close();
}

//方式三
//点击 绑定按钮 弹出对话框
connect(ui->browseButton, &QPushButton::clicked, this, [this](){
        //消息弹窗 窗口父类 窗口标题 窗口文本内容
        QMessageBox::information(this, "信息", "点击浏览");
    });

5、qt显示图片

1、在Button上显示图标
    QIcon con("D:\\Qt_warkspace\\QtCreatorLearn_Calculator\\delete.png");
    ui->Button_delete->setIcon(con);

2、在label上显示图片 QPixmap    //自带头文件
    QPixmap pix(QString path);
    ui->label->setPixmap(pix);
3、在label上显示图片 QImage     //自带头文件
    QImage img;
    img.load(QString path);
    ui->label->setPixmap(QPixmap::fromImage(img));

4、图片拉伸填满
label->QLabel->scaledContents->true

6、定时器

6.1 QObject

开始:startTimer 结束:killTimer

class Widget ... {
    ...
public:
    //继承QObject的虚函数
    //传入定时器编号QTimerEvent *event
    virtual void timerEvent(QTimerEvent *event);
private:
    int myTimerId;
}
构造函数{
    ...
}
槽函数中 开始定时器{
    //启动定时器,返回定时器编号
    myTimerId = this->startTimer(TIMEOUT);
}
//重写的虚函数 传入定时器编号QTimerEvent *event
槽函数 每次定时器调用timerEvent(QTimerEvent *event){
    if(event->timerId() != myTimerId)
        return;

    //更新图片
    QString path("D:\\Qt_warkspace\\QtCreator07_QObject_Timer\\img\\");
    path += QString::number(picID);     //int 转 QString
    path += ".jpg";

    QPixmap pix(path);
    ui->label->setPixmap(pix);

    picID++;
    if(picID > 6)
        picID = 1;
}
槽函数中 结束定时器{
    this->killTimer(myTimerId);
}

6.2 QTimer

#include

开始:start 结束:stop

class Widget ... {    ...
private slots:    //槽函数
    void timeoutSlot();    //显示图片 并picID++
private:
    QTimer *timer;
}
槽函数中 开始定时器{
    timer->start(1000);    //毫秒
}
构造函数{
    timer = new QTimer;
    //定时器 绑定 槽函数
    //connect(谁发出信号, 发出什么信号, 谁来处理, 怎么处理)
    connect(timer, &QTimer::timeout, this, &Widget::timeoutSlot);
}
槽函数 每次定时器调用 timeoutSlot{
    //图片处理
    QString path("D:\\Qt_warkspace\\QtCreator08_QTimer\\img\\");
    path += QString::number(picID);
    path += ".jpg";

    QImage img;
    img.load(path);
    ui->label->setPixmap(QPixmap::fromImage(img));

    picID++;
    if(picID > 6){
        picID = 1;
    }
}
槽函数中 结束定时器{
    timer->stop();
}
参函数中 单次定时器{    //(时间过后)只触发一次
    //(定时时长ms, 到时执行对象, 执行槽函数)
    QTimer::singleShot(1000, this, SLOT(timeoutSlot()));
}
    

7、文件操作

mainwindow下

7.1mainwindow与wiget

mainwindow 多一个菜单栏

7.2文件读取

//对话框
#include <QMessageBox>
构造函数{
    //链接 槽函数
    //点击打开 发出信号 发出点击信号triggered 槽函数openActionSlot执行
    connect(ui->openAction_O, &QAction::triggered, this, &MainWindow::openActionSlot);
}
//读取指定文件并显示
void MainWindow::openActionSlot(){
    //getOpenFileName弹出文件选择对话框
    //返回 选择的文件路径 取消对话框后 返回Empty
    //(父类对象, 对话框标题, 设置当前默认路径, 显示可执行文件)
    //QCoreApplication::applicationFilePath()获取程序执行的当前文件路径
    QString fileName = QFileDialog::getOpenFileName(this, "选择一个文件",
        QCoreApplication::applicationFilePath(), "*.cpp");

    if(fileName.isEmpty()){
        //未选择文件 返回值为空 弹出提示对话框
        QMessageBox::warning(this, "警告", "请选择一个文件");
    }else{
        //在终端打(3应用程序输出)印fileName
        qDebug() << fileName;

        //打开选中文件
        QFile file(fileName);     //创建文件对象
        file.open(QIODevice::ReadOnly);     //打开方式 只读
        QByteArray ba = file.readAll();     //一次读取所有 大文件推荐另一种方式
        ui->textEdit->setText(QString(ba));    //显示文件内容
        file.close();
    }

}

7.3新建文本

构造函数{
    //链接 槽函数
    //点击新建 发出信号 点击信号triggered 槽函数newActionSlot执行
    connect(ui->newAction_N, &QAction::triggered, this, &MainWindow::newActionSlot);
}
//新建文本
void MainWindow::newActionSlot(){
    //清空textEdit数据
    ui->textEdit->clear();
    this->setWindowTitle("新建文本文档.txt");
}

7.4文本另存为

构造函数{
    //保存文件 发出点击信号triggered 槽函数saveActionSlot执行
    connect(ui->saveAction_S, &QAction::triggered, this, &MainWindow::saveActionSlot);
}
//文件另存为(与打开指定文件类似)
void MainWindow::saveActionSlot(){
    //getSaveFileName(父类对象, 对话框标题, 设置默认路径, 显示可执行文件(不填为全文件))
    QString fileName = QFileDialog::getSaveFileName(this, "选择存储位置",
        QCoreApplication::applicationFilePath());
    if(fileName.isEmpty()){
        //未选择文件 返回值为空 弹出提示对话框
        QMessageBox::warning(this, "警告", "取消存储");
    }else{
        QFile file(fileName);
        file.open(QIODevice::WriteOnly);    //打开方式 只写
        QString temp = ui->textEdit->toPlainText();        //读取文件内容
        QByteArray ba;
        ba.append(temp.toUtf8());   //字符串转ByteArray
        file.write(ba);
        file.close();
    }
}

7.5 ctrl s保存 (键盘事件)

应用消息事件 中的 键盘事件


//消息事件 头文件
#include <QKeyEvent>        //键盘事件头文件
#include <QMouseEvent>      //鼠标事件头文件
class MainWindow ... {
    ...
public:
    //重写虚函数 键盘事件
    void keyPressEvent(QKeyEvent* k);
    //鼠标事件
    void mousePressEvent(QMouseEvent *m);
    ...
}

//ctrl s保存修改后的文件到源文件
//重写qobject消息事件 - 键盘事件keyPressEvent
void MainWindow::keyPressEvent(QKeyEvent* k){
    //判断热键ctrl 、 s
    //宏定义Key_S == S   宏定义ControlModifier == ctrl
    if(k->modifiers() == Qt::ControlModifier && k->key() == Qt::Key_S){
        if(fileName.isEmpty()){
            saveActionSlot();
        }else{
            //修改文件后保存到源文件
            QFile file(fileName);
            file. open (QIODevice::ReadWrite | QIODevice::Text);
            //获取textEdit中的内容
            QString content = ui->textEdit->toPlainText();
            QByteArray ba = content.toUtf8();
            file.write(ba);
            //提示成功
            QMessageBox::warning(this,"修改文件提示","文件修改成功!");
            //存储修改的新数据
            fileContent = content;
            file. close ();

            //修改窗口标题
            setWindowTitle(winTitle);
        }
    }
}

8、qt实现tcp通信

暂时只实现了,客户端连接服务端

8.1介绍

linux中 Qt TCP网络
服务器:socket(创建) -> bind(绑定) -> listen(监听) -> accept(接受客服端连接) -> recv/send(接受/发送) -> close(断开连接)
客户端:socket(创建) -> connect(向服务器发起连接) -> send/recv(发送/接受) -> close(断开连接)

qt封装了面向对象接口

补:Qt UDP网络
服务器:socked(创建) -> bind(绑定) -> ewcvfrom() -> sendto() -> close(关闭套接字)
客户端:socket() -> sendto() -> recvfrom() -> close()

8.2 qt 客户端

.pro工程文件中
#qt与网络相关的项目以及mysql项目 都需要在工程文件中加network库
QT       += core gui network

//添加 qt网络库
#include <QTcpSocket>
//包含ip、ip地址对象的头文件
#include <QHostAddress>

class Widget ... {
    ...
private:    
    QTcpSocket *socket;
    ...
};

构造函数{
    ...
    socket = new QTcpSocket;    //创建socket对象
}

//点击Button 客服端连接服务器
void Widget::on_connectButton_2_clicked()
{
    //1、获取IP地址和端口号
    QString IP = ui->ipLineEdit->text();
    QString port = ui->portLineEdit_2->text();

    //2、连接服务器
    //( QHostAddress主机地址, quint16端口号, )
    //port.toUShort()转为无符号的short == quint16
    socket->connectToHost(QHostAddress(IP), port.toUShort());

    //3、连接服务器成功,socket对象会发出信号
    //(socket发出信号, 发出connected连接信号, 匿名函数处理)
    connect(socket, &QTcpSocket::connected, [this](){
        //(父类对象, 对话框标题, 对话框内容)
        QMessageBox::information(this, "连接提示", "连接服务器成功");
    });

    //4、连接异常、断开 socket会发出信号
    connect(socket, &QTcpSocket::disconnected, [this](){
        //(父类对象, 警告框标题, 警告框内容)
        QMessageBox::warning(this, "连接提示", "连接异常,网络断开");
    });
}

8.3 服务器

本地电脑做服务器需要:关闭vpn(clash...)、防火墙

.pro工程文件中
#qt与网络相关的项目以及mysql项目 都需要在工程文件中加network库
QT       += core gui network

//TCP服务器专用 头文件
#include <QTcpServer>
//客户端 头文件
#include <QTcpSocket>
//包含ip、ip地址对象的头文件
#include <QHostAddress>

class Widget ... {
private:    
    //创建服务器对象
    QTcpServer *server;
};

构造函数{
    //创建TcpServer服务器对象
    server = new QTcpServer;

    //监听 (网卡, 端口号)
    //电脑只有一个网卡
    //QHostAddress::AnyIPv4 获取电脑任意的IPv4地址
    server->listen(QHostAddress::AnyIPv4, 7777);

    //当客服端对服务器发起连接 server对象会发出信号
    //(server对象会发出信号, 发出新建连接信号newConnection, Widget处理, Widget处理执行槽函数)
    connect(server, &QTcpServer::newConnection, this, &Widget::newClientHandler);;
}

//处理接连的槽函数
void Widget::newClientHandler(){
    //建立tcp连接 服务器向客服端建立连接
    QTcpSocket *socket = server->nextPendingConnection();
    QHostAddress ip = socket->peerAddress();      //获取客户端的地址
    quint16 port = socket->peerPort();         //获取客服端的端口号

    ui->ipLineEdit->setText(ip.toString());
    ui->portLineEdit_2->setText(QString::number(port));


}

9、客服端与服务器通信

界面文件(右击) -> 添加新文件 -> Qt -> 设计师界面类 ->选择合适界面模板 -> 设置类(类名、头文件.h、源文件.cpp、界面文件.ui、路径)

9.1客户端 + 新建聊天窗口

继续使用10、11项目

//1、新建Chat窗口文件(chat.h、 chat.cpp、 chat.ui)
//2、搭建chat.ui
//3、配置chat类
class Chat ... {
public:
    explicit Chat(QTcpSocket *s, QWidget *parent = nullptr);
private slots:
    void on_clearButton_clicked();
    void on_pushButton_2_clicked();

private:
    QTcpSocket *socket;
    ...
}
构造函数{
    //将连接成功的socket传入chat类
    socket = s;
}
//4、编写槽函数
void Chat::on_clearButton_clicked()
{
    //功能, 取消发送
    ui->lineEdit->clear();
}


void Chat::on_pushButton_2_clicked()
{
    //获取lineEdit输入的数据
    QByteArray ba;
    QString data = ui->lineEdit->text();
    ba.append(data.toUtf8());    //将QString转换为QByteArray
    //发送数据
    socket->write(ba);
}

//4、继续编写 8中客户端连接服务器成功后 socket发出信号
connect(socket, &QTcpSocket::disconnected, [this](){
    //(父类对象, 警告框标题, 警告框内容)
    QMessageBox::warning(this, "连接提示", "连接异常,网络断开");
    //隐藏主窗口
    this->hide();
    
    //启动新窗口
    Chat *c = new Chat(socket);
    c->show();
});

9.2 服务器接受消息

//接 8中 服务器与客户端建立TCP连接后的槽函数
void Widget::newClientHandler(){
    //建立tcp连接 服务器向客服端建立连接
    QTcpSocket *socket = server->nextPendingConnection();
    QHostAddress ip = socket->peerAddress();      //获取客户端的地址
    quint16 port = socket->peerPort();         //获取客服端的端口号

    ui->ipLineEdit->setText(ip.toString());
    ui->portLineEdit_2->setText(QString::number(port));

    //当服务器收到客户端发送的信息,socket发出readyread信号
    //(tcp连接发出信号, )
    connect(socket, &QTcpSocket::readyRead, this, &Widget::clienInfoslot);

}
//readyread信号 对应执行的槽函数
void Widget::clienInfoslot(){
    //在槽函数中使用sender可以获取谁发出的信号
    //获取信号的发出者
    QTcpSocket *s = (QTcpSocket *)sender();

    //用QBateArray构造QString对象
    QString data(s->readAll());

    ui->textEdit->setText(data);
}

10、多线程

继续使用11项目

线程:Qt封装了QThread (继承Qobject) 线程类

服务器 (线程只需要在服务器使用):

//1、添加线程类
项目目录下(新建) -> c/c++ -> c++ class -> 命名类(myThread), 继承QObject

//2、编写myThread.h
//继承线程类
class myThread : public QThread
{
    //保证信号与槽的运行
    Q_OBJECT
public:
    explicit myThread(QTcpSocket *s);
    //继承自QThread的虚函数 run
    void run();    //线程处理函数

signals:

public slots:
    void clientInfoSlot();

private:
    QTcpSocket *socket;
};

//3、myThread.cpp
myThread::myThread(QTcpSocket *s)
{
    socket = s;
}

void myThread::run(){
    //服务器 线程处理客户端发出的信号
    //绑定客户端发送数据的信号与槽
    connect(socket, &QTcpSocket::readyRead, this, &myThread::clientInfoSlot);
}

void myThread::clientInfoSlot(){
    //不能在其它类中操作别的界面
    //读取数据
    qDebug() << socket->readAll();
}
//4、在widget.cpp 新建连接信号newConnectio对应的槽函数中
void Widget::newClientHandler(){
    //建立tcp连接 服务器向客服端建立连接
    QTcpSocket *socket = server->nextPendingConnection();
    QHostAddress ip = socket->peerAddress();      //获取客户端的地址
    quint16 port = socket->peerPort();         //获取客服端的端口号

    ui->ipLineEdit->setText(ip.toString());
    ui->portLineEdit_2->setText(QString::number(port));
    //当服务器收到客户端发送的信息,socket发出readyread信号
    //(tcp连接发出信号, 准备读信号readyRead, 服务器处理, 执行对应槽函数)
    //connect(socket, &QTcpSocket::readyRead, this, &Widget::clienInfoslot);
    
    //启动线程 传入连接的服务器对象
    myThread *t = new myThread(socket);     //创建线程对象
    t->start();     //开始线程
}

11、自定义信号

继续使用11项目

关键字 emit

//1、在myThread.h中自定义信号
class mythread ... {
    ...
signals:
    //信号也是以函数的形式存在
    //自定义信号
    void sendToWidget(QByteArray b);
...
}

//2、mythread.cpp 绑定的槽函数发出自定义信号
//线程处理客户端发出的信号 处理对应的槽函数clientInfoSlot
void myThread::clientInfoSlot(){
    //读取数据
    QByteArray ba = socket->readAll();

    //自定义信号 利用信号发送数据 到widget
    //关键字 emit 发送信号
    emit sendToWidget(ba);

}

//3、widget.cpp 建立连接的槽函数中
//发出新建连接信号newConnection 槽函数newClientHandler处理
void Widget::newClientHandler(){
    //建立tcp连接 服务器向客服端建立连接
    QTcpSocket *socket = server->nextPendingConnection();
    QHostAddress ip = socket->peerAddress();      //获取客户端的地址
    quint16 port = socket->peerPort();         //获取客服端的端口号

    ui->ipLineEdit->setText(ip.toString());
    ui->portLineEdit_2->setText(QString::number(port));

    //当服务器收到客户端发送的信息,socket发出readyread信号
    //(tcp连接发出信号, 准备读信号readyRead, 服务器处理, 执行对应槽函数)
    //connect(socket, &QTcpSocket::readyRead, this, &Widget::clienInfoslot);

    //启动线程 传入连接的服务器对象
    myThread *t = new myThread(socket);     //创建线程对象
    t->start();     //开始线程

    //绑定 自定义信号与槽
    //(myThread发出信号, 发出自定义信号sendToWidget, widget处理, 对应处理的槽函数)
    connect(t, &myThread::sendToWidget, this, &Widget::threadSlot);
}
//自定义信号sendToWidget 对应的槽函数threadSlot (在widget.h的slots中声明)
void Widget::threadSlot(QByteArray b){
    //显示信号带来的数据
    ui->textEdit->setText(QString(b));  //QString使用QByteArray构造对象
}

12、Qt连接MySql

12.1 qtcreator安装mysql驱动

1、使用Qt Maintenance Tool安装source(用于获取cmake的编译源文件)
2、在没有空格的根文件下建立临时 编译驱动文件夹
3、拷贝...qt/6.6.2/Src下的qtbase整个文件到临时文件 的子目录下
 .../temp/q/qtbase
4、拷贝 安装的mysql目录下的include 和lib整个文件到临时文件 的子目录下
 .../temp/s/include
  .../temp/s/lib
5、用QtCreator打开...\q\qtbase\src\plugins\sqldrivers\CMakeLists.txt 并构建项目 (编译器自动项目取名 QSQLiteDriverPlugins)
6、编辑项目QSQLiteDriverPlugins\CMake Modules下的.cmake.conf
添加:
SET(FEATURE_sql_mysql ON)
//填的是拷贝到临时目录的 mysql的include文件夹
SET(MySQL_INCLUDE_DIR "D:/Microsoft-Edge_Store/aaa/s/include")
//填的是拷贝到临时目录的 mysql的lib 下的libmysql.lib文件
SET(MySQL_LIBRARY "D:/Microsoft-Edge_Store/aaa/s/lib/libmysql.lib")
7、编译 且在...\temp\q\qtbase\src\plugins\sqldrivers\build 下产生Desktop_Qt_6_6_2_MinGW_64_bit文件
8、拷贝 ...Desktop_Qt_6_6_2_MinGW_64_bit\plugins\sqldrivers的两个文件
    qsqlmysql.debug
    qsqlmysql.dll
   拷贝到电脑安装的...\Qt..\6.6.2\mingw_64\plugins\sqldrivers下
9、拷贝 安装MySQL的...\mysql\Sql_Server\lib下的两个文件
    libmysql.dll
    libmysql.lib
   拷贝到 ...\Qt..\6.6.2\mingw_64\bin下  即可完成
   
提示:
最好自己编译mysql驱动文件,不同qt版本必须使用同版本的mysql驱动

12.2 使用mysql

//1、初始化
.pro工程文件中
#qt与网络相关的项目以及mysql项目 都需要在工程文件中加network库
QT       += core gui sql

//数据库对象头文件
#include <QSqlDatabase>
//执行sql语句的类
#include <QSqlQuery>
#include <QSqlError>
//消息对话框
#include <QMessageBox>
//在头文件中 给Widget类添加成员
QSqlDatabase db;

//2、连接数据库
构造函数中{
    ...
    //连接数据库
    //加载数据库驱动(返回数据库对象)
    db = QSqlDatabase::addDatabase("QMYSQL");     //加载mysql数据库驱动

    db.setDatabaseName("myqtdatabase");     //设置加载数据库的 名称
    db.setPort(3306);
    db.setHostName("localhost");        //设置连接数据库的ip地址 本地localhost
    db.setUserName("root");     //设置连接数据库的用户名
    db.setPassword("root");     //设置连接数据库的密码

    //打开数据库
    if(db.open()){
        QMessageBox::information(this, "连接提示", "连接成功");
    }else{
        QMessageBox::warning(this, "错误", "连接失败");
        qDebug() << db.lastError().text();
    }
}

//3、在数据库中插入数据
void Widget::on_insertButton_clicked()
{
    QString id = ui->idLineEdit->text();
    QString name = ui->nameLineEdit_2->text();
    QString birth = ui->birLineEdit_3->text();

    //插入数据 的sql语句
    //类似c的 %d
    //.arg(id).arg(name).arg(birth) 分别替换 %1 %2 %3
    QString sql = QString("insert into student value (%1, '%2', '%3');").arg(id).arg(name).arg(birth);

    //执行sql语句的类
    QSqlQuery query;
    if(query.exec(sql)){
        QMessageBox::information(this, "插入提示", "插入成功");
    }else{
        QMessageBox::warning(this, "插入提示", "插入失败");
    }
}

//4、查询数据库数据
void Widget::on_findButton_2_clicked()
{
    QSqlQuery query;
    //查询数据 的sql
    //查询数据的结果保存在QSqlQuery对象中
    query.exec("select * from student;");

    //query.next()获得一条数据
    while(query.next()){
        //query.value(0)为数据库一条数据的 id
        //query.value(1)为数据库一条数据的 name
        qDebug() << query.value(0);
        qDebug() << query.value(1);
        qDebug() << query.value(2);
    }
}

12.3 mysql创建用户

#1、登录
mysql -u root -p
password: root

#2、创建用户
#test1用户名 %代表所有电脑都可登录 by设置密码
create user "test1"@"%" identified by "test1";

#3、授予权限
grant select, insert, create on *.* to "test1"@"%";

12.4 控件Table View 对数据库增、删、改、查

//1、初始化
.pro工程文件中
#qt与网络相关的项目以及mysql项目 都需要在工程文件中加network库
QT       += core gui sql

//数据库对象头文件
#include <QSqlDatabase>
#include <QMessageBox>
//创建sql显示 模型对象
#include <QSqlTableModel>
#include <QSqlError>
//widget类中
widget ... {
    ...    
    QSqlTableModel *m;
}

//2、tableView控件操作
构造函数中{
    //连接mysql
    QSqlDatabase db;
    //加载数据库驱动(返回数据库对象)
    db = QSqlDatabase::addDatabase("QMYSQL");

    db.setDatabaseName("myqtdatabase");     //设置加载数据库的 名称
    // db.setPort(3306);
    db.setHostName("localhost");        //设置连接数据库的ip地址 本地localhost
    db.setUserName("root");     //设置连接数据库的用户名
    db.setPassword("root");     //设置连接数据库的密码

    //打开数据库
    if(db.open()){
        QMessageBox::information(this, "连接提示", "连接成功");

        //初始化sql显示 模型
        m = new QSqlTableModel;
        //将数据模型与 数据库的表关联
        m->setTable("student");
        //将ui界面中的tableView控件 与QSqlTableModel结合
        ui->tableView->setModel(m);
    }else{
        QMessageBox::warning(this, "错误", "连接失败");
        qDebug() << db.lastError().text();
    }
}

//3、显示数据
void Widget::on_pushButton_clicked()
{
    //查询操作1、得到具体数据并显示
    // QSqlQuery query;
    //查询数据 的sql
    //查询数据的结果保存在QSqlQuery对象中
    // query.exec("select * from student;");

    //query.next()获得一条数据
    // while(query.next()){
    //     //query.value(0)为数据库一条数据的 id
    //     //query.value(1)为数据库一条数据的 name
    //     qDebug() << query.value(0);
    //     qDebug() << query.value(1);
    //     qDebug() << query.value(2);
    // }

    //查询数据2、利用tableView控件 与mysql关联 显示数据
    //显示数据到ui
    m->select();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值