2023-12-05 Qt学习总结 (AI辅助)


点击 <C 语言编程核心突破> 快速C语言入门



前言

要解决问题: 学习qt最核心知识, 多一个都不学.


一 Qt是什么

Qt是一个跨平台的GUI应用程序开发框架,提供了丰富的GUI组件库和工具,支持C++编程语言。

Qt可以用于开发桌面应用程序、嵌入式系统、移动设备和Web应用程序等各种应用场景。

Qt的特点是易用、高效、灵活、跨平台、可扩展性好等。

官网连接: https://www.qt.io/

另外Qt的开源政策也比较值得关注, 有人戏称"开源刺客", 使用时要注意, 开源协议并不是免费的代名词.

二 Qt开发工具链

Qt开发工具链包括如下几个方面:

  1. Qt Creator:是Qt官方推荐的集成开发环境(IDE),用于开发Qt应用程序。它提供了丰富的自动化工具和调试支持,包括代码编辑,编译器,调试器,可视化设计工具等。
    qtcreator

  2. Qt Designer:是一个Qt应用程序界面设计工具,可以快速创建出美观的GUI界面。它提供了图形化的界面编辑器,支持拖放式的界面设计,可以预览和调整界面的布局和外观。
    Designer

  3. Qt Linguist:是Qt的国际化工具,用于将Qt应用程序翻译成多种不同的语言。它提供了一个简单而直观的界面,可以轻松地添加、编辑和维护翻译文件,包括.po(GNU Gettext)和.ts(Qt翻译)文件。

  4. Qt Assistant:是一个Qt文档工具,用于帮助开发者查找和浏览Qt文档。它提供了一份完整的Qt文档,并支持基于关键字或类名的搜索和查找。
    Assistant

  5. Qt Test:是一个Qt测试框架,可以帮助开发者编写和运行单元测试和集成测试。它提供了一些基本的测试工具,包括测试驱动程序、测试用例、测试报告、测试运行器等。

  6. 为了生成最终的可执行文件, 需要配置C++编译器, 可以是gcc, mingw64, mscv, clang. 同时需要使用CMake.
    在这里插入图片描述

三 Qt编程涉及的术语和名词

以下是一些 Qt 编程中常用的术语和名词:

  1. QObjects: Qt 中的所有对象都是 QObject 的子类。

  2. Signals and Slots:信号和槽是 Qt 中最重要的一种事件通信机制,允许在不同的对象之间进行通信。

  3. Widgets:Qt 中的 UI 组件,包括按钮、文本框、标签等等。

  4. Layouts:Qt 中用于管理窗口布局的类。

  5. Main Window:Qt 应用程序中的主窗口。

  6. QML:Qt Quick Markup Language,一种用户界面描述语言,用于在 Qt 中创建动态 UI。

  7. Model/View Programming:Qt 中一种用于管理数据和 UI 显示的编程模式。

  8. QPainter:绘图引擎,用于在 widget 上绘制图形。

  9. QThread:Qt 中的线程类,用于创建并管理线程。

  10. Qt Designer:Qt 中的图形界面设计器,用于可视化设计 UI。

四 Qt Creator使用

Qt Creator 用于创建Qt软件。以下是一些使用Qt Creator的步骤:

  1. 安装Qt Creator:

我是用msys2资源管理工具安装的, 基于clang64版本, 同时安装clang tool chain, qt6, 具体方法比较简单, 不再赘述.

安装完成后,打开Qt Creator。

  1. 创建一个新项目:
    在这里插入图片描述
    选择您要创建的应用类型(如控制台应用程序或窗口应用程序)。
    在这里插入图片描述
    设置项目名称和路径,然后单击“下一步”。
    在这里插入图片描述

  2. 配置项目:在这一步中,您可以选择构建设置
    在这里插入图片描述
    基类类型
    在这里插入图片描述
    语言
    在这里插入图片描述
    构建套件
    在这里插入图片描述
    汇总确认, 单击“完成”以创建新项目。
    在这里插入图片描述

  3. 编写代码:在Qt Creator中,您可以使用代码编辑器编写代码。选择您想要编辑的文件,然后开始编写代码。
    在这里插入图片描述

  4. 构建和运行项目:构建项目时,Qt Creator会自动生成可执行文件。也可以通过Qt Creator提供的调试工具来调试程序。
    在这里插入图片描述

  5. 调试:在Qt Creator中,您可以使用调试器调试程序。单击“调试”菜单,然后选择“调试器”。在调试器中,您可以设置断点、查看变量和堆栈跟踪等。
    在这里插入图片描述

  6. 完成:完成项目后,您可以导出可执行文件或创建安装程序。单击“构建”菜单,然后选择“构建设置”。在“构建设置”中,您可以选择要导出的文件类型和位置。
    在这里插入图片描述
    使用Qt提供的windeployqt工具自动复制依赖文件,并生成可执行文件。
    先将生成的可执行文件复制到一个文件夹, 如E:\clangC++\learnQT\Learn_10_export
    然后运行windeployqt自动复制依赖:

C:\Users\Lhb>cd E:\clangC++\learnQT\Learn_10_export
C:\Users\Lhb>E:
E:\clangC++\learnQT\Learn_10_export>windeployqt6 Learn_10.exe
E:\clangC++\learnQT\Learn_10_export\Learn_10.exe 64 bit, release executable
Adding Qt6Network for qtuiotouchplugin.dll
Adding Qt6Svg for qsvgicon.dll

在这里插入图片描述

五 Hello Qt!

现在我们已经有了一个空窗口工程, 传统上, 我们要实现一个"Hello Qt !"的程序,

双击Widget.ui, 进入设计界面
在这里插入图片描述
鼠标右键点击Label不要松手, 拖入右边的界面中
在这里插入图片描述
双击TextLabel, 改成Hello Qt !,
在这里插入图片描述
鼠标右键Hello Qt !, 点击改变格式文本, 更改文字的字号,大小.
在这里插入图片描述
更改字体: 点击Hello Qt !在属性中点击font字体, 调整字体.
在这里插入图片描述
运行程序:

在这里插入图片描述
效果:
在这里插入图片描述
恭喜你, 写了第一个Qt程序.

六 Qt控件和事件

Qt的控件可以分为基本控件和高级控件两种类型,其中基本控件包括按钮、标签、文本框、进度条等常用控件,

高级控件包括表格、树形控件、列表、对话框等更加复杂的控件。

在这里插入图片描述

通过这些控件的组合和设置属性,我们可以实现我们所需的用户界面。

Qt的事件机制允许我们在用户交互时捕捉到相应的事件,如按钮被单击、鼠标移动、键盘按下等。

在这里插入图片描述

我们可以通过重载控件的事件处理函数来处理这些事件,例如QPushButton的clicked()信号就是当用户单击该按钮时触发的事件。

在这里插入图片描述

Qt的控件和事件机制为我们设计和实现用户界面提供了强大的支持,使得我们可以轻松地实现复杂的图形化交互应用程序。

七 Qt信号和槽

Qt信号和槽是一种重要的机制,用于在对象之间进行通信。

它们是Qt框架中最强大的特性之一。

信号是一种事件,当发生某些特定的情况时,对象发射信号。

例如,当用户单击按钮或窗口关闭时,对象会发射相应的信号。

槽是一种方法,当一个信号发射时,与之相关联的槽将被调用。

槽可以执行任何操作,例如更改部件属性、计算数据等等。

一个对象可以有多个信号和槽,它们可以相互连接。

通过使用信号和槽,Qt提供了一种非常方便的方法来实现事件处理和通信。

它可以减少代码的重复性,使程序更加模块化和易于维护。

使用信号和槽需要遵循以下步骤:

  1. 定义信号:在类中声明信号,以便对象可以发射它。

  2. 定义槽:在类中声明槽,以便当信号被发射时可以调用它.

在这里插入图片描述
3. 连接信号和槽:使用QObject::connect()函数连接信号和槽。

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

    // 链接信号与槽 谁发出信号 发出什么信号 谁处理信号 怎么处理
    connect(ui->CancelButton, &QPushButton::clicked, this,
            &Widget::on_CancelButton_clicked);
}

以下是一个简单的示例代码:

Widget.h, 除了pushButton_clicked()函数, 其余的基本自动给出

#ifndef WIDGET_H
#define WIDGET_H

#include <QMessageBox>
#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui
{
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

  public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

  private slots:
    void pushButton_clicked();

  private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

main.cpp, 全部自动给出

#include "Widget.h"

#include <QApplication>
#include <QLocale>
#include <QTranslator>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QTranslator translator;
    const QStringList uiLanguages = QLocale::system().uiLanguages();
    for (const QString &locale : uiLanguages) {
        const QString baseName = "Learn_10_" + QLocale(locale).name();
        if (translator.load(":/i18n/" + baseName)) {
            a.installTranslator(&translator);
            break;
        }
    }
    Widget w;
    w.show();
    return a.exec();
}

Widget.cpp , 除了自己实现pushButton_clicked(), 以及连接clicked信号与pushButton_clicked槽函数, 其余自动给出

#include "Widget.h"
#include "./ui_Widget.h"

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

    // button发出clicked信号, widget接收到信号, 运行pushButton_clicked
    connect(ui->pushButton, &QAbstractButton::clicked, this,
            &Widget::pushButton_clicked);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::pushButton_clicked()
{
    QMessageBox::information(this, "信息", "按钮被点击");
}

Learn_10_zh_CN.ts, 全部自动给出

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="zh_CN"></TS>

ui_Widget.h, 拖控件, 改字体, 其余全部自动给出.

