《Qt应用开发》笔记p5

QMainWindow (主窗口)

Qt的 QMainWindow 用于创建具有标准组件的桌面应用程序,是构建复杂桌面应用程序用户界面的基础。

特点:

  1. 标准化结构
  2. 提高开发效率
  3. 功能清晰。

五个常用的部分:

  1. 菜单栏 Menu Bar
  2. 工具条 Tool Bar
  3. 停靠部件 Dock Widgets
  4. 中心部件 Central Widget
  5. 状态栏 Status Bar

图示:

模式对话框

模式对话框是指独占所有输入的对话框,在此对话框结束之前,所有的对话框都禁止使用的对话框。

消息对话框

消息对话框属于模式对话框。

复制代码
QMessageBox::question  // 带问号图标的对话框
QMessageBox::information  // 带蓝色叹号的对话框
QMessageBox::warning  // 带红色叹号的对话框
QMessageBox::critical // 带致命错误图标的对话框

QFileDialog 对话框

Qt 提供的一些标准的对话框,如文件操作对话框(QFileDialog等)方便用户调用并获取信息。

复制代码
QFileDialog(
QWidget *parent = nullptr,
const QString &caption = QString(),
const QString &directory = QString(),
const QString &filter = QString()
)

QDialog 对话框

QDialog 对话框是模式对话框的基类,用它可以自定义模式和非模式对话框。

QDialog 的槽函数有:

复制代码
// 接受(返回QDialog::Accepted --> 1)
virtual void  accept()
// 返回 自定义的值。
virtual void  done(int r) 
virtual int exec() // 显示为模式对话框
// 拒绝(QDialog::Rejected --> 0)
virtual void reject()

SQLite 数据库

数据库介绍

数据库从字面意思解释就是存储数据的仓库。

数据库按存储数据的方式可以分为:

  • 关系型数据库

    • 以数据表的形式存储,表和表之间建立逻辑关系,如:
    • Oracle、MySQL、SQLite等。
  • 非关系型数据库

    • 以键值对或字典等方式存储,如:

      • Redis、MongoDB等。

数据表 table

  • 列:字段(每个字段有统一的数据类型),各个字段的类型可以不同。
  • 行:记录,用于记录数据,每一行称之为一条数据。
  • 数据表:有行列组成。

数据表student

ID 姓名 年龄
1 张三 18
2 李四 19
复制代码
INSERT INTO student VALUES(1, "张三", 18);
INSERT INTO student(name, age, id) VALUES("李四", 19, 2);
SELECT * FROM student;

数据表科目 subject

id 科目
1 语文
2 数学
复制代码
INSERT INTO sub VALUES(1, "语文");
INSERT INTO sub VALUES(2, "数学");
SELECT * FROM sub;

数据表 score

id 学生 ID 科目ID 成绩
1 1 1 100
2 1 2 88
3 2 1 99
4 2 2 66
复制代码
INSERT INTO scr VALUES(1, 1, 1, 100);
INSERT INTO scr VALUES(2, 1, 2, 88);
INSERT INTO scr VALUES(3, 2, 1, 99);
INSERT INTO scr VALUES(4, 2, 2, 66);
SELECT * FROM scr;

SQLite 数据库简介

SQLite 是一个轻量级的关系型数据库

SQLite = SQL + Lite

SQL(Structured Query Language) 是结构化查询语言。

Lite 是轻量的意思。

SQLite专门为嵌入式设计,仅仅需要几百K内存就可以运行。

SQLite 支持多个操作系统:Windows,Linux,UNIX等。

SQLite 数据库是遵守ACID规则的数据库。

ACID是数据库管理的四个特征

  1. 原子性(Atomicity)

    • 支持事务操作,要么全部执行,要么都不执行。
  2. 一致性(Consistency)

    • 在事务开始前和事务结束后,数据库是完整的,没有给破坏过。
  3. 隔离性(Isolation)

    • 允许多个事务进行并发的对数据库进行读写和修改,隔离性可以防止在并发执行时导致数据的不一致性。
  4. 持久性(Durability)

    • 在事务完成后,对于数据库的修改会持久的保存在数据库中,并不会被恢复。

