QT数据库编程

news2024/11/19 14:31:19

ui界面

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QButtonGroup>
#include <QFileDialog>
#include <QMessageBox>
MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //    this->setCentralWidget(ui->splitter);
    ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection); //设置择的模式只可以选中一个
    ui->tableView->setAlternatingRowColors(true); //设置不同行颜色
    //设置分组
    QButtonGroup* group = new QButtonGroup(this);
    group->addButton(ui->radioButton);
    group->addButton(ui->radioButton_2);
}

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

void MainWindow::on_pushButton_clicked()
{
    QString file = QFileDialog::getOpenFileName(this, "选择文件", "../", "SQLITE(*.*)");
    if (file.isEmpty())
        return;
    db = QSqlDatabase::addDatabase("QSQLITE"); //添加驱动
    db.setDatabaseName(file); //加入文件
    if (!db.open())
        QMessageBox::warning(this, "错误", "打开失败");
    else {
        openTable(); //打开数据库表格
    }
    qDebug() << "完成";
}

void MainWindow::do_current_changed(const QModelIndex& current, const QModelIndex&)
{
    Q_UNUSED(current);
    qDebug() << "当前改变";
    ui->pushButton_8->setEnabled(tabModel->isDirty()); //是改过的
}

void MainWindow::do_current_row_changed(const QModelIndex& current, const QModelIndex&)
{
    qDebug() << "点击了单元格";
    if (!current.isValid()) {
        ui->label_10->clear();
        return;
    }
    ui->pushButton_8->setEnabled(true);
    //映射
    dataMapper->setCurrentIndex(current.row());

    QSqlRecord curRecord = tabModel->record(current.row());
    if (!curRecord.isEmpty()) {
        qDebug() << "数据" << curRecord;
    }
}

void MainWindow::openTable()
{
    //创建模型,打开数据库表格
    tabModel = new QSqlTableModel(this, db);
    tabModel->setTable("test"); //设置数据库表名称
    tabModel->setEditStrategy(QSqlTableModel::OnManualSubmit); //手动提交
    tabModel->setSort(tabModel->fieldIndex("id"), Qt::DescendingOrder); //按id 降序排序, 升序 AscendingOrder
    if (!tabModel->select()) {
        QMessageBox::critical(this, "错误", tabModel->lastError().text());
    }
    ui->statusbar->showMessage(QString("记录条数为 %1").arg(tabModel->rowCount()));
    //设置字段显示的标题
    tabModel->setHeaderData(tabModel->fieldIndex("id"), Qt::Horizontal, "ID号");
    tabModel->setHeaderData(tabModel->fieldIndex("name"), Qt::Horizontal, "姓名");
    // model /view
    selModel = new QItemSelectionModel(tabModel, this);

    ui->tableView->setModel(tabModel);
    ui->tableView->setSelectionModel(selModel); //注意:必须先设置模型在设置选择模型,否则不生效

    //    ui->tableView->setColumnHidden(tabModel->fieldIndex("id"), true); //隐藏数据

    //代理
    QStringList str;
    str << "男"
        << "女";
    delegateSex.setItems(str, false);
    ui->tableView->setItemDelegateForColumn(tabModel->fieldIndex("name"), &delegateSex);
    //字段与widget映射
    dataMapper = new QDataWidgetMapper(this);
    dataMapper->setModel(tabModel);
    dataMapper->setSubmitPolicy(QDataWidgetMapper::AutoSubmit); //数据自动提交
    dataMapper->addMapping(ui->spinBox, tabModel->fieldIndex("id"));
    dataMapper->addMapping(ui->lineEdit, tabModel->fieldIndex("name"));
    dataMapper->toFirst(); //显示第一条记录
    // 状态发生变化
    //    ui->pushButton->setEnabled(false);
    //获取字段名更新
    QSqlRecord emptyRec = tabModel->record();
    qDebug() << "emptyRec = " << emptyRec;
    for (int i = 0; i < emptyRec.count(); ++i) {
        ui->comboBox->addItem(emptyRec.fieldName(i));
    }
    //信号连接
    connect(selModel, &QItemSelectionModel::currentChanged, this, &MainWindow::do_current_changed);
    connect(selModel, &QItemSelectionModel::currentRowChanged, this, &MainWindow::do_current_row_changed);
}