/********************************************************************************
** Form generated from reading UI file 'Widget.ui'
**
** Created by: Qt User Interface Compiler version 6.5.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef UI_WIDGET_H
#define UI_WIDGET_H

#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QLabel>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_Widget
{
public:
    QWidget *widget;
    QVBoxLayout *verticalLayout;
    QLabel *label;
    QPushButton *pushButton;

    void setupUi(QWidget *Widget)
    {
        if (Widget->objectName().isEmpty())
            Widget->setObjectName("Widget");
        Widget->resize(271, 126);
        widget = new QWidget(Widget);
        widget->setObjectName("widget");
        widget->setGeometry(QRect(20, 10, 227, 107));
        verticalLayout = new QVBoxLayout(widget);
        verticalLayout->setObjectName("verticalLayout");
        verticalLayout->setContentsMargins(0, 0, 0, 0);
        label = new QLabel(widget);
        label->setObjectName("label");
        QFont font;
        font.setFamilies({QString::fromUtf8("\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B")});
        font.setBold(true);
        label->setFont(font);

        verticalLayout->addWidget(label);

        pushButton = new QPushButton(widget);
        pushButton->setObjectName("pushButton");
        QFont font1;
        font1.setFamilies({QString::fromUtf8("\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B")});
        font1.setPointSize(14);
        font1.setBold(true);
        pushButton->setFont(font1);

        verticalLayout->addWidget(pushButton);


        retranslateUi(Widget);

        QMetaObject::connectSlotsByName(Widget);
    } // setupUi

    void retranslateUi(QWidget *Widget)
    {
        Widget->setWindowTitle(QCoreApplication::translate("Widget", "Widget", nullptr));
        label->setText(QCoreApplication::translate("Widget", "<html><head/><body><p><span style=\" font-size:36pt; font-weight:700;\">Hello QT !</span></p></body></html>", nullptr));
        pushButton->setText(QCoreApplication::translate("Widget", "PushButton", nullptr));
    } // retranslateUi

};

namespace Ui {
    class Widget: public Ui_Widget {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_WIDGET_H

以上代码基本都是Qtcreator的框架自动给出的, 真正需要我们编写的只是UI部分(拖动控件改个名字)和信号与槽连接的部分, 及槽函数, 看着很多, 其实如果熟悉流程, 不会超过五分钟.

运行效果:
在这里插入图片描述
在这里插入图片描述

总之,信号和槽是Qt的核心特性之一,使得对象之间的通信变得非常简单。在编写Qt应用程序时,通常需要使用信号和槽机制来实现事件处理和数据通信。

八 Qt自定义信号和槽

Qt提供了一些常见的信号和槽, 如按钮的clicked()信号和QTimertimeout()信号,但有时你需要定义自己的信号和槽。

以下是定义自定义信号和槽的步骤:

  1. 定义信号:在类中声明一个信号,可以理解为一个函数声明,但没有实现。

注意,使用自定义信号和槽时,必须在类定义中包含Q_OBJECT宏,并且该类必须是QObject的子类。

#ifndef MYCLASS_H
#define MYCLASS_H

#include <QDebug>
#include <QObject>

class MyClass : public QObject
{
    Q_OBJECT
  public:
    explicit MyClass(QObject *parent = nullptr);
    void myMethod();

  signals:
    void mySignal(int);

  public slots:
    void mySlot();
};

#endif // MYCLASS_H
  1. 激发信号:在类的某个方法中使用emit关键字来激发该信号。
void MyClass::myMethod()
{
    int value = 1000;
    emit mySignal(value);
}
  1. 定义槽:在类中声明一个槽,可以理解为一个函数,必须在类外有定义, 且为public, 否则无法调用。
void MyClass::mySlot()
{
    qDebug() << "mySlot:";
}

  1. 连接信号和槽:在应用程序的合适位置使用connect()方法来连接信号和槽。

连接一个信号和槽,使得当信号激发时,槽函数将被自动调用。

这种connet()的方法是将信号放在SIGNAL这个宏中, 宏将函数扩展为字符串"mySignal(int)", 注意, 对于含有参数的信号, 其格式要求是函数名(形参类型), mySignal(int)

对于槽函数则放在SLOT宏中, 也会将函数扩展为字符串, 函数格式要求与信号一致.

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

    myc = new MyClass;
    myt = new QTimer;

    // 谁, 发出信号, 谁, 接收信号做什么
    connect(myc, SIGNAL(mySignal(int)), myt, SLOT(start(int)));
    connect(myt, SIGNAL(timeout()), myc, SLOT(mySlot()));
}

  1. 设计一个按钮pushbutton, 按下调用myMethod()函数, 设计一个stop按钮, 按下调用Qtimer的stop()函数.

void Widget::on_pushButton_clicked()
{
    this->myc->myMethod();
}

void Widget::on_stopButton_clicked()
{
    this->myt->stop();
}

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

在上面的例子中,当按下pushbutton时, mySignal信号被激发,接着QTimerstart()方法将被调用,而在QTimer超时时,mySlot方法将被调用, 输出 "mySlot"

当按下stop按钮时, 计时器中断, 不再调用mySlot().

使用自定义信号和槽可以使Qt应用程序更加灵活和可扩展,因为你可以定义和连接任何你需要的信号和槽,以实现特定的功能和交互。

九 QObject基类

QObject是Qt中最基本的类,所有Qt中的对象都从该基类派生而来。

QObject提供了信号槽机制和属性系统,使得Qt应用程序可以实现高效的事件处理和内置的类型转换。

QObject是一个C++类,同时也是Qt元对象系统的重要概念。

QObject还可以自定义事件和事件过滤器,使得开发者可以轻松地编写和组织复杂的应用程序。

使用QObject作为基类,可以使得派生类成为一个Qt对象,从而能够利用Qt的信号槽机制、事件处理机制和属性系统,为应用程序提供更灵活、更可靠的架构支持。

以下是QObject的常用函数:

  1. QObject::QObject(QObject *parent = nullptr) 构造函数,创建一个QObject对象。

  2. QObject::~QObject() 析构函数,销毁QObject对象。

  3. void QObject::setObjectName(const QString &name) 设置对象的名称。

  4. QString QObject::objectName() const 返回对象的名称。

  5. void QObject::setProperty(const char *name, const QVariant &value) 设置对象的属性。

  6. QVariant QObject::property(const char *name) const 返回对象的属性。

  7. bool QObject::connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection) 连接一个信号与槽函数。

  8. bool QObject::disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method) 断开一个信号与槽的连接。

  9. void QObject::deleteLater() 在事件循环中删除对象。

  10. QObjectList QObject::children() const 返回子对象的列表。

  11. bool QObject::event(QEvent *event) 处理事件。

  12. bool QObject::eventFilter(QObject *watched, QEvent *event) 过滤事件。

  13. QThread *QObject::thread() const 返回对象所属的线程。

  14. bool QObject::blockSignals(bool block) 阻止或取消阻止这个对象的所有信号。

  15. bool QObject::signalsBlocked() const 返回是否阻止了这个对象的所有信号。

  16. void QObject::dumpObjectInfo() 输出对象信息。

  17. void QObject::dumpObjectTree() 输出对象树形结构。

十 QWidget基类

QWidget是Qt中所有用户界面类的基类,它提供了一个空白的窗口部件,可以作为其他窗口部件的父类。

QWidget提供了很多基本的函数和信号,包括绘制、布局、尺寸调整、事件处理等。

QWidget还支持嵌套,可以将多个QWidget嵌套在一起形成复杂的界面。

除了QWidget,Qt还提供了一些其他的窗口部件类,例如QMainWindowQDialog等。

这些窗口部件类都是从QWidget派生而来,因此它们都可以使用QWidget提供的函数和信号。

但是这些窗口部件类还提供了一些特殊的功能,例如菜单栏、工具栏、状态栏等,可以方便开发者快速构建各种类型的用户界面。

下面是QWidget基类常用的函数:

  1. QWidget():构造函数,创建一个基本的QWidget对象;

  2. virtual ~QWidget():虚析构函数,释放QWidget对象;

  3. void setWindowTitle(const QString& title):设置窗口标题;

  4. void setWindowIcon(const QIcon& icon):设置窗口图标;

  5. void resize(int w, int h):设置窗口大小;

  6. void setFixedSize(int w, int h):设置窗口固定大小;

  7. void move(int x, int y):移动窗口到给定的位置;

  8. void show():显示窗口;

  9. void hide():隐藏窗口;

  10. void close():关闭窗口;

  11. void setCursor(const QCursor& cursor):设置光标;

  12. QWidget* parentWidget() const:返回父窗口;

  13. void setLayout(QLayout *layout):设置布局管理器;

  14. QLayout* layout() const:返回当前布局管理器;

  15. void setStyleSheet(const QString& styleSheet):设置样式表;

  16. void setWindowFlags(Qt::WindowFlags type):设置窗口标识。

十一 QMainWindow类

QMainWindow是Qt应用程序中最常用的窗口类型之一。

它提供了一个完整的应用程序主窗口的基础, 可以包含菜单栏、工具栏、状态栏和中央窗口部件等。

QMainWindow类继承自QWidget类, 它提供了许多方法和信号来简化应用程序的开发和管理。

可以使用它的方法来管理菜单栏、工具栏和状态栏的内容,以及中央窗口部件的位置和大小等。

QMainWindow类常用函数:

  1. QMainWindow(QWidget * parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags()) 构造函数。

  2. void setCentralWidget(QWidget * widget) 设置窗口的中间部件。

  3. QMenuBar* menuBar() const 返回窗口的菜单栏部件。

  4. QToolBar* addToolBar(const QString & title) 添加工具栏部件。

  5. QStatusBar *statusBar() const 返回窗口的状态栏部件。

  6. void setStatusBar(QStatusBar * statusbar) 设置窗口的状态栏部件。

  7. void addDockWidget(Qt::DockWidgetArea area, QDockWidget * dockwidget) 添加可停靠的窗口部件。

  8. QWidget* centralWidget() const 返回窗口的中间部件。

  9. QList<QDockWidget *> dockWidgets() 返回窗口中所有的可停靠的窗口部件。

  10. Qt::ToolBarArea toolBarArea(QToolBar * toolbar) const 返回工具栏部件的停靠区域。

  11. void removeDockWidget(QDockWidget * dockwidget) 删除可停靠的窗口部件。

  12. QWidget * takeCentralWidget() 取走窗口的中间部件并将其返回。

  13. void setCorner(Qt::Corner corner, Qt::DockWidgetArea area) 设置可停靠的窗口部件的角落。

  14. void setDockOptions(QMainWindow::DockOptions options) 设置可停靠的窗口部件的选项。

十二 QLabel文本框

Qt的QLabel文本框是一个用于显示文本或图像的控件。它是Qt中常用的一种控件,可用于在GUI中显示静态文本、图像或HTML文本。

一些常用的QLabel函数包括:

  1. setText():设置QLabel中显示的文本或HTML文本内容。

  2. setPixmap():设置QLabel中显示的图像。

  3. setAlignment():设置QLabel中文本或图像的对齐方式。

  4. setWordWrap():设置QLabel是否自动换行。

  5. setStyleSheet():设置QLabelCSS样式。

  6. setToolTip():设置QLabel的提示信息。

  7. setTextFormat():设置QLabel显示文本的格式。

  8. clear():清除QLabel显示的内容。

通过拖拽建立一个Label
在这里插入图片描述
可以设置字体, 颜色, 图片等等.
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

十三 QPushButton按钮

QPushButton是Qt中的一个控件类,用于创建一个可点击的按钮。其常用函数有:

  1. setText() 设置按钮的文本

  2. clicked() 按钮被点击时触发的信号

  3. setIcon() 设置按钮的图标

  4. setEnabled() 设置按钮是否可用

  5. setToolTip() 设置鼠标悬停在按钮上时显示的提示文本

  6. setShortcut() 设置按钮的快捷键

  7. setFixedSize() 设置按钮的大小

  8. setDefault() 将按钮设置为默认按钮

  9. setAutoDefault() 设置按钮是否自动变为默认按钮

  10. setCheckable() 设置按钮是否可选

  11. isChecked() 查询按钮是否被选中

  12. setFlat() 设置按钮是否为扁平化样式

  13. setMenu() 设置按钮的菜单

  14. animateClick() 模拟按钮的点击事件,可以用于程序自动化测试等场景。

通过拖拽建立一个Qbutton

在这里插入图片描述
可以通过信号槽机制完成一些操作, 比如弹出一个提示框:
在这里插入图片描述

十四 QLineEdit单行输入框

QLineEdit是一个单行输入框,允许用户输入或编辑单行文本,可以用于获取用户输入,例如用户名、密码等。

QLineEdit类继承自QFrame,可以设置背景色、边框等样式属性,同时还有多种信号和槽可供使用。

常用函数如下:

  1. setText(str)设置QLineEdit中的文本

  2. text()获取QLineEdit中的文本

  3. setPlaceholderText(str)设置QLineEdit的占位符文本

  4. setReadOnly(bool)设置QLineEdit是否只读

  5. setMaxLength(int)设置QLineEdit的最大输入长度

  6. setValidator(QValidator)设置QLineEdit的输入校验器

  7. setAlignment(Qt.AlignmentFlag)设置QLineEdit中文本的对齐方式

  8. clear()清空QLineEdit中的输入内容

  9. selectAll()选中QLineEdit中的所有文本

  10. setFocus()将焦点设置到QLineEdit中

  11. cursorPosition()获取光标在QLineEdit中的位置

  12. setCursorPosition(int)设置光标在QLineEdit中的位置

拖拽出一个LineEdit输入框
在这里插入图片描述
可更改字体, 颜色等, 通过信号槽机制, 完成某些任务

在这里插入图片描述

十五 QListWidget列表框

QListWidget是Qt中的一个重要控件,它可以用于显示一列相关的项目,并允许用户通过单击选择项目。

QListWidget可以以多种模式(例如列表视图或图标视图)显示项目,并可以自定义每个项目的外观和数据。

常用函数:

  1. addItem() 向列表框中添加一个新项目;

  2. count() 返回列表框中项目的数量;

  3. currentItem() 返回当前选中的项目;

  4. currentRow() 返回当前选中项目的行号;

  5. setCurrentItem() 设置当前选中的项目;

  6. setCurrentRow() 设置当前选中项目的行号;

  7. item() 返回指定行号的项目;

  8. itemAt() 返回指定坐标的项目;

  9. takeItem() 移除指定行号的项目;

  10. clear() 清除所有项目。

拖拽一个ListWidget
在这里插入图片描述
双击, 进行编辑, 设置选框
在这里插入图片描述
添加PushButton利用信号和槽机制, 进行处理

获取项目列表项目数量, 遍历列表, 统计勾选的数量, 输出信息.

void Widget::on_pushButton_clicked()
{
    int count = ui->listWidget->count();
    int res = 0;
    for (int var = 0; var < count; ++var)
    {
        if (ui->listWidget->item(var)->checkState() == Qt::Checked)
        {
            res++;
        }
    }
    QMessageBox::information(this, "提示",
                             QString("你太厉害了!\n任务共%1项\n你完成了%2项")
                                 .arg(ui->listWidget->count())
                                 .arg(res));
}

在这里插入图片描述

十六 QTableWidget表格控件

QTableWidget是Qt中用于显示表格的控件,类似于Excel中的表格。

它可以用来显示、编辑和操作一组数据,可以手动添加、删除和修改单元格内容。

常用函数:

  1. setRowCount(int rows) 设置表格的行数。

  2. setColumnCount(int columns) 设置表格的列数。

  3. setItem(int row, int column, QTableWidgetItem* item) 设置单元格的内容,rowcolumn是行列索引,itemQTableWidgetItem类型的指针。

  4. item(int row, int column) 获取给定行列位置的单元格的内容。

  5. selectedItems() 返回所有被选中的单元格。

  6. currentRow() 返回当前选中单元格的行号。

  7. currentColumn() 返回当前选中单元格的列号。

  8. setHorizontalHeaderItem(int column, QTableWidgetItem* item) 设置水平表头的内容,itemQTableWidgetItem类型的指针。

  9. setVerticalHeaderItem(int row, QTableWidgetItem* item) 设置垂直表头的内容,itemQTableWidgetItem类型的指针。

  10. setEditTriggers(QAbstractItemView::EditTrigger triggers) 设置表格中哪些操作触发编辑单元格,EditTrigger是一个枚举类型。

  11. setSelectionMode(QAbstractItemView::SelectionMode mode) 设置表格选择模式,SelectionMode是一个枚举类型。

  12. itemSelectionChanged() 当用户选中新的单元格时,触发此信号。

  13. cellClicked(int row, int column) 单元格被点击时触发此信号。

  14. clear() 清除所有单元格内容。

  15. setSortingEnabled(bool enable) 启用或禁用表格的排序功能。

  16. sortItems(int column, Qt::SortOrder order) 根据指定列的内容对表格进行排序。

  17. horizontalHeaderItem(int column) 返回指定列的水平表头项。

  18. verticalHeaderItem(int row) 返回指定行的垂直表头项。

拖拽生成一个Table Widget,
在这里插入图片描述
双击设置行列, 项目内容
在这里插入图片描述
在这里插入图片描述
插入QButton并使用信号和槽机制进行通信, 遍历表格, 统计选中人数, 并给出信息.

void Widget::on_pushButton_clicked()
{
    int count = ui->tableWidget->rowCount();
    int res = 0;
    for (int var = 0; var < count; ++var)
    {
        if (ui->tableWidget->item(var, 0)->checkState() == Qt::Checked)
        {
            res++;
        }
    }
    QMessageBox::information(
        this, "提示",
        QString("表格中共有%1个人, 有%2个人被选中").arg(count).arg(res));
}

在这里插入图片描述

十七 QTreeWidget树形控件

QTreeWidget是Qt中提供的一个树形控件,用于展示具有分层结构数据的控件。

以下是一些常用的C++函数:

  1. setHeaderLabels() 设置树形控件的列标签

  2. setColumnCount() 设置列数

  3. setColumnWidth() 设置列宽

  4. setSortingEnabled() 启用或禁用排序

  5. setCurrentItem() 设置当前项

  6. currentItem() 获取当前项

  7. topLevelItem() 获取顶层项

  8. takeTopLevelItem() 移除顶层项

  9. addTopLevelItem() 添加顶层项

  10. clear() 清除所有项

  11. selectedItems() 获取所有选择项

此外,还有许多其他的函数可以设置树形控件的样式、行为、数据等。

需要根据具体的需求进行选择和使用。

拖拽建立一个树:
在这里插入图片描述
建立一个PushButtton, 利用信号和槽机制, 打印顶级条目数, 次级条目数, 被选中的次级条目数:

void Widget::on_pushButton_clicked()
{
    int topCount = ui->treeWidget->topLevelItemCount();
    qDebug() << "顶级条目数" << topCount;
    int checkedCount = 0;

    for (int var = 0; var < topCount; ++var)
    {
        int childcnt = ui->treeWidget->topLevelItem(var)->childCount();
        qDebug() << "顶级条目" << var << "下条目数" << childcnt;

        for (int varB = 0; varB < childcnt; ++varB)
        {
            if (ui->treeWidget->topLevelItem(var)->child(varB)->checkState(0) ==
                Qt::Checked)
            {
                checkedCount++;
            }
        }
    }
    qDebug() << "被选择的次级条目共有" << checkedCount << "个";
}

在这里插入图片描述

十八 QMessageBox消息对话框

QMessageBox消息对话框是Qt中的一个提供用户交互界面的对话框窗口。

它通常用于在程序中弹出提示框或警告框。

用户可以通过它来选择是或否、确定或取消等选项。

QMessageBox可以显示文本信息、图标和按钮。

常用的QMessageBox函数有:

  1. QMessageBox::about(QWidget *parent, const QString &title, const QString &text):显示一个包含文本和"OK"按钮的对话框,用于显示有关应用程序的信息。

  2. QMessageBox::warning(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons = QMessageBox::Ok, QMessageBox::StandardButton defaultButton = QMessageBox::NoButton):显示一个包含警告图标、文本和按钮的对话框,询问用户是否要继续操作。

  3. QMessageBox::information(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons = QMessageBox::Ok, QMessageBox::StandardButton defaultButton = QMessageBox::NoButton):显示一个包含信息图标、文本和按钮的对话框。

  4. QMessageBox::question(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons = QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::StandardButton defaultButton = QMessageBox::NoButton):显示一个包含一个有两个按钮的图标和文本的对话框。

  5. QMessageBox::critical(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons = QMessageBox::Ok, QMessageBox::StandardButton defaultButton = QMessageBox::NoButton):显示一个包含错误图标、文本和按钮的对话框。

这些函数中,除了必须提供的参数外,还可以指定按钮和默认按钮的样式。

注意:以上函数的参数都是可选的,您可以选择适合您的情况的参数来使用。

通过pushbutton按钮以及信号和槽机制, 弹出一个QMessageBox, 这个在我们以前的示例中已经频繁使用.

在这里插入图片描述

十九 Qt布局管理

Qt布局管理是一种自动化的方式来管理和调整控件的排列和大小,以适应不同的窗口大小和分辨率。

Qt提供了多种布局管理类,如QHBoxLayout、QVBoxLayout、QGridLayout等,它们分别适用于不同的布局方式和场景。

QHBoxLayoutQVBoxLayout是最常用的布局管理类,它们用于水平和垂直布局,

它们都只需要指定一个父控件,然后添加需要放置的子控件,即可自动排列和调整子控件的大小。

除了水平和垂直布局外,QGridLayout也是一种常用的布局管理方式,它允许将控件按照行和列的方式排列

此外,Qt还提供了其他一些布局管理类,如QFormLayout, 适用于表单布局场景。

总之,Qt布局管理提供了一种灵活、高效、自适应的控件排列和调整方式,可以有效提高界面开发的效率和可靠性。

以下是它们的常用函数:

QHBoxLayout

  1. QHBoxLayout(QWidget *parent = Q_NULLPTR):构造函数,创建一个水平布局管理器。

  2. addWidget(QWidget *widget, int stretch = 0, Qt::Alignment alignment = Qt::Alignment()):添加控件到布局管理器中, stretch参数表示控件在布局中的拉伸因子,alignment参数表示控件在布局中的对齐方式。

  3. setSpacing(int spacing):设置控件之间的间距。

  4. setMargin(int margin):设置布局管理器与父部件之间的边距。

QVBoxLayout

  1. QVBoxLayout(QWidget *parent = Q_NULLPTR):构造函数,创建一个垂直布局管理器。

  2. addWidget(QWidget *widget, int stretch = 0, Qt::Alignment alignment = Qt::Alignment()):添加控件到布局管理器中,stretch参数表示控件在布局中的拉伸因子,alignment参数表示控件在布局中的对齐方式。

  3. setSpacing(int spacing):设置控件之间的间距。

  4. setMargin(int margin):设置布局管理器与父部件之间的边距。

QGridLayout

  1. QGridLayout(QWidget *parent = Q_NULLPTR):构造函数,创建一个网格布局管理器。

  2. addWidget(QWidget *widget, int row, int column, int rowSpan = 1, int columnSpan = 1, Qt::Alignment alignment = Qt::Alignment()):添加控件到布局管理器中,row和column参数表示控件所在的行和列,rowSpan和columnSpan参数表示控件跨越的行数和列数,alignment参数表示控件在布局中的对齐方式。

  3. setSpacing(int spacing):设置控件之间的间距。

  4. setMargin(int margin):设置布局管理器与父部件之间的边距。

拖入3个button,
在这里插入图片描述
使用垂直布局:
在这里插入图片描述
使用水平布局:
在这里插入图片描述

表单布局:
在这里插入图片描述

网络布局:
在这里插入图片描述

二十 QTcpSocket QTcpServer网络库

QTcpSocketQTcpServer网络库是QT框架提供的网络编程库之一,用于实现TCP协议的网络通信。

下面是QTcpSocketQTcpServer网络库中常用的C++函数:

QTcpSocket常用函数:

  1. QTcpSocket(QObject *parent = nullptr):构造函数。
  2. void connectToHost(const QString &hostName, quint16 port):连接到指定的主机名和端口。
  3. void disconnectFromHost():断开与主机的连接。
  4. qint64 write(const char *data, qint64 maxSize):将数据写入套接字。
  5. QByteArray read(qint64 maxSize):从套接字中读取数据。
  6. bool waitForReadyRead(int msecs):等待套接字有可读数据的信号。
  7. bool waitForConnected(int msecs):等待套接字成功连接到主机的信号。
  8. void flush():将写入缓冲区的数据刷新到套接字。

QTcpServer常用函数:

  1. QTcpServer(QObject *parent = nullptr):构造函数。
  2. bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0):开始监听指定的地址和端口。
  3. void close():关闭套接字,停止监听。
  4. bool isListening() const:判断是否正在监听。
  5. QTcpSocket *nextPendingConnection():获取下一个挂起的连接。
  6. qintptr socketDescriptor() const:获取套接字的描述符。

以上是常用的QTcpSocketQTcpServer网络库C++函数,其他函数可参考QT官方文档。

示例:

在这里插入图片描述
在这里插入图片描述
关闭客户端, 再开启客户端连接, 发送信息
在这里插入图片描述

在这里插入图片描述

服务端代码:

Widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QTcpServer>
#include <QTcpSocket>
#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui
{
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

  public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

  private slots:
    void on_cancelButton_clicked();

    void on_sendButton_clicked();

  public slots:
    void connectHandler();
    void reciveText();

  private:
    Ui::Widget *ui;
    QTcpServer *qtServer;
    QTcpSocket *qtSocket;
};
#endif // WIDGET_H

main.cpp

#include "Widget.h"

#include <QApplication>
#include <QLocale>
#include <QTranslator>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QTranslator translator;
    const QStringList uiLanguages = QLocale::system().uiLanguages();
    for (const QString &locale : uiLanguages) {
        const QString baseName = "Learn_18_" + QLocale(locale).name();
        if (translator.load(":/i18n/" + baseName)) {
            a.installTranslator(&translator);
            break;
        }
    }
    Widget w;
    w.show();
    return a.exec();
}

Widget.cpp

#include "Widget.h"
#include "./ui_Widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
    , qtServer(new QTcpServer)
    , qtSocket(nullptr)
{
    ui->setupUi(this);
    qtServer->listen(QHostAddress::AnyIPv4, 8000);
    connect(qtServer, SIGNAL(newConnection()), this, SLOT(connectHandler()));
}

Widget::~Widget()
{
    delete ui;
    qtServer->close();
    if (qtSocket != nullptr)
    {
        qtSocket->close();
    }
}

void Widget::on_cancelButton_clicked()
{
    this->close();
}

void Widget::connectHandler()
{
    if (qtSocket != nullptr)
    {
        qtSocket->disconnect();
        qtSocket->disconnectFromHost();
        qtSocket->close();
    }
    qtSocket = qtServer->nextPendingConnection();
    ui->ipLineEdit->setText(qtSocket->peerAddress().toString());
    ui->portLineEdit->setText(QString::number(qtSocket->peerPort()));
    connect(qtSocket, SIGNAL(readyRead()), this, SLOT(reciveText()));
    connect(qtSocket, &QTcpSocket::disconnected,
            [this]() { qDebug() << "Disconnected"; });
}

void Widget::reciveText()
{
    ui->reciveLineEdit->setText(QString(qtSocket->readAll()));
}

void Widget::on_sendButton_clicked()
{
    if (qtSocket->isValid())
    {
        qtSocket->write(ui->sendLineEdit->text().toUtf8());
    }
    else
    {
        qDebug() << "unconnect";
    }
}

ui_Widget.h

/********************************************************************************
** Form generated from reading UI file 'Widget.ui'
**
** Created by: Qt User Interface Compiler version 6.5.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef UI_WIDGET_H
#define UI_WIDGET_H

#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QFormLayout>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_Widget
{
public:
    QLabel *label_5;
    QWidget *widget;
    QFormLayout *formLayout;
    QLabel *label;
    QLineEdit *ipLineEdit;
    QLabel *label_2;
    QLineEdit *portLineEdit;
    QLabel *label_3;
    QLineEdit *reciveLineEdit;
    QLabel *label_4;
    QLineEdit *sendLineEdit;
    QWidget *widget1;
    QHBoxLayout *horizontalLayout;
    QPushButton *sendButton;
    QPushButton *cancelButton;

    void setupUi(QWidget *Widget)
    {
        if (Widget->objectName().isEmpty())
            Widget->setObjectName("Widget");
        Widget->resize(482, 419);
        label_5 = new QLabel(Widget);
        label_5->setObjectName("label_5");
        label_5->setGeometry(QRect(190, 20, 92, 50));
        label_5->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));
        widget = new QWidget(Widget);
        widget->setObjectName("widget");
        widget->setGeometry(QRect(10, 90, 461, 220));
        formLayout = new QFormLayout(widget);
        formLayout->setObjectName("formLayout");
        formLayout->setContentsMargins(0, 0, 0, 0);
        label = new QLabel(widget);
        label->setObjectName("label");
        label->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(0, QFormLayout::LabelRole, label);

        ipLineEdit = new QLineEdit(widget);
        ipLineEdit->setObjectName("ipLineEdit");
        ipLineEdit->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(0, QFormLayout::FieldRole, ipLineEdit);

        label_2 = new QLabel(widget);
        label_2->setObjectName("label_2");
        label_2->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(1, QFormLayout::LabelRole, label_2);

        portLineEdit = new QLineEdit(widget);
        portLineEdit->setObjectName("portLineEdit");
        portLineEdit->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(1, QFormLayout::FieldRole, portLineEdit);

        label_3 = new QLabel(widget);
        label_3->setObjectName("label_3");
        label_3->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(2, QFormLayout::LabelRole, label_3);

        reciveLineEdit = new QLineEdit(widget);
        reciveLineEdit->setObjectName("reciveLineEdit");
        reciveLineEdit->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(2, QFormLayout::FieldRole, reciveLineEdit);

        label_4 = new QLabel(widget);
        label_4->setObjectName("label_4");
        label_4->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(3, QFormLayout::LabelRole, label_4);

        sendLineEdit = new QLineEdit(widget);
        sendLineEdit->setObjectName("sendLineEdit");
        sendLineEdit->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(3, QFormLayout::FieldRole, sendLineEdit);

        widget1 = new QWidget(Widget);
        widget1->setObjectName("widget1");
        widget1->setGeometry(QRect(10, 330, 461, 54));
        horizontalLayout = new QHBoxLayout(widget1);
        horizontalLayout->setObjectName("horizontalLayout");
        horizontalLayout->setContentsMargins(0, 0, 0, 0);
        sendButton = new QPushButton(widget1);
        sendButton->setObjectName("sendButton");
        sendButton->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout->addWidget(sendButton);

        cancelButton = new QPushButton(widget1);
        cancelButton->setObjectName("cancelButton");
        cancelButton->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout->addWidget(cancelButton);


        retranslateUi(Widget);

        QMetaObject::connectSlotsByName(Widget);
    } // setupUi

    void retranslateUi(QWidget *Widget)
    {
        Widget->setWindowTitle(QCoreApplication::translate("Widget", "Widget", nullptr));
        label_5->setText(QCoreApplication::translate("Widget", "\346\234\215\345\212\241\347\253\257", nullptr));
        label->setText(QCoreApplication::translate("Widget", "IP\345\234\260\345\235\200", nullptr));
        label_2->setText(QCoreApplication::translate("Widget", "\347\253\257\345\217\243\345\217\267", nullptr));
        label_3->setText(QCoreApplication::translate("Widget", "\346\224\266  \346\226\207", nullptr));
        label_4->setText(QCoreApplication::translate("Widget", "\345\217\221  \346\226\207", nullptr));
        sendButton->setText(QCoreApplication::translate("Widget", "\345\217\221\351\200\201", nullptr));
        cancelButton->setText(QCoreApplication::translate("Widget", "\345\217\226\346\266\210", nullptr));
    } // retranslateUi

};

namespace Ui {
    class Widget: public Ui_Widget {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_WIDGET_H

客户端代码

Widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QTcpSocket>
#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui
{
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

  public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

  private slots:
    void on_linkButton_clicked();

    void on_sendButton_clicked();

    void on_cancelButton_clicked();

  public slots:
    void recieveText();

  private:
    Ui::Widget *ui;
    QTcpSocket *socket;
};
#endif // WIDGET_H

main.cpp

#include "Widget.h"

#include <QApplication>
#include <QLocale>
#include <QTranslator>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QTranslator translator;
    const QStringList uiLanguages = QLocale::system().uiLanguages();
    for (const QString &locale : uiLanguages) {
        const QString baseName = "Learn_19_" + QLocale(locale).name();
        if (translator.load(":/i18n/" + baseName)) {
            a.installTranslator(&translator);
            break;
        }
    }
    Widget w;
    w.show();
    return a.exec();
}

Widget.cpp

#include "Widget.h"
#include "./ui_Widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
    , socket(new QTcpSocket)
{
    ui->setupUi(this);
    connect(socket, &QTcpSocket::connected, [this]() { qDebug() << "OK"; });
    connect(socket, SIGNAL(readyRead()), this, SLOT(recieveText()));
    connect(socket, &QTcpSocket::disconnected,
            [this]() { qDebug() << "Disconnected"; });
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_linkButton_clicked()
{
    // socket->disconnect();
    QString ipAdd(ui->ipLineEdit->text());
    socket->connectToHost(QHostAddress(ipAdd),
                          ui->portLineEdit->text().toUShort());
}

void Widget::on_sendButton_clicked()
{
    if (socket->isValid())
    {
        socket->write(ui->sendLineEdit->text().toUtf8());
    }
}

void Widget::on_cancelButton_clicked()
{
    this->close();
}

void Widget::recieveText()
{
    QString res = QString::fromUtf8(socket->readAll());
    ui->recieveLineEdit->setText(res);
    qDebug() << res;
}

ui_Widget.h

/********************************************************************************
** Form generated from reading UI file 'Widget.ui'
**
** Created by: Qt User Interface Compiler version 6.5.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef UI_WIDGET_H
#define UI_WIDGET_H

#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QFormLayout>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_Widget
{
public:
    QLabel *label_5;
    QWidget *layoutWidget;
    QFormLayout *formLayout;
    QLabel *label;
    QLineEdit *ipLineEdit;
    QLabel *label_2;
    QLineEdit *portLineEdit;
    QLabel *label_3;
    QLineEdit *sendLineEdit;
    QLabel *label_4;
    QLineEdit *recieveLineEdit;
    QWidget *layoutWidget1;
    QHBoxLayout *horizontalLayout;
    QPushButton *linkButton;
    QPushButton *sendButton;
    QPushButton *cancelButton;

    void setupUi(QWidget *Widget)
    {
        if (Widget->objectName().isEmpty())
            Widget->setObjectName("Widget");
        Widget->resize(555, 400);
        label_5 = new QLabel(Widget);
        label_5->setObjectName("label_5");
        label_5->setGeometry(QRect(220, 10, 101, 50));
        label_5->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));
        layoutWidget = new QWidget(Widget);
        layoutWidget->setObjectName("layoutWidget");
        layoutWidget->setGeometry(QRect(10, 80, 541, 220));
        formLayout = new QFormLayout(layoutWidget);
        formLayout->setObjectName("formLayout");
        formLayout->setContentsMargins(0, 0, 0, 0);
        label = new QLabel(layoutWidget);
        label->setObjectName("label");
        label->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(0, QFormLayout::LabelRole, label);

        ipLineEdit = new QLineEdit(layoutWidget);
        ipLineEdit->setObjectName("ipLineEdit");
        ipLineEdit->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(0, QFormLayout::FieldRole, ipLineEdit);

        label_2 = new QLabel(layoutWidget);
        label_2->setObjectName("label_2");
        label_2->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(1, QFormLayout::LabelRole, label_2);

        portLineEdit = new QLineEdit(layoutWidget);
        portLineEdit->setObjectName("portLineEdit");
        portLineEdit->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(1, QFormLayout::FieldRole, portLineEdit);

        label_3 = new QLabel(layoutWidget);
        label_3->setObjectName("label_3");
        label_3->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(2, QFormLayout::LabelRole, label_3);

        sendLineEdit = new QLineEdit(layoutWidget);
        sendLineEdit->setObjectName("sendLineEdit");
        sendLineEdit->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(2, QFormLayout::FieldRole, sendLineEdit);

        label_4 = new QLabel(layoutWidget);
        label_4->setObjectName("label_4");
        label_4->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(3, QFormLayout::LabelRole, label_4);

        recieveLineEdit = new QLineEdit(layoutWidget);
        recieveLineEdit->setObjectName("recieveLineEdit");
        recieveLineEdit->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(3, QFormLayout::FieldRole, recieveLineEdit);

        layoutWidget1 = new QWidget(Widget);
        layoutWidget1->setObjectName("layoutWidget1");
        layoutWidget1->setGeometry(QRect(10, 330, 531, 54));
        horizontalLayout = new QHBoxLayout(layoutWidget1);
        horizontalLayout->setObjectName("horizontalLayout");
        horizontalLayout->setContentsMargins(0, 0, 0, 0);
        linkButton = new QPushButton(layoutWidget1);
        linkButton->setObjectName("linkButton");
        linkButton->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout->addWidget(linkButton);

        sendButton = new QPushButton(layoutWidget1);
        sendButton->setObjectName("sendButton");
        sendButton->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout->addWidget(sendButton);

        cancelButton = new QPushButton(layoutWidget1);
        cancelButton->setObjectName("cancelButton");
        cancelButton->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout->addWidget(cancelButton);


        retranslateUi(Widget);

        QMetaObject::connectSlotsByName(Widget);
    } // setupUi

    void retranslateUi(QWidget *Widget)
    {
        Widget->setWindowTitle(QCoreApplication::translate("Widget", "Widget", nullptr));
        label_5->setText(QCoreApplication::translate("Widget", "\345\256\242\346\210\267\347\253\257", nullptr));
        label->setText(QCoreApplication::translate("Widget", "IP", nullptr));
        ipLineEdit->setText(QCoreApplication::translate("Widget", "127.0.0.1", nullptr));
        label_2->setText(QCoreApplication::translate("Widget", "\347\253\257\345\217\243", nullptr));
        portLineEdit->setText(QCoreApplication::translate("Widget", "8000", nullptr));
        label_3->setText(QCoreApplication::translate("Widget", "\345\217\221\351\200\201", nullptr));
        label_4->setText(QCoreApplication::translate("Widget", "\346\216\245\346\224\266", nullptr));
        linkButton->setText(QCoreApplication::translate("Widget", "\350\277\236\346\216\245", nullptr));
        sendButton->setText(QCoreApplication::translate("Widget", "\345\217\221\351\200\201", nullptr));
        cancelButton->setText(QCoreApplication::translate("Widget", "\345\217\226\346\266\210", nullptr));
    } // retranslateUi

};

namespace Ui {
    class Widget: public Ui_Widget {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_WIDGET_H

通常在建立qt项目时, 不会自动链接Network头文件及库文件, 需要在cmake文件中加入:

find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Network)
target_link_libraries(Learn_18 PRIVATE Qt${QT_VERSION_MAJOR}::Network)

其中Learn_18是项目名, 根据你的项目更改.

二十一 QProcess进程类

QProcess是一个进程管理类,它允许您启动外部程序和与它们通信。

QProcess支持同步和异步启动,也可以使用管道和I / O重定向向子进程发送和接收数据。

下面是常用函数列表:

  1. QProcess(const QStringList &arguments = QStringList(), QObject *parent = nullptr) 该函数可以创建一个用于启动外部程序的QProcess对象,可以设置启动参数。

  2. setProgram(QString program) 设置要启动的程序或可执行文件的路径。

  3. setArguments(const QStringList &arguments) 设置启动参数列表。

  4. setWorkingDirectory(QString dir) 设置运行外部程序的工作目录。

  5. start(const QString &program, const QStringList &arguments = {}, OpenMode mode = ReadWrite); 启动外部程序。

  6. waitForStarted(int msecs = 30000) 等待外部程序启动,返回true表示启动成功,false表示启动失败。

  7. waitForFinished(int msecs = 30000) 等待外部程序执行完成,返回true表示执行完成,false表示超时或执行失败。

  8. readAllStandardOutput() 读取外部程序的标准输出,返回一个QByteArray

  9. readAllStandardError() 读取外部程序的标准错误输出,返回一个QByteArray

  10. void write(const QByteArray &byteArray) 向外部程序的标准输入写入数据。

您还可以使用QIODevice API通过管道与子进程通信。

常见的用法是通过标准输入输出管道或错误输出管道发送和接收数据。

您还可以使用readAllStandardOutput()readAllStandardError()函数来获取进程的输出和错误输出。

在非Windows平台上,QProcess使用QAbstractEventDispatcher来监视子进程。

使用QProcess的事件循环时,如果有进程事件到达,将调用QProcess的虚拟函数来处理该事件。

如果使用waitForStarted()waitForFinished()之类的功能等待进程,则QProcess将在事件循环内等待进程事件的到来。

Windows上,QProcess使用WaitHandle实现进程监视,并且可以兼容在Windows上使用其他Qt的进程相关类。

示例:
用进程类实现一个应用, 当点击run, 从命令和参数文本框获取命令文本, 并启动进程, 将结果返回到结果文本框中.
在这里插入图片描述
Widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QProcess>
#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui
{
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

  public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

  private slots:
    void on_runButton_clicked();

  private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

main.cpp

#include "Widget.h"

#include <QApplication>
#include <QLocale>
#include <QTranslator>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QTranslator translator;
    const QStringList uiLanguages = QLocale::system().uiLanguages();
    for (const QString &locale : uiLanguages) {
        const QString baseName = "Learn_20_" + QLocale(locale).name();
        if (translator.load(":/i18n/" + baseName)) {
            a.installTranslator(&translator);
            break;
        }
    }
    Widget w;
    w.show();
    return a.exec();
}

Widget.cpp

#include "Widget.h"
#include "./ui_Widget.h"

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

Widget::~Widget()
{
    delete ui;
}

void Widget::on_runButton_clicked()
{
    QProcess process(this);
    QStringList qsl;
    qsl << ui->optionLineEdit->text();

    process.start(ui->commendLineEdit->text(), qsl);

    if (process.waitForStarted() && process.waitForFinished())
    {
        qDebug() << "OK";
    }

    QByteArray output = process.readAllStandardOutput();

    ui->resultTextEdit->setText(QString::fromLocal8Bit(output));

    qDebug() << QString::fromLocal8Bit(output);
}

ui_Widget.h

/********************************************************************************
** Form generated from reading UI file 'Widget.ui'
**
** Created by: Qt User Interface Compiler version 6.5.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef UI_WIDGET_H
#define UI_WIDGET_H

#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QFormLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QTextEdit>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_Widget
{
public:
    QPushButton *runButton;
    QTextEdit *resultTextEdit;
    QWidget *layoutWidget;
    QFormLayout *formLayout;
    QLabel *label;
    QLabel *label_2;
    QLineEdit *commendLineEdit;
    QLineEdit *optionLineEdit;

    void setupUi(QWidget *Widget)
    {
        if (Widget->objectName().isEmpty())
            Widget->setObjectName("Widget");
        Widget->resize(508, 577);
        runButton = new QPushButton(Widget);
        runButton->setObjectName("runButton");
        runButton->setGeometry(QRect(10, 530, 81, 31));
        runButton->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));
        resultTextEdit = new QTextEdit(Widget);
        resultTextEdit->setObjectName("resultTextEdit");
        resultTextEdit->setGeometry(QRect(10, 90, 491, 421));
        layoutWidget = new QWidget(Widget);
        layoutWidget->setObjectName("layoutWidget");
        layoutWidget->setGeometry(QRect(10, 10, 491, 72));
        formLayout = new QFormLayout(layoutWidget);
        formLayout->setObjectName("formLayout");
        formLayout->setContentsMargins(0, 0, 0, 0);
        label = new QLabel(layoutWidget);
        label->setObjectName("label");
        label->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(0, QFormLayout::LabelRole, label);

        label_2 = new QLabel(layoutWidget);
        label_2->setObjectName("label_2");
        label_2->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(0, QFormLayout::FieldRole, label_2);

        commendLineEdit = new QLineEdit(layoutWidget);
        commendLineEdit->setObjectName("commendLineEdit");
        commendLineEdit->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(1, QFormLayout::LabelRole, commendLineEdit);

        optionLineEdit = new QLineEdit(layoutWidget);
        optionLineEdit->setObjectName("optionLineEdit");
        optionLineEdit->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(1, QFormLayout::FieldRole, optionLineEdit);


        retranslateUi(Widget);

        QMetaObject::connectSlotsByName(Widget);
    } // setupUi

    void retranslateUi(QWidget *Widget)
    {
        Widget->setWindowTitle(QCoreApplication::translate("Widget", "Widget", nullptr));
        runButton->setText(QCoreApplication::translate("Widget", "run", nullptr));
        label->setText(QCoreApplication::translate("Widget", "\345\221\275\344\273\244", nullptr));
        label_2->setText(QCoreApplication::translate("Widget", "\345\217\202\346\225\260", nullptr));
    } // retranslateUi

};

namespace Ui {
    class Widget: public Ui_Widget {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_WIDGET_H

二十二 QThread线程

QThread是Qt框架中的线程类,它提供了一个跨平台的线程类库,可以在Qt应用程序中实现多线程编程,实现并发执行任务的能力。

QThread类通过继承QThread并重载run()函数来实现自己的线程。

run()函数中包含了线程的逻辑代码,线程启动时会自动调用run()函数。

QThread还提供了一些常用的函数,如start()函数开始线程,quit()函数结束线程,wait()函数等待线程结束等。

常用函数:

start():启动线程,该函数将会调用run()函数;

sleep():暂停当前线程,单位毫秒;

quit():结束线程,类似于Thread类的Stop方法;

wait():等待当前线程执行完毕,阻塞当前线程;

finished():当线程执行结束时会发出该信号;

terminate():强制关闭线程,类似于Thread类的Abort方法。

C++示例:用线程返回相加结果, 并在主线程输出
在这里插入图片描述
我们实现一个myThread线程类, 继承自QThread, 当触发计算时, 调用槽函数, 生成线程, 线程运算相加结果, 并通过信号槽机制返回给主线程, 进行显示.

myThread.h

#ifndef MYTHREAD_H
#define MYTHREAD_H

#include <QThread>

class myThread : public QThread
{
    Q_OBJECT
  public:
    explicit myThread(QObject *parent = nullptr, int numA_ = 0, int numB_ = 0);
    void run() override;

  signals:
    void result(int);

  private:
    int numA;
    int numB;
};

#endif // MYTHREAD_H

myThread.cpp

#include "myThread.h"

myThread::myThread(QObject *parent, int numA_, int numB_)
    : QThread{parent}
    , numA(numA_)
    , numB(numB_)
{}

void myThread::run()
{
    emit result(numA + numB);
}

通过简单的封装, 可以很容易的将数据传给线程, 通过信号槽机制, 又很容易的可以将结果返回, 相比C或C++原生thread, 已经人性化的一塌糊度了.

当然, 效率问题不在本文探讨之列.

Widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui
{
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

  public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

  public slots:
    void getResult(int res);

  private slots:
    void on_pushButton_clicked();

  private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

Widget.cpp

#include "Widget.h"
#include "./ui_Widget.h"
#include "myThread.h"

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

Widget::~Widget()
{
    delete ui;
}

void Widget::on_pushButton_clicked()
{
    int numA = ui->lineEditA->text().toInt();
    int numB = ui->lineEditB->text().toInt();

    myThread *qthrd = new myThread(this, numA, numB);
    qthrd->start();

    connect(qthrd, SIGNAL(result(int)), this, SLOT(getResult(int)));

    qthrd->wait();

    qthrd->deleteLater();
}

void Widget::getResult(int res)
{
    ui->lineEditSum->setText(QString::number(res));
}

二十三 QSqlDatabase数据库

QSqlDatabase 是 Qt 框架中关于数据库的统一封装,它支持常见的数据库软件如 MySQL、SQLite、PostgreSQL 等。

在 Qt 中,使用 QSqlDatabase 对象与各种数据库建立连接,然后通过 QSqlQuery 对象进行查询和操作。

常用的 QSqlDatabase C++ 函数包括:

  1. QSqlDatabase::addDatabase() 用于添加一个数据库连接。

  2. QSqlDatabase::setDatabaseName() 设置连接的数据库名。

  3. QSqlDatabase::setUserName() 设置连接的用户名。

  4. QSqlDatabase::setPassword() 设置连接的密码。

  5. QSqlDatabase::setHostName() 设置连接的主机名。

  6. QSqlDatabase::setPort() 设置连接的端口号。

  7. QSqlDatabase::open() 打开数据库连接。

  8. QSqlDatabase::isOpen() 检查连接是否已经打开。

  9. QSqlDatabase::close() 关闭数据库连接。

  10. QSqlDatabase::exec() 执行指定的 SQL 语句。

  11. QSqlDatabase::lastError() 获取最后一次发生的错误。

  12. QSqlDatabase::commit() 提交当前数据库事务。

  13. QSqlDatabase::rollback() 回滚当前数据库事务。

  14. QSqlDatabase::transaction() 开启一个新的数据库事务。

  15. QSqlDatabase::tables() 获取当前数据库中所有表的列表。

  16. QSqlDatabase::record() 获取一个表的结构信息。

  17. QSqlDatabase::primaryIndex() 获取一个表的主键信息。

  18. QSqlDatabase::index() 获取一个表的索引信息。

  19. QSqlDatabase::prepare() 预编译一个 SQL 语句。

  20. QSqlDatabase::bindValue() 绑定一个值到预编译的 SQL 语句中。

这些函数都可以帮助我们完成在数据库中进行增删改查等操作。

示例:

使用数据库实现一个输入和查询界面:

第一步, 连接一个数据库, 数据库中是学生信息, 如学号, 姓名, 生日.

CREATE TABLE student(
    id integer UNSIGNED PRIMARY KEY,
    name varchar(16) NOT NULL,
    birth date
);

如果数据库连接成功,
在这里插入图片描述
开启一个界面, 如查询学生信息, 可按学号, 姓名, 生日查询
在这里插入图片描述
通过学号查询
在这里插入图片描述
添加学生信息:

在这里插入图片描述

在这里插入图片描述
查询全部:

在这里插入图片描述
源代码:
Widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QMessageBox>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui
{
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

  public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

  private slots:
    void on_addButton_clicked();

    void on_idButton_clicked();

    void on_nameButton_clicked();

    void on_birthdayButton_clicked();

  private:
    Ui::Widget *ui;
    QSqlDatabase qdb;
    QSqlQuery query;
};
#endif // WIDGET_H

main.cpp

#include "Widget.h"

#include <QApplication>
#include <QLocale>
#include <QTranslator>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QTranslator translator;
    const QStringList uiLanguages = QLocale::system().uiLanguages();
    for (const QString &locale : uiLanguages) {
        const QString baseName = "Learn_22_" + QLocale(locale).name();
        if (translator.load(":/i18n/" + baseName)) {
            a.installTranslator(&translator);
            break;
        }
    }
    Widget w;
    w.show();
    return a.exec();
}

Widget.h

#include "Widget.h"
#include "./ui_Widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    qdb = QSqlDatabase::addDatabase("QSQLITE");
    qdb.setDatabaseName("E:\\clangC++\\mydatabase.db");
    qdb.setHostName("localhost");
    qdb.setUserName("root");
    qdb.setPassword("root");
    if (!qdb.open())
    {
        QMessageBox::information(this, "提示", "链接失败");
    }
    else
    {
        QMessageBox::information(this, "提示", "链接成功");
        query = QSqlQuery(qdb);
    }
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_addButton_clicked()
{
    QString sql = QString("INSERT INTO student VALUES (%1, '%2', '%3');")
                      .arg(ui->addIdLineEdit->text())
                      .arg(ui->addNameLineEdit->text())
                      .arg(ui->addBirthdayLineEdit->text());
    if (query.exec(sql))
    {
        QMessageBox::information(this, "提示", "插入成功");
    }
    else
    {
        QMessageBox::information(this, "提示", "插入失败");
    }
}

void Widget::on_idButton_clicked()
{
    QString sql = QString("SELECT * FROM student WHERE id LIKE %1;")
                      .arg(ui->idLineEdit->text());
    QString result;
    if (query.exec(sql))
    {
        while (query.next())
        {
            result.append(query.value(0).toString());
            result += "\t|\t";
            result.append(query.value(1).toString());
            result += "\t|\t";
            result.append(query.value(2).toString());
            result += "\n";
        }
        ui->resultTextEdit->setText(result);
    }
    else
    {
        QMessageBox::information(this, "提示", "查询失败");
    }
}

void Widget::on_nameButton_clicked()
{
    QString sql = QString("SELECT * FROM student WHERE name LIKE %1;")
                      .arg(ui->idLineEdit->text());
    QString result;
    if (query.exec(sql))
    {
        while (query.next())
        {
            result.append(query.value(0).toString());
            result += "\t|\t";
            result.append(query.value(1).toString());
            result += "\t|\t";
            result.append(query.value(2).toString());
            result += "\n";
        }
        ui->resultTextEdit->setText(result);
    }
    else
    {
        QMessageBox::information(this, "提示", "查询失败");
    }
}

void Widget::on_birthdayButton_clicked()
{
    QString sql = QString("SELECT * FROM student WHERE birthday LIKE %1;")
                      .arg(ui->idLineEdit->text());
    QString result;
    if (query.exec(sql))
    {
        while (query.next())
        {
            result.append(query.value(0).toString());
            result += "\t|\t";
            result.append(query.value(1).toString());
            result += "\t|\t";
            result.append(query.value(2).toString());
            result += "\n";
        }
        ui->resultTextEdit->setText(result);
    }
    else
    {
        QMessageBox::information(this, "提示", "查询失败");
    }
}

ui_Widget.h

/********************************************************************************
** Form generated from reading UI file 'Widget.ui'
**
** Created by: Qt User Interface Compiler version 6.5.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef UI_WIDGET_H
#define UI_WIDGET_H

#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QTextEdit>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_Widget
{
public:
    QLabel *label;
    QTextEdit *resultTextEdit;
    QLabel *label_2;
    QPushButton *addButton;
    QWidget *widget;
    QHBoxLayout *horizontalLayout;
    QPushButton *idButton;
    QLineEdit *idLineEdit;
    QPushButton *nameButton;
    QLineEdit *nameLineEdit;
    QPushButton *birthdayButton;
    QLineEdit *birthdayLineEdit;
    QWidget *widget1;
    QHBoxLayout *horizontalLayout_2;
    QLabel *label_3;
    QLineEdit *addIdLineEdit;
    QLabel *label_4;
    QLineEdit *addNameLineEdit;
    QLabel *label_5;
    QLineEdit *addBirthdayLineEdit;

    void setupUi(QWidget *Widget)
    {
        if (Widget->objectName().isEmpty())
            Widget->setObjectName("Widget");
        Widget->resize(741, 407);
        label = new QLabel(Widget);
        label->setObjectName("label");
        label->setGeometry(QRect(280, 10, 151, 31));
        label->setStyleSheet(QString::fromUtf8("font: 700 18pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));
        resultTextEdit = new QTextEdit(Widget);
        resultTextEdit->setObjectName("resultTextEdit");
        resultTextEdit->setGeometry(QRect(10, 110, 721, 111));
        resultTextEdit->setStyleSheet(QString::fromUtf8("font: 700 14pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));
        label_2 = new QLabel(Widget);
        label_2->setObjectName("label_2");
        label_2->setGeometry(QRect(290, 240, 151, 31));
        label_2->setStyleSheet(QString::fromUtf8("font: 700 18pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));
        addButton = new QPushButton(Widget);
        addButton->setObjectName("addButton");
        addButton->setGeometry(QRect(320, 360, 75, 37));
        addButton->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));
        widget = new QWidget(Widget);
        widget->setObjectName("widget");
        widget->setGeometry(QRect(10, 50, 721, 39));
        horizontalLayout = new QHBoxLayout(widget);
        horizontalLayout->setObjectName("horizontalLayout");
        horizontalLayout->setContentsMargins(0, 0, 0, 0);
        idButton = new QPushButton(widget);
        idButton->setObjectName("idButton");
        idButton->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout->addWidget(idButton);

        idLineEdit = new QLineEdit(widget);
        idLineEdit->setObjectName("idLineEdit");
        idLineEdit->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout->addWidget(idLineEdit);

        nameButton = new QPushButton(widget);
        nameButton->setObjectName("nameButton");
        nameButton->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout->addWidget(nameButton);

        nameLineEdit = new QLineEdit(widget);
        nameLineEdit->setObjectName("nameLineEdit");
        nameLineEdit->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout->addWidget(nameLineEdit);

        birthdayButton = new QPushButton(widget);
        birthdayButton->setObjectName("birthdayButton");
        birthdayButton->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout->addWidget(birthdayButton);

        birthdayLineEdit = new QLineEdit(widget);
        birthdayLineEdit->setObjectName("birthdayLineEdit");
        birthdayLineEdit->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout->addWidget(birthdayLineEdit);

        widget1 = new QWidget(Widget);
        widget1->setObjectName("widget1");
        widget1->setGeometry(QRect(10, 290, 721, 37));
        horizontalLayout_2 = new QHBoxLayout(widget1);
        horizontalLayout_2->setObjectName("horizontalLayout_2");
        horizontalLayout_2->setContentsMargins(0, 0, 0, 0);
        label_3 = new QLabel(widget1);
        label_3->setObjectName("label_3");
        label_3->setStyleSheet(QString::fromUtf8("font: 700 18pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout_2->addWidget(label_3);

        addIdLineEdit = new QLineEdit(widget1);
        addIdLineEdit->setObjectName("addIdLineEdit");
        addIdLineEdit->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout_2->addWidget(addIdLineEdit);

        label_4 = new QLabel(widget1);
        label_4->setObjectName("label_4");
        label_4->setStyleSheet(QString::fromUtf8("font: 700 18pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout_2->addWidget(label_4);

        addNameLineEdit = new QLineEdit(widget1);
        addNameLineEdit->setObjectName("addNameLineEdit");
        addNameLineEdit->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout_2->addWidget(addNameLineEdit);

        label_5 = new QLabel(widget1);
        label_5->setObjectName("label_5");
        label_5->setStyleSheet(QString::fromUtf8("font: 700 18pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout_2->addWidget(label_5);

        addBirthdayLineEdit = new QLineEdit(widget1);
        addBirthdayLineEdit->setObjectName("addBirthdayLineEdit");
        addBirthdayLineEdit->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout_2->addWidget(addBirthdayLineEdit);


        retranslateUi(Widget);

        QMetaObject::connectSlotsByName(Widget);
    } // setupUi

    void retranslateUi(QWidget *Widget)
    {
        Widget->setWindowTitle(QCoreApplication::translate("Widget", "Widget", nullptr));
        label->setText(QCoreApplication::translate("Widget", "\346\237\245\350\257\242\345\255\246\347\224\237\344\277\241\346\201\257", nullptr));
        label_2->setText(QCoreApplication::translate("Widget", "\346\267\273\345\212\240\345\255\246\347\224\237\344\277\241\346\201\257", nullptr));
        addButton->setText(QCoreApplication::translate("Widget", "\346\267\273\345\212\240", nullptr));
        idButton->setText(QCoreApplication::translate("Widget", "\346\214\211\345\255\246\345\217\267", nullptr));
        nameButton->setText(QCoreApplication::translate("Widget", "\346\214\211\345\247\223\345\220\215", nullptr));
        birthdayButton->setText(QCoreApplication::translate("Widget", "\346\214\211\347\224\237\346\227\245", nullptr));
        label_3->setText(QCoreApplication::translate("Widget", "\345\255\246\345\217\267", nullptr));
        label_4->setText(QCoreApplication::translate("Widget", "\345\247\223\345\220\215", nullptr));
        label_5->setText(QCoreApplication::translate("Widget", "\347\224\237\346\227\245", nullptr));
    } // retranslateUi

};

namespace Ui {
    class Widget: public Ui_Widget {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_WIDGET_H

注意, 默认的Cmake工程文件没有sql相关的资源, 需要自己添加:

find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Sql)
target_link_libraries(Learn_22 PRIVATE Qt${QT_VERSION_MAJOR}::Sql)

二十四 cmake工程管理文件

CMake是一个开源的跨平台的编译系统,它可以自动生成MakefileVisual StudioIDE所需要的工程文件。

在Qt中使用CMake文件可以简化项目的构建过程,让开发者只需要关注自己的代码,而不需要关注具体的构建过程。

Qt的CMake文件通常包含以下部分:

  1. 配置Qt模块:CMake文件中需要配置Qt需要使用的模块,例如QtCoreQtGui等。

  2. 定义目标:CMake文件中需要定义编译后的目标,例如可执行文件或库。

  3. 指定源文件:CMake文件中需要指定源文件的位置,以便CMake可以将它们编译成目标文件。

  4. 配置编译选项:CMake文件中需要配置编译选项,例如编译标志、链接选项等。

  5. 安装目标:CMake文件中需要指定安装目标,例如可执行文件、库文件等。这样可以让开发者将编译好的程序方便地部署到其他机器上。

总的来说,Qt中的CMake文件与其他应用程序的CMake文件相似,但需要特别配置Qt的模块和库。

通过使用CMake文件,开发者可以简化Qt项目的构建过程,从而更加专注于代码编写。

默认的cmake工程文件:

# 设置cmake最小版本
cmake_minimum_required(VERSION 3.5)

# 设置项目名称和版本号
project(Learn_22 VERSION 0.1 LANGUAGES CXX)

# 开启Qt自动化
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

# 设置C++标准
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 查找Qt库
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets LinguistTools)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets LinguistTools)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Sql)

# 设置翻译文件
set(TS_FILES Learn_22.ts)

# 设置项目源文件
set(PROJECT_SOURCES
        main.cpp
        Widget.cpp
        Widget.h
        Widget.ui
        ${TS_FILES}
)

# Qt6和Qt5的构建方式有所不同,需要分别处理
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
    # 使用qt_add_executable创建可执行文件
    qt_add_executable(Learn_22
        MANUAL_FINALIZATION
        ${PROJECT_SOURCES}
    )

    # 使用qt_create_translation创建翻译文件
    qt_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
else()
    # 使用add_executable创建可执行文件
    if(ANDROID)
        add_library(Learn_22 SHARED
            ${PROJECT_SOURCES}
        )
    else()
        add_executable(Learn_22
            ${PROJECT_SOURCES}
        )
    endif()

    # 使用qt5_create_translation创建翻译文件
    qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
endif()

# 链接Qt库
target_link_libraries(Learn_22 PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
target_link_libraries(Learn_22 PRIVATE Qt${QT_VERSION_MAJOR}::Sql)

# 设置可执行文件的属性
set_target_properties(Learn_22 PROPERTIES
    MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com
    MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
    MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
    MACOSX_BUNDLE TRUE
    WIN32_EXECUTABLE TRUE
)

# 安装可执行文件
install(TARGETS Learn_22
    BUNDLE DESTINATION .
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})

# 完成Qt6可执行文件的构建和安装
if(QT_VERSION_MAJOR EQUAL 6)
    qt_finalize_executable(Learn_22)
endif()

二十五 QFile文件操作

QFile是Qt提供的文件读写类,支持对文件进行读写、复制、重命名、删除等操作。常用C++函数如下:

  1. 打开文件:QFile file(fileName)

  2. 打开文件模式:

    • 只读模式:file.open(QIODevice::ReadOnly)

    • 只写模式:file.open(QIODevice::WriteOnly)

    • 读写模式:file.open(QIODevice::ReadWrite)

    • 追加模式:file.open(QIODevice::Append)

  3. 写入文件:file.write("Hello World!")

  4. 读取文件内容:

    • 读取所有数据:file.readAll()

    • 读取一行数据:file.readLine()

    • 读取指定字节数的数据:file.read(numBytes)

  5. 获取文件大小:file.size()

  6. 检查文件是否打开:file.isOpen()

  7. 关闭文件:file.close()

  8. 拷贝文件:QFile::copy(sourceFileName, targetFileName)

  9. 重命名文件:QFile::rename(oldName, newName)

  10. 删除文件:QFile::remove(fileName)

示例:

建立一个界面, 利用信号和槽机制, 打开一个文件, 并将文件内容显示出来
在这里插入图片描述
编辑内容, 然后保存.
在这里插入图片描述
代码:

Widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QFile>
#include <QMessageBox>
#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui
{
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

  public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

  private slots:
    void on_openButton_clicked();

    void on_saveButton_clicked();

  private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

widget.cpp

#include "Widget.h"
#include "./ui_Widget.h"

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

Widget::~Widget()
{
    delete ui;
}

void Widget::on_openButton_clicked()
{
    QFile file(ui->fileLineEdit->text());
    if (file.open(QIODevice::ReadOnly))
    {
        QMessageBox::information(this, "提示", "打开文件");
    }
    else
    {
        QMessageBox::information(this, "提示", "未打开文件");
    }

    ui->textEdit->setText(QString(file.readAll()));

    file.close();
}

void Widget::on_saveButton_clicked()
{
    QFile file(ui->fileLineEdit->text());
    if (file.open(QIODevice::WriteOnly | QIODevice::Truncate))
    {
        QMessageBox::information(this, "提示", "打开文件");
    }
    else
    {
        QMessageBox::information(this, "提示", "未打开文件");
    }

    file.write(ui->textEdit->toPlainText().toUtf8());

    file.close();
}

二十六 学生信息管理系统

用Qt实现一个含界面的简单学生信息管理系统, 主要功能:

  1. 登录和注册功能:系统需要有注册和登录功能,学生可以通过注册账号并登录来使用系统。

  2. 学生信息录入:系统需要支持学生信息的录入和管理,包括学生姓名、学号、性别、年龄、联系方式等信息。

  3. 学生信息查询:系统需要支持信息查询功能,学生可以通过查询功能查看自己的个人信息。

  4. 学生信息修改:学生可以随时修改自己的个人信息,如联系方式。

  5. 学生成绩管理:系统需要支持学生成绩信息的录入和管理,包括学生课程成绩等信息。

  6. 学生成绩查询:学生可以通过系统查询自己的课程成绩。

  7. 班级信息管理:系统需要支持班级信息的录入和管理,包括班级名称、班级简介等信息。

  8. 公告管理:系统需要支持公告管理功能,管理员可以通过系统发布学校或班级的公告通知。

  9. 系统安全:系统需要有安全保障措施,防止信息泄露或被恶意攻击。

  10. 界面友好:系统需要具备友好的用户界面,方便学生和管理员使用。

在这里插入图片描述

插入介绍: QTableViewQSqlTableModel

QTableView

QTableView是Qt框架中的一个控件,用于显示和编辑过滤表格数据。

它是一个基于模型/视图架构的控件,通过使用模型来管理数据,视图来显示数据。

以下是使用QTableView的一些常见方法和C++函数:

  1. 设置模型

可以通过setModel()函数将一个QAbstractTableModel类型的模型设置给QTableView控件。

模型通过继承QAbstractTableModel类实现,它负责管理数据。

常用的模型类有QStandardItemModelQSqlTableModel

  1. 设置选择模式

通过setSelectionBehavior()setSelectionMode()函数设置选择模式,用于指定用户如何在表格中选择行或单元格。

其中,setSelectionBehavior()函数指定用户选择行或单元格时的行为,而setSelectionMode()函数指定用户可以选择的行数。

  1. 设置表头

通过setHorizontalHeader()setVerticalHeader()函数设置自定义表头,这些表头可以是其他QWidget控件。

  1. 设置单元格属性

可以通过setItemDelegate()函数设置一个委托类,以控制QTableView中每个单元格的显示和编辑行为.

  1. 隐藏列

通过hideColumn()函数隐藏某一列.

QSqlTableModel

QSqlTableModel是Qt提供的一种数据库模型类,用于提供对单表数据的读写、修改、删除等操作。它继承于QAbstractTableModel,可以在TableView中使用。

使用方法:

  1. 首先需要创建数据库连接

    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("myDB.sqlite");
    if(!db.open())
    {
        qDebug()<<"open database error!";
        return ;
    }
    
  2. 创建QSqlTableModel对象

    QSqlTableModel *model = new QSqlTableModel(this, db); // this表示当前类是model的父类,对象被删除时会自动删除model对象
    model->setTable("student");
    model->setSort(0, Qt::AscendingOrder); // 按照某一列升序排序
    model->select(); // 获取所有数据
    
  3. TableView中显示数据

    ui->tableView->setModel(model);
    
  4. 更新表格中第一行的数据:

    QModelIndex index = model->index(0, 1); // 获取第一行第二列的index
    model->setData(index, "NewValue", Qt::EditRole); // 设置新值
    model->submitAll(); // 提交更改
    

常用函数

  1. setTable(const QString &tableName):设置表名

  2. setFilter(const QString &filter):设置筛选条件

  3. setSort(int column, Qt::SortOrder order):设置排序

  4. select():从表中获取数据

  5. setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole):更新数据

  6. insertRows(int row, int count, const QModelIndex &parent = QModelIndex()):插入行数据

  7. removeRows(int row, int count, const QModelIndex &parent = QModelIndex()):删除行数据

  8. setEditStrategy(EditStrategy strategy):置修改策略,决定了如何在模型中更改数据,并决定在什么条件下提交更改到数据库。 SqlTableModel提供了三种修改策略:QSqlTableModel::OnFieldChange(默认值)当编辑器中的一个单元格的内容改变时,自动提交该单元格的内容。 QSqlTableModel::OnRowChange 当编辑器中的一整行的内容改变时,自动提交该行的内容。 QSqlTableModel::OnManualSubmit 不自动提交更改,需要调用submitAll()函数手动提交。

程序所用数据库表格

需要三个表:

  1. login 这个给管理员使用, 校对管理员密码, 我们这里设置默认用户名和密码都是root, 可以直接在系统下改
CREATE TABLE login(
    name varchar(16) NOT NULL,
    stuPassword varchar(16) NOT NULL
);

  1. news 这个是储存班级和学校通知
CREATE TABLE news(
    theDate date NOT NULL,
    theTitle varchar(256) NOT NULL,
    theArtical varchar(2048) NOT NULL
);

  1. student 这个是储存学生信息, 包括学号, 登录密码, 学生信息, 学生成绩
CREATE TABLE student(
    stuNumber integer UNSIGNED PRIMARY KEY,
    stuPassword varchar(16) NOT NULL,
    stuName varchar(16) NOT NULL,
    sex varchar(8) NOT NULL,
    birth date NOT NULL,
    phoneNumber varchar(16),
    math integer UNSIGNED,
    chinese integer UNSIGNED,
    english integer UNSIGNED,
    physical integer UNSIGNED,
    chemistry integer UNSIGNED
);

程序组成以及界面

分为学生客户端和管理员端, 使用两个独立程序, 学生端有三个界面, 一个是登录, 另一个是注册, 还有查询.
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

管理端, 有注册, 成绩录入和信息推送.
在这里插入图片描述
在这里插入图片描述

学生端源码:

reg.h

#ifndef REG_H
#define REG_H

#include <QMessageBox>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QWidget>

namespace Ui
{
class reg;
}

class reg : public QWidget
{
    Q_OBJECT

  public:
    explicit reg(int stuNum_, QString passNumber_, QSqlDatabase *qdata_,
                 QWidget *parent = nullptr);
    ~reg();

  private slots:
    void on_cancelButton_clicked();

    void on_OkButton_clicked();

  private:
    Ui::reg *ui;
    unsigned int stuNum;
    QString passNumber;
    QSqlDatabase *qdata;
};

#endif // REG_H

student.h

#ifndef STUDENT_H
#define STUDENT_H

#include <QSqlDatabase>
#include <QSqlQuery>
#include <QWidget>

namespace Ui
{
class student;
}

class student : public QWidget
{
    Q_OBJECT

  public:
    explicit student(unsigned int stuNum_, QSqlDatabase *qdata_,
                     QWidget *parent = nullptr);
    ~student();

  private slots:
    void on_stuInfButton_clicked();

    void on_phoneChangeButton_clicked();

    void on_scoreButton_clicked();

    void on_newsButton_clicked();

  private:
    Ui::student *ui;
    unsigned int stuNum;
    QSqlDatabase *qdata;
};

#endif // STUDENT_H

Widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include "reg.h"
#include "student.h"
#include <QMessageBox>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui
{
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

  public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

  private slots:
    void on_loginButton_clicked();

    void on_registButton_clicked();

  private:
    Ui::Widget *ui;
    QSqlDatabase qdata;
    student *stu = nullptr;
    reg *regist = nullptr;
};
#endif // WIDGET_H

main.cpp

#include "Widget.h"

#include <QApplication>
#include <QLocale>
#include <QTranslator>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QTranslator translator;
    const QStringList uiLanguages = QLocale::system().uiLanguages();
    for (const QString &locale : uiLanguages) {
        const QString baseName = "Learn_24_" + QLocale(locale).name();
        if (translator.load(":/i18n/" + baseName)) {
            a.installTranslator(&translator);
            break;
        }
    }
    Widget w;
    w.show();
    return a.exec();
}

reg.cpp

#include "reg.h"
#include "ui_reg.h"

reg::reg(int stuNum_, QString passNumber_, QSqlDatabase *qdata_,
         QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::reg)
    , stuNum(stuNum_)
    , passNumber(passNumber_)
    , qdata(qdata_)
{
    ui->setupUi(this);
    ui->stuNumberLineEdit->setText(QString::number(stuNum));
}

reg::~reg()
{
    qDebug() << "delete reg";
    delete ui;
}

void reg::on_cancelButton_clicked()
{
    this->close();
}

void reg::on_OkButton_clicked()
{
    QSqlQuery qsql(*qdata);
    if (ui->stuNameLineEdit->text().isEmpty() ||
        ui->sexLineEdit->text().isEmpty() ||
        ui->birthdayLineEdit->text().isEmpty())
    {
        QMessageBox::information(this, "提示", "姓名, 性别, 年龄不可为空");
    }
    else
    {
        if (qsql.exec(
                QString(
                    "INSERT INTO student VALUES ('%1', '%2', '%3', '%4', '%5', "
                    "'%6', '', '', '', '', '');")
                    .arg(QString::number(stuNum))
                    .arg(passNumber)
                    .arg(ui->stuNameLineEdit->text())
                    .arg(ui->sexLineEdit->text())
                    .arg(ui->birthdayLineEdit->text())
                    .arg(ui->phoneLineEdit->text())))
        {
            qDebug() << "OK";
        }
    }
}

student.cpp

#include "student.h"
#include "ui_student.h"

student::student(unsigned int stuNum_, QSqlDatabase *qdata_, QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::student)
    , stuNum(stuNum_)
    , qdata(qdata_)
{
    ui->setupUi(this);
    QSqlQuery qsql(*qdata);
    if (qsql.exec(
            QString("SELECT * FROM student WHERE stuNumber = %1;").arg(stuNum)))
    {
        qsql.next();
        ui->numberLineEdit->setText(qsql.value(0).toString());
        ui->nameLineEdit->setText(qsql.value(2).toString());
        ui->sexLineEdit->setText(qsql.value(3).toString());
        ui->birthdayLineEdit->setText(qsql.value(4).toString());
        ui->phoneLineEdit->setText(qsql.value(5).toString());
    }
}

student::~student()
{
    qDebug() << "delete student";
    delete ui;
}

void student::on_stuInfButton_clicked()
{
    QSqlQuery qsql(*qdata);
    if (qsql.exec(
            QString("SELECT * FROM student WHERE stuNumber = %1;").arg(stuNum)))
    {
        qsql.next();
        ui->phoneLineEdit->setText(qsql.value(5).toString());
    }
}

void student::on_phoneChangeButton_clicked()
{
    QSqlQuery qsql(*qdata);
    if (qsql.exec(
            QString(
                "UPDATE student SET phoneNumber = '%1' WHERE stuNumber = '%2';")
                .arg(ui->phoneLineEdit->text())
                .arg(stuNum)))
    {
        qDebug() << "OK";
    }
}

void student::on_scoreButton_clicked()
{
    QSqlQuery qsql(*qdata);
    if (qsql.exec(
            QString("SELECT * FROM student WHERE stuNumber = %1;").arg(stuNum)))
    {
        qsql.next();
        QString result;
        result += "数学:\t";
        result += qsql.value(6).toString();
        result += "\n语文:\t";
        result += qsql.value(7).toString();
        result += "\n英语:\t";
        result += qsql.value(8).toString();
        result += "\n物理:\t";
        result += qsql.value(9).toString();
        result += "\n化学:\t";
        result += qsql.value(10).toString();
        ui->scoreTextEdit->setPlainText(result);
    }
    else
    {
        qDebug() << "fail";
    }
}

void student::on_newsButton_clicked()
{
    QSqlQuery qsql(*qdata);
    if (qsql.exec(QString("SELECT * FROM news;")))
    {
        QString result;
        while (qsql.next())
        {
            result += qsql.value(0).toString();
            result += "\t";
            result += qsql.value(1).toString();
            result += "\n";
            result += qsql.value(2).toString();
            result += "\n\n";
        }
        ui->newsTextEdit->appendPlainText(result);
    }
    else
    {
        qDebug() << "fail";
    }
}

Widget.cpp

#include "Widget.h"
#include "./ui_Widget.h"

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

    qdata = QSqlDatabase::addDatabase("QSQLITE");
    qdata.setHostName("localhost");
    qdata.setDatabaseName("E:\\clangC++\\learnQT\\Learn_24\\database.db");
    qdata.setUserName("root");
    qdata.setPassword("root");
    if (qdata.open())
    {
        qDebug() << "OK";
    }
    else
    {
        qDebug() << "Fail";
    }
}

Widget::~Widget()
{
    qDebug() << "delete Widget";
    delete ui;
    delete stu;
    delete regist;
}

void Widget::on_loginButton_clicked()
{
    QSqlQuery qsql(qdata);
    if (qsql.exec(QString("SELECT * FROM student WHERE stuNumber = %1;")
                      .arg(ui->stuNumLineEdit->text())))
    {
        if (qsql.next())
        {
            QString name = qsql.value(0).toString();
            QString password = qsql.value(1).toString();
            qDebug() << name << " " << password;

            if (name == ui->stuNumLineEdit->text() &&
                password == ui->passwordLineEdit->text())
            {
                qDebug() << "show stu";
                stu = new student(password.toUInt(), &qdata);
                this->hide();
                stu->show();
            }
            else
            {
                qDebug() << "学号或密码错误";
            }
        }
    }
    else
    {
        qDebug() << "Fail";
    }
}

void Widget::on_registButton_clicked()
{
    QSqlQuery qsql(qdata);
    bool flag;
    ui->stuNumLineEdit->text().toUInt(&flag);
    if (flag &&
        qsql.exec(QString("SELECT stuNumber FROM student WHERE stuNumber = %1;")
                      .arg(ui->stuNumLineEdit->text())))
    {
        if (qsql.next())
        {
            qDebug() << ui->stuNumLineEdit->text();
            QMessageBox::information(this, "提示", "学号重复");
        }
        else
        {
            qDebug() << "show reg";
            regist = new reg(ui->stuNumLineEdit->text().toUInt(),
                             ui->passwordLineEdit->text(), &qdata);
            this->hide();
            regist->show();
        }
    }
    else
    {
        qDebug() << "Fail";
    }
}

ui_Widget.h

/********************************************************************************
** Form generated from reading UI file 'Widget.ui'
**
** Created by: Qt User Interface Compiler version 6.5.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef UI_WIDGET_H
#define UI_WIDGET_H

#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QFormLayout>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_Widget
{
public:
    QLabel *label;
    QWidget *layoutWidget;
    QFormLayout *formLayout;
    QLabel *label_2;
    QLineEdit *stuNumLineEdit;
    QLabel *label_3;
    QLineEdit *passwordLineEdit;
    QWidget *layoutWidget1;
    QHBoxLayout *horizontalLayout;
    QPushButton *loginButton;
    QPushButton *registButton;

    void setupUi(QWidget *Widget)
    {
        if (Widget->objectName().isEmpty())
            Widget->setObjectName("Widget");
        Widget->resize(337, 233);
        label = new QLabel(Widget);
        label->setObjectName("label");
        label->setGeometry(QRect(10, 10, 321, 41));
        label->setStyleSheet(QString::fromUtf8("font: 700 20pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));
        label->setAlignment(Qt::AlignCenter);
        layoutWidget = new QWidget(Widget);
        layoutWidget->setObjectName("layoutWidget");
        layoutWidget->setGeometry(QRect(30, 70, 289, 72));
        formLayout = new QFormLayout(layoutWidget);
        formLayout->setObjectName("formLayout");
        formLayout->setContentsMargins(0, 0, 0, 0);
        label_2 = new QLabel(layoutWidget);
        label_2->setObjectName("label_2");
        label_2->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(0, QFormLayout::LabelRole, label_2);

        stuNumLineEdit = new QLineEdit(layoutWidget);
        stuNumLineEdit->setObjectName("stuNumLineEdit");
        stuNumLineEdit->setStyleSheet(QString::fromUtf8("font: 700 14pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(0, QFormLayout::FieldRole, stuNumLineEdit);

        label_3 = new QLabel(layoutWidget);
        label_3->setObjectName("label_3");
        label_3->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(1, QFormLayout::LabelRole, label_3);

        passwordLineEdit = new QLineEdit(layoutWidget);
        passwordLineEdit->setObjectName("passwordLineEdit");
        passwordLineEdit->setStyleSheet(QString::fromUtf8("font: 700 14pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(1, QFormLayout::FieldRole, passwordLineEdit);

        layoutWidget1 = new QWidget(Widget);
        layoutWidget1->setObjectName("layoutWidget1");
        layoutWidget1->setGeometry(QRect(100, 180, 158, 32));
        horizontalLayout = new QHBoxLayout(layoutWidget1);
        horizontalLayout->setObjectName("horizontalLayout");
        horizontalLayout->setContentsMargins(0, 0, 0, 0);
        loginButton = new QPushButton(layoutWidget1);
        loginButton->setObjectName("loginButton");
        loginButton->setStyleSheet(QString::fromUtf8("font: 700 12pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout->addWidget(loginButton);

        registButton = new QPushButton(layoutWidget1);
        registButton->setObjectName("registButton");
        registButton->setStyleSheet(QString::fromUtf8("font: 700 12pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout->addWidget(registButton);


        retranslateUi(Widget);

        QMetaObject::connectSlotsByName(Widget);
    } // setupUi

    void retranslateUi(QWidget *Widget)
    {
        Widget->setWindowTitle(QCoreApplication::translate("Widget", "Widget", nullptr));
        label->setText(QCoreApplication::translate("Widget", "\345\255\246\347\224\237\344\277\241\346\201\257\347\263\273\347\273\237", nullptr));
        label_2->setText(QCoreApplication::translate("Widget", "\345\255\246    \345\217\267", nullptr));
        label_3->setText(QCoreApplication::translate("Widget", "\345\257\206    \347\240\201", nullptr));
        loginButton->setText(QCoreApplication::translate("Widget", "\347\231\273\345\275\225", nullptr));
        registButton->setText(QCoreApplication::translate("Widget", "\346\263\250\345\206\214", nullptr));
    } // retranslateUi

};

namespace Ui {
    class Widget: public Ui_Widget {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_WIDGET_H

ui_student.h

/********************************************************************************
** Form generated from reading UI file 'student.ui'
**
** Created by: Qt User Interface Compiler version 6.5.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef UI_STUDENT_H
#define UI_STUDENT_H

#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QFormLayout>
#include <QtWidgets/QFrame>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPlainTextEdit>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QSpacerItem>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_student
{
public:
    QLabel *label;
    QPlainTextEdit *scoreTextEdit;
    QPlainTextEdit *newsTextEdit;
    QFrame *line;
    QFrame *line_2;
    QWidget *layoutWidget;
    QFormLayout *formLayout;
    QLabel *label_2;
    QLineEdit *nameLineEdit;
    QLabel *label_3;
    QLineEdit *numberLineEdit;
    QLabel *label_4;
    QLineEdit *sexLineEdit;
    QLabel *label_5;
    QLineEdit *birthdayLineEdit;
    QLabel *label_6;
    QLineEdit *phoneLineEdit;
    QWidget *layoutWidget1;
    QHBoxLayout *horizontalLayout;
    QPushButton *stuInfButton;
    QSpacerItem *horizontalSpacer;
    QPushButton *phoneChangeButton;
    QWidget *layoutWidget2;
    QHBoxLayout *horizontalLayout_2;
    QLabel *label_7;
    QSpacerItem *horizontalSpacer_2;
    QPushButton *scoreButton;
    QWidget *layoutWidget3;
    QHBoxLayout *horizontalLayout_3;
    QLabel *label_8;
    QSpacerItem *horizontalSpacer_3;
    QPushButton *newsButton;

    void setupUi(QWidget *student)
    {
        if (student->objectName().isEmpty())
            student->setObjectName("student");
        student->resize(860, 590);
        student->setMinimumSize(QSize(860, 590));
        student->setMaximumSize(QSize(860, 590));
        label = new QLabel(student);
        label->setObjectName("label");
        label->setGeometry(QRect(140, 10, 111, 41));
        label->setStyleSheet(QString::fromUtf8("font: 700 20pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));
        scoreTextEdit = new QPlainTextEdit(student);
        scoreTextEdit->setObjectName("scoreTextEdit");
        scoreTextEdit->setGeometry(QRect(420, 60, 431, 231));
        scoreTextEdit->setStyleSheet(QString::fromUtf8("font: 700 14pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));
        newsTextEdit = new QPlainTextEdit(student);
        newsTextEdit->setObjectName("newsTextEdit");
        newsTextEdit->setGeometry(QRect(10, 390, 841, 191));
        newsTextEdit->setStyleSheet(QString::fromUtf8("font: 700 14pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));
        line = new QFrame(student);
        line->setObjectName("line");
        line->setGeometry(QRect(7, 313, 851, 21));
        line->setFrameShape(QFrame::HLine);
        line->setFrameShadow(QFrame::Sunken);
        line_2 = new QFrame(student);
        line_2->setObjectName("line_2");
        line_2->setGeometry(QRect(396, 5, 20, 318));
        line_2->setFrameShape(QFrame::VLine);
        line_2->setFrameShadow(QFrame::Sunken);
        layoutWidget = new QWidget(student);
        layoutWidget->setObjectName("layoutWidget");
        layoutWidget->setGeometry(QRect(10, 60, 381, 186));
        formLayout = new QFormLayout(layoutWidget);
        formLayout->setObjectName("formLayout");
        formLayout->setContentsMargins(0, 0, 0, 0);
        label_2 = new QLabel(layoutWidget);
        label_2->setObjectName("label_2");
        label_2->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(0, QFormLayout::LabelRole, label_2);

        nameLineEdit = new QLineEdit(layoutWidget);
        nameLineEdit->setObjectName("nameLineEdit");
        nameLineEdit->setStyleSheet(QString::fromUtf8("font: 700 14pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));
        nameLineEdit->setReadOnly(true);

        formLayout->setWidget(0, QFormLayout::FieldRole, nameLineEdit);

        label_3 = new QLabel(layoutWidget);
        label_3->setObjectName("label_3");
        label_3->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(1, QFormLayout::LabelRole, label_3);

        numberLineEdit = new QLineEdit(layoutWidget);
        numberLineEdit->setObjectName("numberLineEdit");
        numberLineEdit->setStyleSheet(QString::fromUtf8("font: 700 14pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));
        numberLineEdit->setReadOnly(true);

        formLayout->setWidget(1, QFormLayout::FieldRole, numberLineEdit);

        label_4 = new QLabel(layoutWidget);
        label_4->setObjectName("label_4");
        label_4->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(2, QFormLayout::LabelRole, label_4);

        sexLineEdit = new QLineEdit(layoutWidget);
        sexLineEdit->setObjectName("sexLineEdit");
        sexLineEdit->setStyleSheet(QString::fromUtf8("font: 700 14pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));
        sexLineEdit->setReadOnly(true);

        formLayout->setWidget(2, QFormLayout::FieldRole, sexLineEdit);

        label_5 = new QLabel(layoutWidget);
        label_5->setObjectName("label_5");
        label_5->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(3, QFormLayout::LabelRole, label_5);

        birthdayLineEdit = new QLineEdit(layoutWidget);
        birthdayLineEdit->setObjectName("birthdayLineEdit");
        birthdayLineEdit->setStyleSheet(QString::fromUtf8("font: 700 14pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));
        birthdayLineEdit->setReadOnly(true);

        formLayout->setWidget(3, QFormLayout::FieldRole, birthdayLineEdit);

        label_6 = new QLabel(layoutWidget);
        label_6->setObjectName("label_6");
        label_6->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(4, QFormLayout::LabelRole, label_6);

        phoneLineEdit = new QLineEdit(layoutWidget);
        phoneLineEdit->setObjectName("phoneLineEdit");
        phoneLineEdit->setStyleSheet(QString::fromUtf8("font: 700 14pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(4, QFormLayout::FieldRole, phoneLineEdit);

        layoutWidget1 = new QWidget(student);
        layoutWidget1->setObjectName("layoutWidget1");
        layoutWidget1->setGeometry(QRect(50, 270, 301, 36));
        horizontalLayout = new QHBoxLayout(layoutWidget1);
        horizontalLayout->setObjectName("horizontalLayout");
        horizontalLayout->setContentsMargins(0, 0, 0, 0);
        stuInfButton = new QPushButton(layoutWidget1);
        stuInfButton->setObjectName("stuInfButton");
        stuInfButton->setStyleSheet(QString::fromUtf8("font: 700 14pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout->addWidget(stuInfButton);

        horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);

        horizontalLayout->addItem(horizontalSpacer);

        phoneChangeButton = new QPushButton(layoutWidget1);
        phoneChangeButton->setObjectName("phoneChangeButton");
        phoneChangeButton->setStyleSheet(QString::fromUtf8("font: 700 14pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout->addWidget(phoneChangeButton);

        layoutWidget2 = new QWidget(student);
        layoutWidget2->setObjectName("layoutWidget2");
        layoutWidget2->setGeometry(QRect(420, 10, 421, 39));
        horizontalLayout_2 = new QHBoxLayout(layoutWidget2);
        horizontalLayout_2->setObjectName("horizontalLayout_2");
        horizontalLayout_2->setContentsMargins(0, 0, 0, 0);
        label_7 = new QLabel(layoutWidget2);
        label_7->setObjectName("label_7");
        label_7->setStyleSheet(QString::fromUtf8("font: 700 20pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout_2->addWidget(label_7);

        horizontalSpacer_2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);

        horizontalLayout_2->addItem(horizontalSpacer_2);

        scoreButton = new QPushButton(layoutWidget2);
        scoreButton->setObjectName("scoreButton");
        scoreButton->setStyleSheet(QString::fromUtf8("font: 700 14pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout_2->addWidget(scoreButton);

        layoutWidget3 = new QWidget(student);
        layoutWidget3->setObjectName("layoutWidget3");
        layoutWidget3->setGeometry(QRect(250, 340, 361, 39));
        horizontalLayout_3 = new QHBoxLayout(layoutWidget3);
        horizontalLayout_3->setObjectName("horizontalLayout_3");
        horizontalLayout_3->setContentsMargins(0, 0, 0, 0);
        label_8 = new QLabel(layoutWidget3);
        label_8->setObjectName("label_8");
        label_8->setStyleSheet(QString::fromUtf8("font: 700 20pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout_3->addWidget(label_8);

        horizontalSpacer_3 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);

        horizontalLayout_3->addItem(horizontalSpacer_3);

        newsButton = new QPushButton(layoutWidget3);
        newsButton->setObjectName("newsButton");
        newsButton->setStyleSheet(QString::fromUtf8("font: 700 14pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout_3->addWidget(newsButton);


        retranslateUi(student);

        QMetaObject::connectSlotsByName(student);
    } // setupUi

    void retranslateUi(QWidget *student)
    {
        student->setWindowTitle(QCoreApplication::translate("student", "Form", nullptr));
        label->setText(QCoreApplication::translate("student", "\345\255\246\347\224\237\344\277\241\346\201\257", nullptr));
        label_2->setText(QCoreApplication::translate("student", "\345\247\223\345\220\215", nullptr));
        label_3->setText(QCoreApplication::translate("student", "\345\255\246\345\217\267", nullptr));
        label_4->setText(QCoreApplication::translate("student", "\346\200\247\345\210\253", nullptr));
        label_5->setText(QCoreApplication::translate("student", "\345\271\264\351\276\204", nullptr));
        label_6->setText(QCoreApplication::translate("student", "\350\201\224\347\263\273\346\226\271\345\274\217", nullptr));
        stuInfButton->setText(QCoreApplication::translate("student", "\344\277\241\346\201\257\346\237\245\350\257\242", nullptr));
        phoneChangeButton->setText(QCoreApplication::translate("student", "\350\201\224\347\263\273\346\226\271\345\274\217\344\277\256\346\224\271", nullptr));
        label_7->setText(QCoreApplication::translate("student", "\345\255\246\347\224\237\346\210\220\347\273\251", nullptr));
        scoreButton->setText(QCoreApplication::translate("student", "\346\237\245\350\257\242", nullptr));
        label_8->setText(QCoreApplication::translate("student", "\345\255\246\346\240\241\345\205\254\345\221\212", nullptr));
        newsButton->setText(QCoreApplication::translate("student", "\346\237\245\350\257\242", nullptr));
    } // retranslateUi

};

namespace Ui {
    class student: public Ui_student {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_STUDENT_H

ui_reg.h

/********************************************************************************
** Form generated from reading UI file 'reg.ui'
**
** Created by: Qt User Interface Compiler version 6.5.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef UI_REG_H
#define UI_REG_H

#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QFormLayout>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_reg
{
public:
    QLabel *label;
    QWidget *layoutWidget;
    QFormLayout *formLayout;
    QLabel *label_2;
    QLineEdit *stuNameLineEdit;
    QLabel *label_3;
    QLineEdit *stuNumberLineEdit;
    QLabel *label_4;
    QLineEdit *sexLineEdit;
    QLabel *label_5;
    QLineEdit *birthdayLineEdit;
    QLabel *label_6;
    QLineEdit *phoneLineEdit;
    QWidget *layoutWidget1;
    QHBoxLayout *horizontalLayout;
    QPushButton *OkButton;
    QPushButton *cancelButton;

    void setupUi(QWidget *reg)
    {
        if (reg->objectName().isEmpty())
            reg->setObjectName("reg");
        reg->resize(400, 335);
        label = new QLabel(reg);
        label->setObjectName("label");
        label->setGeometry(QRect(120, 10, 171, 41));
        label->setStyleSheet(QString::fromUtf8("font: 700 20pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));
        layoutWidget = new QWidget(reg);
        layoutWidget->setObjectName("layoutWidget");
        layoutWidget->setGeometry(QRect(10, 60, 381, 201));
        formLayout = new QFormLayout(layoutWidget);
        formLayout->setObjectName("formLayout");
        formLayout->setContentsMargins(0, 0, 0, 0);
        label_2 = new QLabel(layoutWidget);
        label_2->setObjectName("label_2");
        label_2->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(0, QFormLayout::LabelRole, label_2);

        stuNameLineEdit = new QLineEdit(layoutWidget);
        stuNameLineEdit->setObjectName("stuNameLineEdit");
        stuNameLineEdit->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(0, QFormLayout::FieldRole, stuNameLineEdit);

        label_3 = new QLabel(layoutWidget);
        label_3->setObjectName("label_3");
        label_3->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(1, QFormLayout::LabelRole, label_3);

        stuNumberLineEdit = new QLineEdit(layoutWidget);
        stuNumberLineEdit->setObjectName("stuNumberLineEdit");
        stuNumberLineEdit->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));
        stuNumberLineEdit->setReadOnly(true);

        formLayout->setWidget(1, QFormLayout::FieldRole, stuNumberLineEdit);

        label_4 = new QLabel(layoutWidget);
        label_4->setObjectName("label_4");
        label_4->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(2, QFormLayout::LabelRole, label_4);

        sexLineEdit = new QLineEdit(layoutWidget);
        sexLineEdit->setObjectName("sexLineEdit");
        sexLineEdit->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(2, QFormLayout::FieldRole, sexLineEdit);

        label_5 = new QLabel(layoutWidget);
        label_5->setObjectName("label_5");
        label_5->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(3, QFormLayout::LabelRole, label_5);

        birthdayLineEdit = new QLineEdit(layoutWidget);
        birthdayLineEdit->setObjectName("birthdayLineEdit");
        birthdayLineEdit->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(3, QFormLayout::FieldRole, birthdayLineEdit);

        label_6 = new QLabel(layoutWidget);
        label_6->setObjectName("label_6");
        label_6->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(4, QFormLayout::LabelRole, label_6);

        phoneLineEdit = new QLineEdit(layoutWidget);
        phoneLineEdit->setObjectName("phoneLineEdit");
        phoneLineEdit->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(4, QFormLayout::FieldRole, phoneLineEdit);

        layoutWidget1 = new QWidget(reg);
        layoutWidget1->setObjectName("layoutWidget1");
        layoutWidget1->setGeometry(QRect(130, 280, 158, 39));
        horizontalLayout = new QHBoxLayout(layoutWidget1);
        horizontalLayout->setObjectName("horizontalLayout");
        horizontalLayout->setContentsMargins(0, 0, 0, 0);
        OkButton = new QPushButton(layoutWidget1);
        OkButton->setObjectName("OkButton");
        OkButton->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout->addWidget(OkButton);

        cancelButton = new QPushButton(layoutWidget1);
        cancelButton->setObjectName("cancelButton");
        cancelButton->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout->addWidget(cancelButton);


        retranslateUi(reg);

        QMetaObject::connectSlotsByName(reg);
    } // setupUi

    void retranslateUi(QWidget *reg)
    {
        reg->setWindowTitle(QCoreApplication::translate("reg", "Form", nullptr));
        label->setText(QCoreApplication::translate("reg", "\345\255\246\347\224\237\344\277\241\346\201\257\345\275\225\345\205\245", nullptr));
        label_2->setText(QCoreApplication::translate("reg", "\345\247\223\345\220\215", nullptr));
        stuNameLineEdit->setText(QString());
        label_3->setText(QCoreApplication::translate("reg", "\345\255\246\345\217\267", nullptr));
        stuNumberLineEdit->setText(QString());
        label_4->setText(QCoreApplication::translate("reg", "\346\200\247\345\210\253", nullptr));
        sexLineEdit->setText(QString());
        label_5->setText(QCoreApplication::translate("reg", "\345\271\264\351\276\204", nullptr));
        birthdayLineEdit->setText(QString());
        label_6->setText(QCoreApplication::translate("reg", "\350\201\224\347\263\273\346\226\271\345\274\217", nullptr));
        phoneLineEdit->setText(QString());
        OkButton->setText(QCoreApplication::translate("reg", "\347\241\256\345\256\232", nullptr));
        cancelButton->setText(QCoreApplication::translate("reg", "\345\217\226\346\266\210", nullptr));
    } // retranslateUi

};

namespace Ui {
    class reg: public Ui_reg {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_REG_H

Cmakelists.txt

cmake_minimum_required(VERSION 3.5)

project(Learn_24 VERSION 0.1 LANGUAGES CXX)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets LinguistTools)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets LinguistTools)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Sql)

set(TS_FILES Learn_24_zh_CN.ts)

set(PROJECT_SOURCES
        main.cpp
        Widget.cpp
        Widget.h
        Widget.ui
        student.cpp
        student.h
        student.ui
        reg.cpp
        reg.h
        reg.ui
        ${TS_FILES}
)

if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
    qt_add_executable(Learn_24
        MANUAL_FINALIZATION
        ${PROJECT_SOURCES}
    )
# Define target properties for Android with Qt 6 as:
#    set_property(TARGET Learn_24 APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
#                 ${CMAKE_CURRENT_SOURCE_DIR}/android)
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation

    qt_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
else()
    if(ANDROID)
        add_library(Learn_24 SHARED
            ${PROJECT_SOURCES}
        )
# Define properties for Android with Qt 5 after find_package() calls as:
#    set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
    else()
        add_executable(Learn_24
            ${PROJECT_SOURCES}
        )
    endif()

    qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
endif()

target_link_libraries(Learn_24 PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
target_link_libraries(Learn_24 PRIVATE Qt${QT_VERSION_MAJOR}::Sql)

set_target_properties(Learn_24 PROPERTIES
    MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com
    MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
    MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
    MACOSX_BUNDLE TRUE
    WIN32_EXECUTABLE TRUE
)

install(TARGETS Learn_24
    BUNDLE DESTINATION .
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})

if(QT_VERSION_MAJOR EQUAL 6)
    qt_finalize_executable(Learn_24)
endif()

管理员端源码:

main.cpp

#include "Widget.h"

#include <QApplication>
#include <QLocale>
#include <QTranslator>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QTranslator translator;
    const QStringList uiLanguages = QLocale::system().uiLanguages();
    for (const QString &locale : uiLanguages) {
        const QString baseName = "Learn_25_" + QLocale(locale).name();
        if (translator.load(":/i18n/" + baseName)) {
            a.installTranslator(&translator);
            break;
        }
    }
    Widget w;
    w.show();
    return a.exec();
}

Widget.cpp

#include "Widget.h"
#include "./ui_Widget.h"

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

    qdata = QSqlDatabase::addDatabase("QSQLITE");
    qdata.setHostName("localhost");
    qdata.setDatabaseName("E:\\clangC++\\learnQT\\Learn_24\\database.db");
    qdata.setUserName("root");
    qdata.setPassword("root");
    if (qdata.open())
    {
        qDebug() << "OK";
    }
    else
    {
        qDebug() << "Fail";
    }
}

Widget::~Widget()
{
    delete ui;
    delete adm;
}

void Widget::on_longinButton_clicked()
{
    QSqlQuery qsql(qdata);
    if (qsql.exec(QString("SELECT * FROM login WHERE name = '%1';")
                      .arg(ui->nameLineEdit->text())))
    {
        while (qsql.next())
        {
            if (qsql.value(1).toString() == ui->passwordLineEdit->text())
            {
                adm = new admin(&qdata);
                this->hide();
                adm->show();
                break;
            }
        }
    }
    else
    {
        qDebug() << "fail";
    }
}

Widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include "admin.h"
#include <QMessageBox>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui
{
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

  public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

  private slots:
    void on_longinButton_clicked();

  private:
    Ui::Widget *ui;
    QSqlDatabase qdata;
    admin *adm = nullptr;
};
#endif // WIDGET_H

ui_Widget.h

/********************************************************************************
** Form generated from reading UI file 'Widget.ui'
**
** Created by: Qt User Interface Compiler version 6.5.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef UI_WIDGET_H
#define UI_WIDGET_H

#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QFormLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_Widget
{
public:
    QLabel *label;
    QPushButton *longinButton;
    QWidget *layoutWidget;
    QFormLayout *formLayout;
    QLabel *label_2;
    QLineEdit *nameLineEdit;
    QLabel *label_3;
    QLineEdit *passwordLineEdit;

    void setupUi(QWidget *Widget)
    {
        if (Widget->objectName().isEmpty())
            Widget->setObjectName("Widget");
        Widget->resize(304, 217);
        label = new QLabel(Widget);
        label->setObjectName("label");
        label->setGeometry(QRect(80, 10, 141, 37));
        label->setStyleSheet(QString::fromUtf8("font: 700 20pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));
        longinButton = new QPushButton(Widget);
        longinButton->setObjectName("longinButton");
        longinButton->setGeometry(QRect(110, 170, 91, 31));
        longinButton->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));
        layoutWidget = new QWidget(Widget);
        layoutWidget->setObjectName("layoutWidget");
        layoutWidget->setGeometry(QRect(10, 70, 291, 72));
        formLayout = new QFormLayout(layoutWidget);
        formLayout->setObjectName("formLayout");
        formLayout->setContentsMargins(0, 0, 0, 0);
        label_2 = new QLabel(layoutWidget);
        label_2->setObjectName("label_2");
        label_2->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(0, QFormLayout::LabelRole, label_2);

        nameLineEdit = new QLineEdit(layoutWidget);
        nameLineEdit->setObjectName("nameLineEdit");
        nameLineEdit->setStyleSheet(QString::fromUtf8("font: 700 14pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(0, QFormLayout::FieldRole, nameLineEdit);

        label_3 = new QLabel(layoutWidget);
        label_3->setObjectName("label_3");
        label_3->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(1, QFormLayout::LabelRole, label_3);

        passwordLineEdit = new QLineEdit(layoutWidget);
        passwordLineEdit->setObjectName("passwordLineEdit");
        passwordLineEdit->setStyleSheet(QString::fromUtf8("font: 700 14pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        formLayout->setWidget(1, QFormLayout::FieldRole, passwordLineEdit);


        retranslateUi(Widget);

        QMetaObject::connectSlotsByName(Widget);
    } // setupUi

    void retranslateUi(QWidget *Widget)
    {
        Widget->setWindowTitle(QCoreApplication::translate("Widget", "Widget", nullptr));
        label->setText(QCoreApplication::translate("Widget", "\347\256\241\347\220\206\345\221\230\347\231\273\345\275\225", nullptr));
        longinButton->setText(QCoreApplication::translate("Widget", "\347\231\273\345\275\225", nullptr));
        label_2->setText(QCoreApplication::translate("Widget", "\350\264\246\345\217\267", nullptr));
        nameLineEdit->setText(QCoreApplication::translate("Widget", "root", nullptr));
        label_3->setText(QCoreApplication::translate("Widget", "\345\257\206\347\240\201", nullptr));
        passwordLineEdit->setText(QCoreApplication::translate("Widget", "root", nullptr));
    } // retranslateUi

};

namespace Ui {
    class Widget: public Ui_Widget {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_WIDGET_H

admin.cpp

#include "admin.h"
#include "ui_admin.h"

admin::admin(QSqlDatabase *qdata_, QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::admin)
    , qdata(qdata_)
{
    ui->setupUi(this);
    // qtbv = new QSqlTableModel(this, *qdata);
    qtbv = new myModel(this, *qdata);
    qtbv->setTable("student");
    qtbv->select();
    qtbv->setEditStrategy(QSqlTableModel::OnManualSubmit);
    qtbv->setHeaderData(0, Qt::Horizontal, "学号");
    qtbv->setHeaderData(2, Qt::Horizontal, "姓名");
    qtbv->setHeaderData(6, Qt::Horizontal, "数学");
    qtbv->setHeaderData(7, Qt::Horizontal, "语文");
    qtbv->setHeaderData(8, Qt::Horizontal, "英语");
    qtbv->setHeaderData(9, Qt::Horizontal, "物理");
    qtbv->setHeaderData(10, Qt::Horizontal, "化学");

    ui->scoreTableView->setModel(qtbv);
    ui->scoreTableView->hideColumn(1);
    ui->scoreTableView->hideColumn(3);
    ui->scoreTableView->hideColumn(4);
    ui->scoreTableView->hideColumn(5);
}

admin::~admin()
{
    qDebug() << "delete admin";
    delete ui;
}

void admin::on_newsButton_clicked()
{
    QSqlQuery qsql(*qdata);
    if (ui->newsDateLineEdit->text().isEmpty() ||
        ui->newsTitleLineEdit->text().isEmpty() ||
        ui->newsTextEdit->toPlainText().isEmpty())
    {
        QMessageBox::information(this, "提示", "日期, 标题, 内容不可为空");
    }
    else
    {
        if (qsql.exec(QString("INSERT INTO news VALUES ('%1', '%2', '%3');")
                          .arg(ui->newsDateLineEdit->text())
                          .arg(ui->newsTitleLineEdit->text())
                          .arg(ui->newsTextEdit->toPlainText())))
        {
            qDebug() << "OK";
        }
    }
}

void admin::on_classButton_clicked()
{
    QSqlQuery qsql(*qdata);
    if (ui->classDateLineEdit->text().isEmpty() ||
        ui->classTitleLineEdit->text().isEmpty() ||
        ui->classTextEdit->toPlainText().isEmpty())
    {
        QMessageBox::information(this, "提示", "日期, 标题, 内容不可为空");
    }
    else
    {
        if (qsql.exec(QString("INSERT INTO news VALUES ('%1', '%2', '%3');")
                          .arg(ui->classDateLineEdit->text())
                          .arg(ui->classTitleLineEdit->text())
                          .arg(ui->classTextEdit->toPlainText())))
        {
            qDebug() << "OK";
        }
    }
}

void admin::on_stuScoreButton_clicked()
{
    if (qtbv->submitAll())
    {
        qDebug() << "submitAll OK";
    }
}

admin.h

#ifndef ADMIN_H
#define ADMIN_H

#include "myModel.h"
#include <QMessageBox>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlTableModel>
#include <QWidget>

namespace Ui
{
class admin;
}

class admin : public QWidget
{
    Q_OBJECT

  public:
    explicit admin(QSqlDatabase *qdata_, QWidget *parent = nullptr);
    ~admin();

  private slots:
    void on_newsButton_clicked();

    void on_classButton_clicked();

    void on_stuScoreButton_clicked();

  private:
    Ui::admin *ui;
    QSqlDatabase *qdata;
    myModel *qtbv;
    // QSqlTableModel *qtbv;
};

#endif // ADMIN_H

ui_admin.h

/********************************************************************************
** Form generated from reading UI file 'admin.ui'
**
** Created by: Qt User Interface Compiler version 6.5.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef UI_ADMIN_H
#define UI_ADMIN_H

#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QFrame>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPlainTextEdit>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QSpacerItem>
#include <QtWidgets/QTableView>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_admin
{
public:
    QFrame *line;
    QFrame *line_2;
    QTableView *scoreTableView;
    QPlainTextEdit *newsTextEdit;
    QPlainTextEdit *classTextEdit;
    QWidget *layoutWidget;
    QHBoxLayout *horizontalLayout_3;
    QLabel *label_6;
    QLineEdit *classDateLineEdit;
    QLabel *label_7;
    QLineEdit *classTitleLineEdit;
    QWidget *widget;
    QHBoxLayout *horizontalLayout;
    QLabel *label_4;
    QLineEdit *newsDateLineEdit;
    QLabel *label_5;
    QLineEdit *newsTitleLineEdit;
    QWidget *widget1;
    QHBoxLayout *horizontalLayout_2;
    QLabel *label_2;
    QSpacerItem *horizontalSpacer;
    QPushButton *newsButton;
    QWidget *widget2;
    QHBoxLayout *horizontalLayout_4;
    QLabel *label_3;
    QSpacerItem *horizontalSpacer_2;
    QPushButton *classButton;
    QWidget *widget3;
    QHBoxLayout *horizontalLayout_5;
    QLabel *label;
    QSpacerItem *horizontalSpacer_3;
    QPushButton *stuScoreButton;

    void setupUi(QWidget *admin)
    {
        if (admin->objectName().isEmpty())
            admin->setObjectName("admin");
        admin->resize(1210, 950);
        admin->setMinimumSize(QSize(1210, 950));
        admin->setMaximumSize(QSize(1210, 950));
        line = new QFrame(admin);
        line->setObjectName("line");
        line->setGeometry(QRect(7, 530, 1191, 20));
        line->setFrameShape(QFrame::HLine);
        line->setFrameShadow(QFrame::Sunken);
        line_2 = new QFrame(admin);
        line_2->setObjectName("line_2");
        line_2->setGeometry(QRect(600, 540, 21, 401));
        line_2->setFrameShape(QFrame::VLine);
        line_2->setFrameShadow(QFrame::Sunken);
        scoreTableView = new QTableView(admin);
        scoreTableView->setObjectName("scoreTableView");
        scoreTableView->setGeometry(QRect(10, 60, 1191, 471));
        scoreTableView->setStyleSheet(QString::fromUtf8("font: 700 12pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));
        newsTextEdit = new QPlainTextEdit(admin);
        newsTextEdit->setObjectName("newsTextEdit");
        newsTextEdit->setGeometry(QRect(10, 677, 591, 261));
        classTextEdit = new QPlainTextEdit(admin);
        classTextEdit->setObjectName("classTextEdit");
        classTextEdit->setGeometry(QRect(618, 677, 583, 261));
        layoutWidget = new QWidget(admin);
        layoutWidget->setObjectName("layoutWidget");
        layoutWidget->setGeometry(QRect(640, 620, 532, 34));
        horizontalLayout_3 = new QHBoxLayout(layoutWidget);
        horizontalLayout_3->setObjectName("horizontalLayout_3");
        horizontalLayout_3->setContentsMargins(0, 0, 0, 0);
        label_6 = new QLabel(layoutWidget);
        label_6->setObjectName("label_6");
        label_6->setStyleSheet(QString::fromUtf8("font: 700 14pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout_3->addWidget(label_6);

        classDateLineEdit = new QLineEdit(layoutWidget);
        classDateLineEdit->setObjectName("classDateLineEdit");
        classDateLineEdit->setStyleSheet(QString::fromUtf8("font: 700 14pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout_3->addWidget(classDateLineEdit);

        label_7 = new QLabel(layoutWidget);
        label_7->setObjectName("label_7");
        label_7->setStyleSheet(QString::fromUtf8("font: 700 14pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout_3->addWidget(label_7);

        classTitleLineEdit = new QLineEdit(layoutWidget);
        classTitleLineEdit->setObjectName("classTitleLineEdit");
        classTitleLineEdit->setStyleSheet(QString::fromUtf8("font: 700 14pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout_3->addWidget(classTitleLineEdit);

        widget = new QWidget(admin);
        widget->setObjectName("widget");
        widget->setGeometry(QRect(20, 620, 532, 34));
        horizontalLayout = new QHBoxLayout(widget);
        horizontalLayout->setObjectName("horizontalLayout");
        horizontalLayout->setContentsMargins(0, 0, 0, 0);
        label_4 = new QLabel(widget);
        label_4->setObjectName("label_4");
        label_4->setStyleSheet(QString::fromUtf8("font: 700 14pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout->addWidget(label_4);

        newsDateLineEdit = new QLineEdit(widget);
        newsDateLineEdit->setObjectName("newsDateLineEdit");
        newsDateLineEdit->setStyleSheet(QString::fromUtf8("font: 700 14pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout->addWidget(newsDateLineEdit);

        label_5 = new QLabel(widget);
        label_5->setObjectName("label_5");
        label_5->setStyleSheet(QString::fromUtf8("font: 700 14pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout->addWidget(label_5);

        newsTitleLineEdit = new QLineEdit(widget);
        newsTitleLineEdit->setObjectName("newsTitleLineEdit");
        newsTitleLineEdit->setStyleSheet(QString::fromUtf8("font: 700 14pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout->addWidget(newsTitleLineEdit);

        widget1 = new QWidget(admin);
        widget1->setObjectName("widget1");
        widget1->setGeometry(QRect(230, 550, 281, 47));
        horizontalLayout_2 = new QHBoxLayout(widget1);
        horizontalLayout_2->setObjectName("horizontalLayout_2");
        horizontalLayout_2->setContentsMargins(0, 0, 0, 0);
        label_2 = new QLabel(widget1);
        label_2->setObjectName("label_2");
        label_2->setStyleSheet(QString::fromUtf8("font: 700 20pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout_2->addWidget(label_2);

        horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);

        horizontalLayout_2->addItem(horizontalSpacer);

        newsButton = new QPushButton(widget1);
        newsButton->setObjectName("newsButton");
        newsButton->setStyleSheet(QString::fromUtf8("font: 700 18pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout_2->addWidget(newsButton);

        widget2 = new QWidget(admin);
        widget2->setObjectName("widget2");
        widget2->setGeometry(QRect(770, 550, 311, 43));
        horizontalLayout_4 = new QHBoxLayout(widget2);
        horizontalLayout_4->setObjectName("horizontalLayout_4");
        horizontalLayout_4->setContentsMargins(0, 0, 0, 0);
        label_3 = new QLabel(widget2);
        label_3->setObjectName("label_3");
        label_3->setStyleSheet(QString::fromUtf8("font: 700 20pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout_4->addWidget(label_3);

        horizontalSpacer_2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);

        horizontalLayout_4->addItem(horizontalSpacer_2);

        classButton = new QPushButton(widget2);
        classButton->setObjectName("classButton");
        classButton->setStyleSheet(QString::fromUtf8("font: 700 18pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout_4->addWidget(classButton);

        widget3 = new QWidget(admin);
        widget3->setObjectName("widget3");
        widget3->setGeometry(QRect(520, 10, 371, 43));
        horizontalLayout_5 = new QHBoxLayout(widget3);
        horizontalLayout_5->setObjectName("horizontalLayout_5");
        horizontalLayout_5->setContentsMargins(0, 0, 0, 0);
        label = new QLabel(widget3);
        label->setObjectName("label");
        label->setStyleSheet(QString::fromUtf8("font: 700 20pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout_5->addWidget(label);

        horizontalSpacer_3 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);

        horizontalLayout_5->addItem(horizontalSpacer_3);

        stuScoreButton = new QPushButton(widget3);
        stuScoreButton->setObjectName("stuScoreButton");
        stuScoreButton->setStyleSheet(QString::fromUtf8("font: 700 18pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));

        horizontalLayout_5->addWidget(stuScoreButton);


        retranslateUi(admin);

        QMetaObject::connectSlotsByName(admin);
    } // setupUi

    void retranslateUi(QWidget *admin)
    {
        admin->setWindowTitle(QCoreApplication::translate("admin", "Form", nullptr));
        label_6->setText(QCoreApplication::translate("admin", "\346\227\245\346\234\237", nullptr));
        label_7->setText(QCoreApplication::translate("admin", "\346\240\207\351\242\230", nullptr));
        label_4->setText(QCoreApplication::translate("admin", "\346\227\245\346\234\237", nullptr));
        label_5->setText(QCoreApplication::translate("admin", "\346\240\207\351\242\230", nullptr));
        label_2->setText(QCoreApplication::translate("admin", "\345\205\254\345\221\212\347\256\241\347\220\206", nullptr));
        newsButton->setText(QCoreApplication::translate("admin", "\345\217\221\345\270\203", nullptr));
        label_3->setText(QCoreApplication::translate("admin", "\347\217\255\347\272\247\344\277\241\346\201\257\347\256\241\347\220\206", nullptr));
        classButton->setText(QCoreApplication::translate("admin", "\345\217\221\345\270\203", nullptr));
        label->setText(QCoreApplication::translate("admin", "\345\255\246\347\224\237\346\210\220\347\273\251\347\256\241\347\220\206", nullptr));
        stuScoreButton->setText(QCoreApplication::translate("admin", "\345\217\221\345\270\203", nullptr));
    } // retranslateUi

};

namespace Ui {
    class admin: public Ui_admin {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_ADMIN_H

myModel.cpp

#include "myModel.h"

myModel::myModel(QObject *parent, const QSqlDatabase &db)
    : QSqlTableModel{parent, db}
{}

myModel::~myModel()
{
    qDebug() << "~myModel";
}

Qt::ItemFlags myModel::flags(const QModelIndex &index) const
{
    if (index.column() == 0 || index.column() == 2)
    {
        return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    }
    else
    {
        return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
    }
}

myModel.h

#ifndef MYMODEL_H
#define MYMODEL_H

#include <QObject>
#include <QSqlTableModel>

class myModel : public QSqlTableModel
{
    Q_OBJECT
  public:
    explicit myModel(QObject *parent = nullptr,
                     const QSqlDatabase &db = QSqlDatabase());

    ~myModel();
    Qt::ItemFlags flags(const QModelIndex &index) const override;

  signals:
};

#endif // MYMODEL_H


总结

一 Qt是什么
二 Qt开发工具链
三 Qt编程涉及的术语和名词
四 Qt Creator使用
五 Hello Qt!
六 Qt控件和事件
七 Qt信号和槽
八 Qt自定义信号和槽
九 QObject基类
十 QWidget基类
十一 QMainWindow类
十二 QLabel文本框
十三 QPushButton按钮
十四 QLineEdit单行输入框
十五 QListWidget列表框
十六 QTableWidget表格控件
十七 QTreeWidget树形控件
十八 QMessageBox消息对话框
十九 Qt布局管理
二十 QTcpSocket QTcpServer网络库
服务端代码:
客户端代码
二十一 QProcess进程类
二十二 QThread线程
二十三 QSqlDatabase数据库
二十四 cmake工程管理文件
二十五 QFile文件操作
二十六 学生信息管理系统
插入介绍: QTableViewQSqlTableModel
QTableView
QSqlTableModel
程序所用数据库表格
程序组成以及界面
学生端源码:
管理员端源码:


点击 <C 语言编程核心突破> 快速C语言入门


  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不停感叹的老林_<C 语言编程核心突破>

不打赏的人, 看完也学不会.

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值