安装 SQLite

复制代码
sudo apt install sqlite3 libsqlite3-dev -y

SQLite3 官网 https://www.sqlite.org/

使用 sqlite3 命令来操作数据库

复制代码
sqlite3 [数据库文件名]

示例

复制代码
$ sqlite3 test.db 
SQLite version 3.31.1 2020-01-27 19:55:54
Enter ".help" for usage hints.
sqlite> 

SQLite3 控制台的基本操作

复制代码
.version // 查看数据库的版本信息
.help    // 查看所有的SQLite命令
.quit/.exit  //  退出数据库控制台
.print       // 打印一些信息
.tables      // 查看当前数据库中的所有数据表。
.schema [数据表]  // 查看数据表的创建结构。

SQLite3数据库基础数据类型

存储类 说明 常见声明的类型
NULL 空值
INTEGER 带符号整数 INTEGER, INT, BIGINT, TINYINT
REAL 浮点数 REAL, FLOAT, DOUBLE
TEXT 文本字符串 TEXT, VARCHAR(N), CHAR(N), CLOB
BLOB 二进制数据 BLOB(如果没有声明类型,默认也是 BLOB)

SQL 语言的语句的两种类型

  • DDL(数据定义语言)
  • DML(数据操作语言)

SQL 语句的关键字不区分大小写,即(CREATE、create 和CrEaTe都是一样的)

DDL(数据定义语言)-- 用来操作数据表

DDL用于定义和管理数据库的结构,包括创建、修改和删除数据库对象(如表)

创建数据表的SQL语句

复制代码
-- 格式
CREATE TABLE 表名(字段名1 字段数据类型1,字段名2 字段数据类型2,...);

示例

复制代码
CREATE TABLE student(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER); 
CREATE TABLE sub(id INTEGER PRIMARY KEY AUTOINCREMENT, subject VARCHAR(20) NOT NULL UNIQUE);
CREATE TABLE scr(id INTEGER PRIMARY KEY AUTOINCREMENT, stu_id INTEGER, sub_id INTEGER, score INT);

SQL 中的约束关键字

复制代码
NOT NULL    // 非空(不允许没有值)
UNIQUE      // 唯一(字段内不允许重复)
PRIMARY KEY // 主键(非空且唯一,通常作为唯一标识使用)
AUTOINCREMENT // 整数值自动递增。

删除数据表的SQL语句

复制代码
DROP TABLE 表名

示例

复制代码
DROP TABLE student;
DROP TABLE scr;
DROP TABLE sub;

DML 数据操作语言 -- 用来操作数据记录的

DML包括的命令有

  • INSERT - 插入记录
  • UPDATE - 更新(修改)记录的值
  • DELETE - 删除记录
  • SELECT - 查询记录

插入数据记录 INSERT

作用:向数据表中插入记录

语法格式

复制代码
INSERT INTO 数据表名(字段名1, 字段名2,...) VALUES(字段数据1,字段数据2,...);
// 或
INSERT INTO 数据表名 VALUES(字段数据1,字段数据2,...);

示例

复制代码
INSERT INTO student(id, name, age) VALUES(1, "zhang3", 18);
INSERT INTO student(name, age) VALUES('li4', 19);
INSERT INTO student VALUES(3, 'wang5', 17);

查询记录 SELECT

作用:用于查询记录

语法规则

复制代码
SELECT 字段名1, 字段名2, ... FROM 表名;
SELECT * FROM 表名;
SELECT 字段名1, 字段名2, ...  FROM 表名 WHERE 条件;

示例

复制代码
SELECT * FROM student;
SELECT name, age FROM student;
SELECT name FROM student;
SELECT name, age, id FROM student;
// 查询 年龄小于 18 周岁的学生的姓名和年龄
SELECT name,age FROM student WHERE age < 18;

修改数据记录 UPDATE