void MainWindow::on_pushButton_3_clicked()
{
    QModelIndex index = ui->tableView->currentIndex();
    QSqlRecord rec = tabModel->record();
    rec.setValue(tabModel->fieldIndex("name"), "王五");
    tabModel->insertRecord(index.row(), rec);

    selModel->clearSelection();
    selModel->setCurrentIndex(tabModel->index(tabModel->rowCount() - 1, 1), QItemSelectionModel::Select);
    //更新状态栏
    ui->statusbar->showMessage(QString("记录条数为 %1").arg(tabModel->rowCount()));
}

void MainWindow::on_pushButton_2_clicked()
{
    QSqlRecord rec = tabModel->record();
    rec.setValue(tabModel->fieldIndex("name"), "王五");

    tabModel->insertRecord(tabModel->rowCount(), rec);

    selModel->clearSelection();
    selModel->setCurrentIndex(tabModel->index(tabModel->rowCount() - 1, 1), QItemSelectionModel::Select);
    //更新状态栏
    ui->statusbar->showMessage(QString("记录条数为 %1").arg(tabModel->rowCount()));
}

void MainWindow::on_pushButton_4_clicked()
{
    QModelIndex index = ui->tableView->currentIndex();
    tabModel->removeRow(index.row());
    ui->statusbar->showMessage(QString("记录条数为 %1").arg(tabModel->rowCount()));
}

void MainWindow::on_pushButton_5_clicked()
{
    QString aFile = QFileDialog::getOpenFileName(this, "选择图片", "", "(*.jpg)");
    if (aFile.isEmpty())
        return;
    QFile* file = new QFile(aFile, this);
    if (file->open(QIODevice::ReadOnly)) {
        QByteArray arr = file->readAll();
        file->close();
        QSqlRecord rec = tabModel->record(selModel->currentIndex().row());
        rec.setValue("photh", arr); //设置数据
        tabModel->setRecord(selModel->currentIndex().row(), rec); //设置行数据
        QPixmap pix;
        pix.load(aFile); //加载图片
        ui->label_10->setPixmap(pix.scaledToWidth(pix.width()));
    }
}

void MainWindow::on_pushButton_6_clicked()
{
    QSqlRecord rec = tabModel->record(selModel->currentIndex().row());
    rec.setNull("photh");
    tabModel->setRecord(selModel->currentIndex().row(), rec);
    ui->label_10->clear();
}

void MainWindow::on_pushButton_7_clicked()
{
    if (tabModel->rowCount() == 0)
        return;
    for (int i = 0; i < tabModel->rowCount(); ++i) {
        QSqlRecord rec = tabModel->record(i);
        rec.setValue("name", rec.value("name").toInt() + 100);
        tabModel->setRecord(i, rec);
    }
    if (tabModel->submitAll()) { // submit不成功,需要all
        QMessageBox::information(this, "成功", "涨工资成功");
    }
}

void MainWindow::on_pushButton_8_clicked()
{
    bool ret = tabModel->submitAll();
    if (!ret) {
        QMessageBox::critical(this, "失败", "保存失败");
    }
}

void MainWindow::on_pushButton_9_clicked()
{
    tabModel->revertAll(); //还原
}

void MainWindow::on_comboBox_currentIndexChanged(int index)
{
    if (ui->radioButton->isChecked()) {
        tabModel->sort(index, Qt::AscendingOrder);
    } else {
        tabModel->sort(index, Qt::DescendingOrder);
    }
    tabModel->select();
}

void MainWindow::on_radioButton_clicked()
{
    try {
        tabModel->sort(ui->comboBox->currentIndex(), Qt::AscendingOrder); // sort不需要select
    } catch (QException err) {
        qDebug() << err.what();
    }
}

