QT数据库编程

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模块使用

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向)

hello&#xff0c;大家好&#xff0c;这里是bang___bang_ &#xff0c;今天和大家谈谈Linux中的基础IO&#xff0c;包含内容有对应的系统文件I/O接口&#xff0c;文件描述符&#xff0c;理解重定向。 目录 1️⃣初识文件 2️⃣ 系统文件I/O接口 &#x1f359;open &#x1…

小程序学习(五):WXSS模板语法

1.什么是WXSS WXSS是一套样式语言,用于美化WXML的组件样式,类似于网页开发中的CSS 2.WXSS和CSS的关系 WXSS模板样式-rpx 3.什么是rpx尺寸单位 4.rpx的实现原理 5.rpx与px之间的单位换算* WXSS模板样式-样式导入 6.什么是样式导入 使用WXSS提供的import语法,可以导入外联的样式…

华为云低代码平台Astro Canvas 搭建汽车展示大屏——实验指导手册

实验背景 大屏应用Astro Canvas是华为云低代码平台Astro的子服务之一&#xff0c;是以数据可视化为核心&#xff0c;以屏幕轻松编排&#xff0c;多屏适配可视为基础&#xff0c;用户可通过图形化界面轻松搭建专业水准的数据可视化大屏。例如汽车展示大屏、监控大屏、项目开发大…

数据结构——绪论

一、绪论 &#xff08;一&#xff09;基本概念 数据&#xff1a;数据是对客观事物的符号表示&#xff0c;在计算机科学中是指所有能输入到计算机中并被计算机程序处理的符号的总称。 数据元素&#xff1a;数据元素是数据的基本单位&#xff0c;在计算机程序中通常作为一个整…

消息队列总结(4)- RabbitMQ Kafka RocketMQ高性能方案

1.RabbitMQ的高性能解决方案 1.1 发布确认机制 RabbitMQ提供了3种生产者发布确认的模式&#xff1a; 简单模式&#xff08;Simple Mode&#xff09;&#xff1a;生产者发送消息后&#xff0c;等待服务器确认消息已经被接收。这种模式下&#xff0c;生产者发送消息后会阻塞&am…

学习系统编程No.34【线程同步之信号量】

引言&#xff1a; 北京时间&#xff1a;2023/7/29/16:34&#xff0c;一切尽在不言中&#xff0c;前几天追了几部电视剧&#xff0c;看了几部电影&#xff0c;刷了n个视屏&#xff0c;在前天我们才终于从这快乐的日子里恢复过来&#xff0c;然后看了两节课&#xff0c;也就是上…

真机搭建中小网络

这是b站上的一个视频&#xff0c;演示了如何搭建一个典型的中小网络&#xff0c;供企业使用 一、上行端口&#xff1a;上行端口就是连接汇聚或者核心层的口&#xff0c;或者是出广域网互联网的口。也可理解成上传数据的端口。 二、下行端口&#xff1a;连接数据线进行下载的端…

Scratch Blocks自定义组件之「旋律播放」

一、背景 看到microbit edit有旋律编辑器&#xff0c;就在scratch块中也写了一个&#xff0c;如下图所示 这是我写的 这是Micro:bit的 二、功能配置说明 支持8个音符8拍旋律控制 三、使用说明 &#xff08;1&#xff09;引入添加field_tone.js到core文件夹中&#xff0c;代码在…

信息系统网络安全整改方案

第1章 项目概述 1.1 项目目标 本方案将通过对公司网络信息系统的安全现状进行分析工作&#xff0c;参照国家信息系统等级保护要求&#xff0c;找出信息系统与安全等级保护要求之间的差距&#xff0c;给出相应的整改意见&#xff0c;推动 XX 企业公司网络信息系统安全整改工作的…

计算机毕设 深度学习手势识别 - yolo python opencv cnn 机器视觉

文章目录 0 前言1 课题背景2 卷积神经网络2.1卷积层2.2 池化层2.3 激活函数2.4 全连接层2.5 使用tensorflow中keras模块实现卷积神经网络 3 YOLOV53.1 网络架构图3.2 输入端3.3 基准网络3.4 Neck网络3.5 Head输出层 4 数据集准备4.1 数据标注简介4.2 数据保存 5 模型训练5.1 修…