作用:修改指定条件的数据记录的某个字段的值

语法规则

复制代码
UPDATE 表名 SET 字段名1=字段值1, 字段名2=字段值2, ... WHERE 条件;

示例

复制代码
// 修改ID 为 1 的用户的 姓名为 张三丰 年龄为 19 周岁
UPDATE student SET name="张三丰",age=19 WHERE id=1;

SQL 中的比较运算

复制代码
>        大于
>=       大于等于  
<        小于
<=       小于等于  
=         等于
!=   <>   不等于

SQL 中的逻辑运算

复制代码
AND 与运算
OR  或运算
NOT 非运算

删除记录 DELETE

作用:删除指定条件的数据记录。

语法规则

复制代码
DELETE FROM 表名 WHERE 条件;

示例

复制代码
// 删除 ID 为 1 的用户
DELETE FROM student WHERE id=1;
// 删除所有记录但不删除数据表
DELETE FROM student;

Linux 下SQLite数据的查询工具 sqlitebrowser

复制代码
# 安装方法
sudo apt install sqlitebrowser
# 运行方法
sqlitebrowser SQLite.db文件

联合UNION查询

复制代码
// 查询 所有 成绩中大于 80 的成绩
SELECT * FROM scr WHERE score >80;
// 查询 所有 成绩中大于 80 的语文成绩
SELECT * FROM scr WHERE score >80 and sub_id = 1;

// 将三张表拼接成一张大表
SELECT * FROM scr
 JOIN student
 ON scr.stu_id = student.id
 JOIN sub ON scr.sub_id = sub.id;

// 查询 语文 成绩中大于 80 的学生姓名
SELECT name, subject, score FROM scr
 JOIN student
 ON scr.stu_id = student.id
 JOIN sub ON scr.sub_id = sub.id
 WHERE subject="语文" and score >80;
 

// 查询 数学 成绩中大于 80 的学生姓名
SELECT name, subject, score FROM scr
 JOIN student
 ON scr.stu_id = student.id
 JOIN sub ON scr.sub_id = sub.id
 WHERE subject="数学" and score >80; 

笛卡尔积图示

SQLite3 的C语言接口

详见:/usr/include/sqlite3.h 文件

相关函数

复制代码
sqlite3_open()
sqlite3_exec();
sqlite3_close()

sqlite3_step() 
sqlite3_prepare()

示例

复制代码
#include <stdio.h>
#include <sqlite3.h>

static int callback(void *NotUsed, int argc, char **argv, char **azColName){
  int i;
  for(i=0; i<argc; i++){
    printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
  }
  printf("\n");
  return 0;
}

int main(int argc, char **argv){
  sqlite3 *db;
  char *zErrMsg = 0;
  int rc;

  if( argc!=3 ){
    fprintf(stderr, "Usage: %s DATABASE SQL-STATEMENT\n", argv[0]);
    return(1);
  }
  rc = sqlite3_open(argv[1], &db);
  if( rc ){
    fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
    sqlite3_close(db);
    return(1);
  }
  rc = sqlite3_exec(db, argv[2], callback, 0, &zErrMsg);
  if( rc!=SQLITE_OK ){
    fprintf(stderr, "SQL error: %s\n", zErrMsg);
    sqlite3_free(zErrMsg);
  }
  sqlite3_close(db);
  return 0;
}

编译

复制代码
gcc 01_sqlite_demo.cpp -lsqlite3

运行

复制代码
./a.out test.db "SELECT * FROM student;"
或
./a.out test.db "SELECT * FROM sub;"

SQLite 的Qt接口

Qt 提供了两个类 QSqlDatabase 和 QSqlQuery 用于数据库操作,

他们的作用如下:

  • QSqlDatabase 用于连接数据库。
  • QSqlQuery 用于查询操作

使用步骤:

  1. 在 .pro 项目文件中加入:QT += sql 来让数据库模块参加编译
  2. 使用QSqlDatabase 连接数据库,并检测连接是否正常。
  3. 使用 QSqlQuery 调用 SQL 语句进行查询等 DML 操作并得到结果。