void MainWindow::on_radioButton_2_clicked()
{
    try {
        tabModel->sort(ui->comboBox->currentIndex(), Qt::DescendingOrder); // sort不需要select
    } catch (QException err) {
        qDebug() << err.clone();
    }
}

void MainWindow::on_radioButton_3_clicked()
{
    tabModel->setFilter("name='12'");
    ui->statusbar->showMessage(QString("记录条数为 %1").arg(tabModel->rowCount()));
}

void MainWindow::on_radioButton_4_clicked()
{
    tabModel->setFilter("name='张三'");
    ui->statusbar->showMessage(QString("记录条数为 %1").arg(tabModel->rowCount()));
}

void MainWindow::on_radioButton_5_clicked()
{
    tabModel->setFilter("");
    ui->statusbar->showMessage(QString("记录条数为 %1").arg(tabModel->rowCount()));
}

 mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include "tcomboxdelegate.h"
#include <QDataWidgetMapper>
#include <QMainWindow>
#include <QSql>
#include <QSqlTableModel>
#include <QtSql>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE

class MainWindow : public QMainWindow {
    Q_OBJECT

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

private slots:
    void on_pushButton_clicked();
    void do_current_changed(const QModelIndex& current, const QModelIndex& previous);
    void do_current_row_changed(const QModelIndex& current, const QModelIndex& previous);

    void on_pushButton_3_clicked();

    void on_pushButton_2_clicked();

    void on_pushButton_4_clicked();

    void on_pushButton_5_clicked();

    void on_pushButton_6_clicked();

    void on_pushButton_7_clicked();

    void on_pushButton_8_clicked();

    void on_pushButton_9_clicked();

    void on_comboBox_currentIndexChanged(int index);

    void on_radioButton_clicked();

    void on_radioButton_2_clicked();

    void on_radioButton_3_clicked();

    void on_radioButton_4_clicked();

    void on_radioButton_5_clicked();

private:
    Ui::MainWindow* ui;
    QSqlTableModel* tabModel;
    QDataWidgetMapper* dataMapper;
    QItemSelectionModel* selModel;
    QSqlDatabase db;

    TComBoxDelegate delegateSex;
    TComBoxDelegate deleagteDepart;

    void openTable();
};
#endif // MAINWINDOW_H

tcomboxdelegate.cpp

#include "tcomboxdelegate.h"
#include <QComboBox>
TComBoxDelegate::TComBoxDelegate(QObject* parent)
    : QStyledItemDelegate { parent }
{
}
QWidget* TComBoxDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
    QComboBox* editor = new QComboBox(parent);
    editor->setEditable(m_editable);
    qDebug() << m_itemList.size();
    for (auto item : m_itemList) {
        editor->addItem(item);
    }
    return editor;
}

void TComBoxDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
{
    QComboBox* box = dynamic_cast<QComboBox*>(editor); //把editor转为指向QSpinBox的指针 动态强转
    QString value = index.model()->data(index, Qt::DisplayRole).toString();
    box->setCurrentText(value);
}

void TComBoxDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
{
    QComboBox* box = dynamic_cast<QComboBox*>(editor); //把editor转为指向QSpinBox的指针 动态强转
    QString value = box->currentText();
    model->setData(index, value);
}

void TComBoxDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
    editor->setGeometry(option.rect);
}

void TComBoxDelegate::setItems(QStringList list, bool editabale)
{
    m_itemList = list;
    m_editable = editabale;
}

tcomboxdelegate.h

#ifndef TCOMBOXDELEGATE_H
#define TCOMBOXDELEGATE_H

#include <QObject>
#include <QStyledItemDelegate>

class TComBoxDelegate : public QStyledItemDelegate {
    Q_OBJECT
public:
    explicit TComBoxDelegate(QObject* parent = nullptr);

    // QAbstractItemDelegate interface
public:
    virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
    virtual void setEditorData(QWidget* editor, const QModelIndex& index) const override;
    virtual void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override;
    virtual void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
    void setItems(QStringList list, bool editabale);

private:
    QStringList m_itemList;
    bool m_editable;
};