与“云”共舞,联想凌拓的新科技与新突破

伴随着数字经济的高速发展&#xff0c;IT信息技术在数字中国建设中起到的驱动和支撑作用也愈发凸显。特别是2023年人工智能和ChatGPT在全球的持续火爆&#xff0c;更是为整个IT产业注入了澎湃动力。那么面对日新月异的IT信息技术&#xff0c;再结合疫情之后截然不同的经济环境和…

【抖音小游戏】 Unity制作抖音小游戏方案 最新完整详细教程来袭【持续更新】

前言 【抖音小游戏】 Unity制作抖音小游戏方案 最新完整详细教程来袭【持续更新】一、相关准备工作1.1 用到的相关网址1.2 注册字节开发者后台账号 二、相关集成工作2.1 下载需要的集成资源2.2 安装StarkSDK和starksdk-unity-tools工具包2.3 搭建测试场景 三、构建发布3.1 发布…

【深度学习】MAT: Mask-Aware Transformer for Large Hole Image Inpainting

论文&#xff1a;https://arxiv.org/abs/2203.15270 代码&#xff1a;https://github.com/fenglinglwb/MAT 文章目录 AbstractIntroductionRelated WorkMethod总体架构卷积头Transformer主体Adjusted Transformer Block Multi-Head Contextual Attention Style Manipulation Mo…

探索Vue组件通信的秘密:打破隔阂,实现数据共享

一、Vue组件通信 每个组件都有自己的数据, 提供在data中, 每个组件的数据是独立的, 组件数据无法互相直接访问 (合理的)但是如果需要跨组件访问数据, 就需要用到组件通信 要是有一万个商品&#xff1f;&#xff1f;&#xff1f;&#xff1f;就要写一万个吗&#xff1f;函数调用…

KubeSphere 3.4.0 发布:支持 K8s v1.26

2023 年 07 月 26 日&#xff0c;KubeSphere 开源社区激动地向大家宣布&#xff0c;KubeSphere 3.4.0 正式发布&#xff01; 让我们先简单回顾下之前三个大版本的主要变化&#xff1a; KubeSphere 3.1.0 新增了“边缘计算”、“计量计费” 等功能&#xff0c;将 Kubernetes 从…

myeclipse的Debug模式

1.表示当前实现继续运行直到下一个断点&#xff0c;快捷键为F8。 2.表示打断整个进程 3.表示进入当前方法&#xff0c;快捷键为F5。 4.表示运行下一行代码&#xff0c;快捷键为F6。 5.表示退出当前方法&#xff0c;返回到调用层&#xff0c;快捷键为F7。 6.表示当前线程的…

kotlin 编写一个简单的天气预报app(五)增加forcast接口并显示

参考资料 OpenWeatherMap提供了一个/forecast接口&#xff0c;用于获取未来几天的天气预报。你可以使用HTTP GET请求访问该接口&#xff0c;并根据你所在的城市或地理坐标获取相应的天气数据。 以下是一个示例请求的URL和一些常用的参数&#xff1a; URL: http://api.openwe…

我的创作纪念日——256天

机缘 最开始我写博客没有什么特别的原因&#xff0c;主要是因为以下几点&#xff1a; 练习自己的语言组织能力 记录自己学习生活中学到的知识 为和我同一个学习阶段的朋友提供帮助 事实上最开始我根本不指望我的博客有多少人看&#xff0c;主要是想找一个好的保存 Markdown 笔…

花费7元训练自己的GPT 2模型

在上一篇博客中&#xff0c;我介绍了用Tensorflow来重现GPT 1的模型和训练的过程。这次我打算用Pytorch来重现GPT 2的模型并从头进行训练。 GPT 2的模型相比GPT 1的改进并不多&#xff0c;主要在以下方面&#xff1a; 1. GPT 2把layer normalization放在每个decoder block的前…

PHP最简单自定义自己的框架(一)

为啥要定义自己的框架&#xff1a; 定制化需求&#xff1a;每个项目都有不同的需求和特点&#xff0c;使用通用的框架可能无法满足所有的要求。自定义框架可以根据具体需求进行定制&#xff0c;提供更加灵活和符合项目需求的解决方案。学习和成长&#xff1a;自定义框架是一个很…