示例

sqlitewidget.h

复制代码
#ifndef SQLITEWIDGET_H
#define SQLITEWIDGET_H

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

class SQLiteWidget : public QWidget
{
    Q_OBJECT
public:
    SQLiteWidget(QWidget *parent = nullptr);
    ~SQLiteWidget();
protected:
    void initSqlite(void);
    void initUI(void);
    void onSqlExecBtn(void);
private:
    QTextEdit * textEdit; // 用于输入SQL 语句
    QSqlDatabase db;   // 用于记录数据库连接
};

#endif // SQLITEWIDGET_H

sqlitewidget.cpp

复制代码
#include <QVBoxLayout>
#include <QPushButton>
#include <QDebug>

#include "sqlitewidget.h"

SQLiteWidget::SQLiteWidget(QWidget *parent)
    : QWidget(parent)
{
    initSqlite();
    initUI();
}

SQLiteWidget::~SQLiteWidget()
{
}

void SQLiteWidget::initSqlite(void)
{
    // 添加SQLITE 数据库引擎,并生成数据库对象db
    db = QSqlDatabase::addDatabase("QSQLITE");
    // 连接 test.db 数据库。
    db.setDatabaseName("../test.db");
    // 打开数据库,并判断是否成功连接
    if (db.open()) {
        qDebug() << "数据库连接成功!";
    } else {
        qDebug() << "数据库连接失败!";
    }

}
void SQLiteWidget::initUI(void)
{
    textEdit = new QTextEdit;
    textEdit->setPlaceholderText("请输入SQL语句");
    QPushButton * btn = new QPushButton("运行SQL");

    QVBoxLayout * vlayout = new QVBoxLayout(this);
    vlayout->addWidget(textEdit);
    vlayout->addWidget(btn);

    connect(btn, &QPushButton::pressed,
            this, &SQLiteWidget::onSqlExecBtn);
}
void SQLiteWidget::onSqlExecBtn(void)
{
    // 获取用户输入的信息的纯文本。
    QString sql = textEdit->toPlainText();
    qDebug() << sql;
    // 创建查询对象
    QSqlQuery query;
    // 执行SQL 语句
    if (!query.exec(sql)) {
        qDebug() << "SQL 语句执行失败!";
        return;
    }
    // qDebug() << "查询到" << query.size() << "条记录!";
    // 遍历每一条数据记录
    while(query.next()) {
        // 根据 列名称返回该条记录对应的列,并转为整数。
        int id = query.value("id").toInt();
        QString name = query.value("name").toString();
        // 根据 列号(列索引)返回该条记录对应的列,并转为整数。
        int age = query.value(2).toInt();
        qDebug() << "id:" << id << "name:" << name
                    << "age:" << age;
    }
}
相关推荐
qq_433554543 小时前
C++ 完全背包时间优化、完全背包空间优化
开发语言·c++·动态规划
海棠蚀omo3 小时前
Linux操作系统-进程(三)
linux·操作系统
yanqiaofanhua3 小时前
C语言自学--编译和链接
c语言·开发语言
周之鸥3 小时前
Qt 项目国际化从零到一:用 Qt Linguist 实现多语言动态切换(含源码与踩坑指南)
qt·i18n·cmake·qmake·linguist·lupdate·lrelease
打码的猿3 小时前
在Qt中实现SwitchButton(开关按钮)
开发语言·qt·ui
友友马3 小时前
『 QT 』QT窗口坐标体系详解
开发语言·qt
cxr8283 小时前
AI智能体赋能金融研究领域之仿真:流动性风暴下的高维战略 —— QT驱动的系统性失位与方舟部署蓝图
人工智能·qt·金融·ai赋能
骑士雄师3 小时前
Java 泛型中级面试题及答案
java·开发语言·面试
hour_go3 小时前
页表 vs. 组相联缓存:内存管理与性能优化的殊途同归
笔记·操作系统·分页·计算机体系结构·tlb·组相联缓存