#endif // TCOMBOXDELEGATE_H

QSqlQueryModel模块使用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/813215.html

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

相关文章

递归算法判断是否是“平衡二叉树”

题目&#xff1a; 给定一个二叉树&#xff0c;判断它是否是高度平衡的二叉树。 本题中&#xff0c;一棵高度平衡二叉树定义为&#xff1a; 一个二叉树每个节点的左右两个子树的高度差的绝对值不超过1 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;true 解…

【Unity2D】粒子特效

为什么要使用粒子特效 Unity 的粒子系统是一种非常强大的工具&#xff0c;可以用来创建各种各样的游戏特效&#xff0c;如火焰、烟雾、水流、爆炸等等。使用粒子特效可以使一些游戏动画更加真实或者使游戏效果更加丰富。 粒子特效的使用 在Hierarchy界面右键添加Effects->…

ICASSP 2023 | Cough Detection Using Millimeter-Wave FMCW Radar

原文链接&#xff1a;https://mp.weixin.qq.com/s?__bizMzg4MjgxMjgyMg&mid2247486540&idx1&sn6ebd9f58e9f08a369904f9c48e12d136&chksmcf51beb5f82637a3c65cf6fa53e8aa136021e35f63a58fdd7154fc486a285ecde8b8521fa499#rd ICASSP 2023 | Cough Detection Usi…

【Golang 接口自动化01】使用标准库net/http发送Get请求

目录 发送Get请求 响应信息 拓展 资料获取方法 发送Get请求 使用Golang发送get请求很容易&#xff0c;我们还是使用http://httpbin.org作为服务端来进行演示。 package mainimport ("bytes""fmt""log""net/http""net/url&qu…

vue基础-key的作用

vue基础-key的作用 1、无key2、有key&#xff0c;值为索引3、有key&#xff0c;值为id 1、无key 最大限度尝试就地修改/复用相同类型元素 2、有key&#xff0c;值为索引 有key属性&#xff0c;基于key来比较新旧虚拟DOM&#xff0c;移除key不存在的元素 3、有key&#xf…

学习笔记——压力测试案例,监控平台

测试案例 # 最简单的部署方式直接单机启动 nohup java -jar lesson-one-0.0.1-SNAPSHOT.jar > ./server.log 2>&1 &然后配置执行计划&#xff1a; 新建一个执行计划 配置请求路径 配置断言配置响应持续时间断言 然后配置一些查看结果的统计报表或者图形 然后我…

一篇文章彻底搞懂TCP协议!

文章目录 1. TCP协议的引入2. TCP协议的特点3. TCP协议格式3.1 序号与确认序号3.2 发送缓冲区与接收缓冲区3.3 窗口大小3.4 六个标志位 4. 确认应答机制5. 超时重传机制6. 连接管理机制6.1 三次握手6.2 四次挥手 7. 流量控制8. 滑动窗口9. 拥塞控制10. 延迟应答11. 捎带应答12.…

FFmpeg5.0源码阅读——av_interleaved_write_frame

摘要&#xff1a;本文主要详细描述FFmpeg中封装时写packet到媒体文件的函数av_interleaved_write_frame的实现。   关键字&#xff1a;av_interleaved_write_frame   读者须知&#xff1a;读者需要熟悉ffmpeg的基本使用。 1 基本调用流程 av_interleaved_write_frame的基本…

python文件处理方式

python文件处理方式 file open(D:\pythonText.txt, r, encodingUTF-8) print(file) # <_io.TextIOWrapper nameD:\\pythonText.txt moder encodingUTF-8> print(type(file)) # <class _io.TextIOWrapper>读取文件 file open(D:\pythonText.txt, r, encodingU…

【C++】 虚析构和纯虚析构,Visual Studio开发人员工具查看类内部结构cl /d1 reportSingleClassLayout

author&#xff1a;&Carlton tag&#xff1a;C topic&#xff1a;【C】 虚析构和纯虚析构&#xff0c;Visual Studio开发人员工具查看类内部结构cl /d1 reportSingleClassLayout website&#xff1a;黑马程序员C date&#xff1a;&#xff1a;2023年7月29日 目录 虚析构…

No106.精选前端面试题,享受每天的挑战和学习

今日份摘抄&#xff1a;本事不在自身都是虚的 文章目录 MySQL的ACID特性分别是怎么实现的&#xff1f;1. 原子性 (Atomicity)2. 一致性 (Consistency)3. 隔离性 (Isolation)4. 持久性 (Durability) OSI七层模型1. 物理层&#xff08;Physical Layer&#xff09;2. 数据链路层&a…

Java-简单认识类和对象

一、初步认识面向对象 1.1 什么是面向对象 Java是一门纯面向对象的语言(Object Oriented Program&#xff0c;简称OOP)&#xff0c;在面向对象的世界里&#xff0c;一切皆为对象。面向对象是解决问题的一种思想&#xff0c;主要依靠对象之间的交互完成一件事情。用面向对象的思…

map,set的封装(基于改造红黑树)

目录 引言 1.迭代器 2.map的[]重载 3.KeyOfValue模板参数 4.整体代码展示 //改造后的红黑树代码 #include <iostream> using namespace std;enum Colour {RED 0,BLACK, };//为了实现map与set封装使用同一个模板红黑树&#xff0c;前者的value是pair&#xff0c;后者…

数学分析:外微分

先回顾下微分的概念&#xff0c;首先我们找到一个道路x&#xff0c;它是关于时间t的函数&#xff0c;然后我们可以得到一个速度&#xff0c;也就是切向量&#xff0c;所有道路的切向量组成了切空间。如果从泛函角度来理解&#xff0c;它应该是一个求偏导的基。是一个向量。而微…

Python语法(二、内置函数)

数学计算库 Python ​math ​模块提供了许多对浮点数的数学运算函数。 Python ​cmath ​模块包含了一些用于复数运算的函数。 import math 内置函数 关键字 自定义函数 Python函数的定义。定义函数需要用def 关键字实现&#xff0c;具体的语法格式如下&#xff1a; def 函…

求二维离散点集的凸包点

1 算法思路 这类求解最外围的点集问题,我们称之为凸包问题,光光是⽤⾁眼去观察的话,这种问题我们很快就能得出答案,并且能马上说出哪⼏个点 是解,但是如果让你敲代码,去解决这类的问题,可能很多⼈会不知道如何去下⼿。 在讲解凸包这类问题的解法前,我们⾸先要先讲下向…

#P1000. [NOIP2008普及组] 立体图

题目描述 小渊是个聪明的孩子&#xff0c;他经常会给周围的小朋友们讲些自己认为有趣的内容。最近&#xff0c;他准备给小朋友们讲解立体图&#xff0c;请你帮他画出立体图。 小渊有一块面积为 m \times nmn 的矩形区域&#xff0c;上面有 m \times nmn 个边长为 11 的格子&a…

Linux环境安装MySQL(详细教程)

1、下载MySQL MySQL官网&#xff1a;MySQLhttps://www.mysql.com/ 下载社区版&#xff08;免费&#xff0c;但不提供技术支持&#xff09; 简单说明一下rpm和tar包的区别&#xff1a; tar 只是一种压缩文件格式&#xff0c;所以&#xff0c;它只是把文件压缩打包 rpm&#xf…

HTML+CSS前端 简易用户登录界面

Day1 刚学了一些html和css的简单语法&#xff0c;尝试写一个非常简易的静态用户登录界面。 login_simple.html <!DOCTYPE html> <html lang"en"><head><meta name"viewport" content"widthdevice-width,initial-scale1.0"…

C++复刻:[流光按钮]+[悬浮波纹按钮]

目录 参考效果实现main.cppdialog.hdialog.cppflowingRayButton.h 流动光线按钮flowingRayButton.cpp 流动光线按钮hoveringRippleButton.h 悬浮波纹按钮hoveringRippleButton.cpp 悬浮波纹按钮模糊知识点 源码 参考 GitHub地址 B站主页 效果 实现 main.cpp #include "…