Qt|读写数据库管理图片资源工具

文章目录

  • 创建项目
  • 设置UI布局
  • 控制数据库类实现
  • 界面实现类
  • 主函数

功能:用来管理数据库中图像资源
开发环境:windows10+VS2017+Qt5.14.2开发

创建项目

首先创建Qt Widgets Application
next->next->finish就创建好了
在这里插入图片描述

设置UI布局

打开已经创建好的UI控件,设计UI布局,根据自己需求可灵活修改,基本需要数据库的连接,图像资源导入、导出、预览、检索等。
在这里插入图片描述

控制数据库类实现

头文件:

#pragma once#include <QObject>
#include <QVariant>
#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
#include <memory>#define ResourceDataSPtr std::shared_ptr<ControlDB::ResourceData>
#define ResourceDataList QVector<std::shared_ptr<ControlDB::ResourceData>>class ControlDB  : public QObject
{Q_OBJECTpublic:enum PictureType{JPG,PNG,SVG};struct ResourceData{int id;QString name;QString svgContent;QByteArray pbgBuffer;PictureType picType;ResourceData(){id = 0;name = "";svgContent = "";}};// explicit 只能修饰含有一个参数的构造函数,或除第一个参数外其余参数都有默认值的构造函数。explicit ControlDB(QObject *parent = nullptr);~ControlDB(); // 连接sqlite数据库bool ConnectNewDatabase(const QString& _dbFilePath);// 查询所有图片资源ResourceDataList QueryPictureDataList();// 根据名称模糊查询图像数据ResourceDataList QueryPictureByName(const QString& _name);// 查询图片数据,需要从base64转回去// 二进制数据有不可见字符,传来传去容易数据错误,base64是可见字符ResourceDataSPtr QueryPicById(const int& _id);// 导入图片资源,资源名称-图片bufvoid ImportPicture(const QString& _resName, const QByteArray& _dataBuf, const PictureType& _type);// 更新图片数据void UpdatePicData(const int& _id, const QString& _newName, const QByteArray& _newData = "");// 根据ID删除图片数据void DeletePicById(const int& _id);// 查询所有svg资源ResourceDataList QuerySvgDataList();// 根据名字模糊查询svg数据ResourceDataList QuerySvgByName(const QString& _name);// 查询SVG图片数据ResourceDataSPtr QuerySvgById(const int& _id);// 导入svg资源void ImportSvg(const QString& _resName, const QString& _fileContent);// 更新SVG数据void UpdateSvgData(const int& _id, const QString& _newName, const QString& _fileContent = "");// 根据ID删除数据void DeleteSvgById(const int& _id);signals:private:QSqlDatabase* resDb_;};

源文件:

#include "ControlDB.h"#include <QDebug>
#include <QString>ControlDB::ControlDB(QObject *parent): QObject(parent), resDb_(nullptr)
{}ControlDB::~ControlDB()
{}bool ControlDB::ConnectNewDatabase(const QString& _dbFilePath)
{if (resDb_ != nullptr){resDb_->close();delete resDb_;resDb_ = nullptr;}// 其实账号密码没用resDb_ = new QSqlDatabase();*resDb_ = QSqlDatabase::addDatabase("QSQLITE");resDb_->setDatabaseName(_dbFilePath);//resDb_->setUserName("Luster");//resDb_->setPassword("123456");return resDb_->open();
}ResourceDataList ControlDB::QueryPictureDataList()
{ResourceDataList resDataList;QSqlQuery queryPic(*resDb_);queryPic.exec("SELECT * FROM PngData");while (queryPic.next()){ResourceDataSPtr curData = std::make_shared<ResourceData>();curData->id = queryPic.value("id").toInt();curData->name = queryPic.value("name").toString();curData->picType = (PictureType)queryPic.value("type").toInt();curData->pbgBuffer = QByteArray::fromBase64(queryPic.value("data").toByteArray());resDataList.push_back(curData);}return resDataList;
}ResourceDataList ControlDB::QueryPictureByName(const QString & _name)
{ResourceDataList resDataList;QSqlQuery queryPic(*resDb_);QString execSqlStr = QString("SELECT * FROM PngData WHERE name LIKE '%%1%'").arg(_name);queryPic.exec(execSqlStr);while (queryPic.next()){ResourceDataSPtr curData = std::make_shared<ResourceData>();curData->id = queryPic.value("id").toInt();curData->name = queryPic.value("name").toString();curData->picType = (PictureType)queryPic.value("type").toInt();curData->pbgBuffer = QByteArray::fromBase64(queryPic.value("data").toByteArray());resDataList.push_back(curData);}return resDataList;
}ResourceDataSPtr ControlDB::QueryPicById(const int& _id)
{ResourceDataSPtr resData = std::make_shared<ResourceData>();QSqlQuery queryPic(*resDb_);QString execSqlStr = QString("SELECT * FROM PngData WHERE id='%1'").arg(_id);queryPic.exec(execSqlStr);if (queryPic.next()){resData->id = queryPic.value("id").toInt();resData->name = queryPic.value("name").toString();resData->picType = (PictureType)queryPic.value("type").toInt();resData->pbgBuffer = queryPic.value("data").toByteArray();}return resData;
}void ControlDB::ImportPicture(const QString& _resName, const QByteArray& _dataBuf, const PictureType& _type)
{QSqlQuery queryPic(*resDb_);QByteArray base64Pic = _dataBuf.toBase64();QString insertSqlStr = QString("INSERT INTO PngData(name,type,data) values ('%1', '%2', '%3');").arg(_resName).arg(_type).arg(base64Pic.data());if (!queryPic.exec(insertSqlStr)){qDebug() << queryPic.lastError();}
}void ControlDB::UpdatePicData(const int& _id, const QString& _newName, const QByteArray& _newData /*= ""*/)
{QSqlQuery queryPic(*resDb_);QString UpdateSqlStr = "";if (_newData.isEmpty())UpdateSqlStr = QString("UPDATE PngData SET name='%1' WHERE id='%2'").arg(_newName).arg(_id);elseUpdateSqlStr = QString("UPDATE PngData SET name='%1',data='%2' WHERE id='%3'").arg(_newName).arg(_newData.toBase64().data()).arg(_id);if (!queryPic.exec(UpdateSqlStr)){qDebug() << queryPic.lastError();}
}void ControlDB::DeletePicById(const int& _id)
{QSqlQuery queryPic(*resDb_);QString insertSqlStr = QString("DELETE FROM PngData WHERE id='%1'").arg(_id);if (!queryPic.exec(insertSqlStr))qDebug() << queryPic.lastError();
}ResourceDataList ControlDB::QuerySvgDataList()
{ResourceDataList resDataList;QSqlQuery querySvg(*resDb_);querySvg.exec("SELECT * FROM SvgData");while (querySvg.next()){ResourceDataSPtr curData = std::make_shared<ResourceData>();curData->id = querySvg.value("id").toInt();curData->name = querySvg.value("name").toString();curData->svgContent = querySvg.value("data").toString();resDataList.push_back(curData);}return resDataList;
}ResourceDataList ControlDB::QuerySvgByName(const QString& _name)
{ResourceDataList resDataList;QSqlQuery querySvg(*resDb_);QString execSqlStr = QString("SELECT * FROM SvgData WHERE name LIKE '%%1%'").arg(_name);querySvg.exec(execSqlStr);while (querySvg.next()) {ResourceDataSPtr curData = std::make_shared<ResourceData>();curData->id = querySvg.value("id").toInt();curData->name = querySvg.value("name").toString();curData->svgContent = querySvg.value("data").toString();resDataList.push_back(curData);}return resDataList;
}ResourceDataSPtr ControlDB::QuerySvgById(const int& _id)
{ResourceDataSPtr resData = std::make_shared<ResourceData>();QSqlQuery querySvg(*resDb_);QString execSqlStr = QString("SELECT * FROM SvgData WHERE id='%1'").arg(_id);querySvg.exec(execSqlStr);if (querySvg.next()){resData->id = querySvg.value("id").toInt();resData->name = querySvg.value("name").toString();resData->svgContent = querySvg.value("data").toString();}return resData;
}void ControlDB::ImportSvg(const QString& _resName, const QString& _fileContent)
{QSqlQuery querySvg(*resDb_);QString insertSqlStr = QString("INSERT INTO SvgData (name,data) values ('%1','%2')").arg(_resName).arg(_fileContent);if (!querySvg.exec(insertSqlStr))qDebug() << querySvg.lastError();
}void ControlDB::UpdateSvgData(const int& _id, const QString& _newName, const QString& _fileContent /*= ""*/)
{QSqlQuery querySvg(*resDb_);QString insertSqlStr = "";if (_fileContent.isEmpty())insertSqlStr = QString("UPDATE SvgData SET name='%1' WHERE id='%2'").arg(_newName).arg(_id);elseinsertSqlStr = QString("UPDATE SvgData SET name='%1',data='%2' WHERE id='%3'").arg(_newName).arg(_fileContent).arg(_id);if (!querySvg.exec(insertSqlStr))qDebug() << querySvg.lastError();
}void ControlDB::DeleteSvgById(const int& _id)
{QSqlQuery querySvg(*resDb_);QString insertSqlStr = QString("DELETE FROM SvgData WHERE id='%1'").arg(_id);if (!querySvg.exec(insertSqlStr))qDebug() << querySvg.lastError();
}

界面实现类

头文件:

#pragma once#include <QtWidgets/QMainWindow>
#include "ui_DBTool.h"
#include "ControlDB.h"class DBTool : public QMainWindow
{Q_OBJECTpublic:DBTool (QWidget *parent = nullptr);~DBTool ();private slots:// 点击选择数据库文件void SlotSelectDbFile();// 连接数据库void SlotConnectResDb();// 导入资源文件,图片或者svgvoid SlotImportResource();// 表格里修改了资源的名字void SlotResourceNameChanged(QTableWidgetItem* _curItem);// 更新选中的资源图void SlotUpdateSelectResource();// 删除选中void SlotDeleteSelectRes();// 导出选中void SlotExportSelectRes();// 查询资源void SlotSearchResource(const QString& _curSearchName);private:Ui::DBToolClass ui;void InitUI();void InitSlots();// 刷新,从数据库查询图片数据下载void RefreshPngTable();// 查询svg数据显示void RefreshSvgTable();// 创建一个表格itemQTableWidgetItem* CreateTableItem(const QString& _text, const bool& _isReadOnly);// 设置操作数据库按钮状态 连接后可用void SetControlDbBtnEnable(bool _is_enable);// 导入图片 JPG和PNG 资源void ImportPng();// 导入svg资源void ImportSvg();// 获取选中的所有行号QVector<int> GetTableSelectRows();std::shared_ptr<ControlDB> control_db_Ptr_;
};

源文件:

#pragma execution-character_set("UTF-8")
#include "DBTool.h"
#include <QFileDialog>
#include <QHeaderView>
#include <QMessageBox>
#include <QLabel>
#include <QSvgWidget>
#include <QFileInfo>
#include <QDebug>DBTool::DBTool(QWidget *parent): QMainWindow(parent)
{ui.setupUi(this);setWindowTitle(QStringLiteral("资源管理器"));InitUI();InitSlots();
}DBTool::~DBTool()
{}void DBTool::SlotSelectDbFile()
{QString selectFilePath = QFileDialog::getOpenFileName(this, QStringLiteral("选择资源数据库"), "../../", "*.db");if (selectFilePath.isEmpty())return;ui.db_path_lineEdit->setText(selectFilePath);
}void DBTool::SlotConnectResDb()
{if (ui.db_path_lineEdit->text().isEmpty())return;bool connectDB = control_db_Ptr_->ConnectNewDatabase(ui.db_path_lineEdit->text());if (!connectDB){QMessageBox::critical(this, QStringLiteral("错误"), "数据库连接失败!");statusBar()->showMessage(QStringLiteral("错误:数据库连接失败!"));return;}elsestatusBar()->showMessage(QStringLiteral("提示:数据库连接成功!"));int curType = ui.type_comboBox->currentIndex();if (curType == 0)RefreshPngTable();else if (curType == 1)RefreshSvgTable();else{ }SetControlDbBtnEnable(true);
}void DBTool::SlotImportResource()
{if (ui.type_comboBox->currentIndex() == 0){ImportPng();RefreshPngTable();}else if (ui.type_comboBox->currentIndex() == 1){ImportSvg();RefreshSvgTable();}else{}
}void DBTool::SlotResourceNameChanged(QTableWidgetItem* _curItem)
{if (!_curItem)return;int changedRow = _curItem->row();if (!ui.db_data_tableWidget->item(changedRow, 0))return;if (!ui.db_data_tableWidget->item(changedRow, 2))return;int changedId = ui.db_data_tableWidget->item(changedRow, 0)->text().toInt();QString changedName = ui.db_data_tableWidget->item(changedRow, 2)->text();// 更新数据库数据if (ui.type_comboBox->currentIndex() == 0){// 更新图片数据control_db_Ptr_->UpdatePicData(changedId, changedName);}else if (ui.type_comboBox->currentIndex() == 1){// 更新SVG数据control_db_Ptr_->UpdateSvgData(changedId, changedName);}else{}qDebug() << changedId << changedName;QString changeText = QStringLiteral("更新资源ID:") + QString::number(changedId) + QStringLiteral("名称为") + changedName;statusBar()->showMessage(changeText);
}void DBTool::SlotUpdateSelectResource()
{// 只能选中一个更新QVector<int> selectRowList = GetTableSelectRows();if (selectRowList.size() != 1){QMessageBox::information(this, QStringLiteral("提示"), QStringLiteral("只能选择一行进行资源更新"));return;}int selectId = ui.db_data_tableWidget->item(selectRowList.first(), 0)->text().toInt();QString selectName = ui.db_data_tableWidget->item(selectRowList.first(), 2)->text();// 选择一个新的资源QString fileSuffix = ui.type_comboBox->currentIndex() == 0 ? "Images(*.jpg *.png *.JPG *.PNG)" : "*.svg";QString selectFilePath = QFileDialog::getOpenFileName(this, "选择资源文件", "../../", fileSuffix);if (selectFilePath.isEmpty())return;QFile picFile(selectFilePath);picFile.open(QIODevice::ReadOnly);QByteArray readBuf = picFile.readAll();QFileInfo picFileInfo(selectFilePath);if (ui.type_comboBox->currentIndex() == 0){control_db_Ptr_->UpdatePicData(selectId, picFileInfo.baseName(), readBuf);RefreshPngTable();}else{control_db_Ptr_->UpdateSvgData(selectId, picFileInfo.baseName(), readBuf);RefreshSvgTable();}picFile.close();
}void DBTool::SlotDeleteSelectRes()
{QVector<int> selectRowList = GetTableSelectRows();if (selectRowList.size() <= 0)return;for (const auto& curRow:selectRowList){int curId = ui.db_data_tableWidget->item(curRow, 0)->text().toInt();if (ui.type_comboBox->currentIndex() == 0)control_db_Ptr_->DeletePicById(curId);else if (ui.type_comboBox->currentIndex() == 1)control_db_Ptr_->DeleteSvgById(curId);}ui.type_comboBox->currentIndex() == 0 ? RefreshPngTable() : RefreshSvgTable();
}void DBTool::SlotExportSelectRes()
{QVector<int> selectRowList = GetTableSelectRows();if (selectRowList.size() == 0)return;QString savePath = QFileDialog::getExistingDirectory(this, "保存文件夹", "../../");if (savePath.isEmpty())return;for (const auto& curRow : selectRowList){int curId = ui.db_data_tableWidget->item(curRow, 0)->text().toInt();if (ui.type_comboBox->currentIndex() == 0){ResourceDataSPtr picBuffer = control_db_Ptr_->QueryPicById(curId);QFile saveFile(savePath + "/" + picBuffer->name + ".png");saveFile.open(QIODevice::WriteOnly);saveFile.write(QByteArray::fromBase64(picBuffer->pbgBuffer));saveFile.close();}else if (ui.type_comboBox->currentIndex() == 1){ResourceDataSPtr svgContent = control_db_Ptr_->QuerySvgById(curId);QFile saveFile(savePath + "/" + svgContent->name + ".svg");saveFile.open(QIODevice::WriteOnly);saveFile.write(svgContent->svgContent.toUtf8());saveFile.close();}}
}void DBTool::SlotSearchResource(const QString& _curSearchName)
{ResourceDataList queryRes;if (ui.type_comboBox->currentIndex() == 0){queryRes = control_db_Ptr_->QueryPictureByName(_curSearchName);ui.db_data_tableWidget->clearContents();ui.db_data_tableWidget->setRowCount(0);ui.db_data_tableWidget->setRowCount(queryRes.size());for (int i = 0; i < queryRes.size(); ++i){const auto& curSvgData = queryRes.at(i);ui.db_data_tableWidget->setItem(i, 0, CreateTableItem(QString::number(curSvgData->id), true));QLabel* bgWidget = new QLabel();QPixmap bgPix;bgPix.loadFromData(curSvgData->pbgBuffer);bgPix = bgPix.scaled(50, 50, Qt::KeepAspectRatio);bgWidget->setPixmap(bgPix);ui.db_data_tableWidget->setCellWidget(i, 1, bgWidget);ui.db_data_tableWidget->setItem(i, 2, CreateTableItem(curSvgData->name, false));ui.db_data_tableWidget->setItem(i, 3, CreateTableItem(curSvgData->picType == ControlDB::JPG ? "JPG" : "PNG", true));ui.db_data_tableWidget->setRowHeight(i, 50);}}else if (ui.type_comboBox->currentIndex() == 1){queryRes = control_db_Ptr_->QuerySvgByName(_curSearchName);ui.db_data_tableWidget->clearContents();ui.db_data_tableWidget->setRowCount(0);ui.db_data_tableWidget->setRowCount(queryRes.size());for (int i = 0; i < queryRes.size(); ++i){const auto& curSvgData = queryRes.at(i);ui.db_data_tableWidget->setItem(i, 0, CreateTableItem(QString::number(curSvgData->id), true));QSvgWidget* bgWidget = new QSvgWidget();bgWidget->load(curSvgData->svgContent.toUtf8());ui.db_data_tableWidget->setCellWidget(i, 1, bgWidget);ui.db_data_tableWidget->setItem(i, 2, CreateTableItem(curSvgData->name, false));ui.db_data_tableWidget->setItem(i, 3, CreateTableItem("SVG", true));}}
}void DBTool::InitUI()
{control_db_Ptr_ = std::make_shared<ControlDB>();SetControlDbBtnEnable(false);ui.db_path_lineEdit->setReadOnly(true);ui.search_lineEdit->setPlaceholderText(QStringLiteral("请输入查询资源名字"));ui.db_data_tableWidget->verticalHeader()->setHidden(false);ui.db_data_tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);ui.db_data_tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);QStringList resTableHeaderLabels;resTableHeaderLabels << "ID" << QStringLiteral("示例") << QStringLiteral("唯一名称") << QStringLiteral("类型");ui.db_data_tableWidget->setColumnCount(resTableHeaderLabels.size());ui.db_data_tableWidget->setHorizontalHeaderLabels(resTableHeaderLabels);
}void DBTool::InitSlots()
{connect(ui.chose_dbpath_pushButton, &QPushButton::clicked, this, &LusterDBTool::SlotSelectDbFile);connect(ui.connect_db_pushButton, &QPushButton::clicked, this, &LusterDBTool::SlotConnectResDb);connect(ui.type_comboBox, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, [=](int _curIndex) {if (_curIndex == 0)RefreshPngTable();else if (_curIndex == 1)RefreshSvgTable();else{ }});connect(ui.import_pushButton, &QPushButton::clicked, this, &LusterDBTool::SlotImportResource);connect(ui.db_data_tableWidget, &QTableWidget::itemChanged, this, &LusterDBTool::SlotResourceNameChanged);connect(ui.update_select_pushButton, &QPushButton::clicked, this, &LusterDBTool::SlotUpdateSelectResource);connect(ui.delete_select_pushButton, &QPushButton::clicked, this, &LusterDBTool::SlotDeleteSelectRes);connect(ui.export_select_pushButton, &QPushButton::clicked, this, &LusterDBTool::SlotExportSelectRes);connect(ui.search_lineEdit, &QLineEdit::textChanged, this, &LusterDBTool::SlotSearchResource);
}void DBTool::RefreshPngTable()
{ui.db_data_tableWidget->blockSignals(true);  //屏蔽掉信号,这样就不会触发itemChanged信号ui.db_data_tableWidget->clearContents();ui.db_data_tableWidget->setRowCount(0);ResourceDataList dataList = control_db_Ptr_->QueryPictureDataList();ui.db_data_tableWidget->setRowCount(dataList.size());for (int i=0;i<dataList.size();++i){const auto& curPngData = dataList.at(i);ui.db_data_tableWidget->setItem(i, 0, CreateTableItem(QString::number(curPngData->id), true));QLabel* bgWidget = new QLabel();QPixmap pngPix;pngPix.loadFromData(curPngData->pbgBuffer);pngPix = pngPix.scaled(50, 50, Qt::KeepAspectRatio);bgWidget->setPixmap(pngPix);ui.db_data_tableWidget->setCellWidget(i, 1, bgWidget);ui.db_data_tableWidget->setItem(i, 2, CreateTableItem(curPngData->name, false));ui.db_data_tableWidget->setItem(i, 3, CreateTableItem(curPngData->picType == ControlDB::JPG ? "JPG" : "PNG", true));ui.db_data_tableWidget->setRowHeight(i, 50);}ui.db_data_tableWidget->blockSignals(false);
}void DBTool::RefreshSvgTable()
{ui.db_data_tableWidget->blockSignals(true);ui.db_data_tableWidget->clearContents();ui.db_data_tableWidget->setRowCount(0);ResourceDataList dataList = control_db_Ptr_->QuerySvgDataList();ui.db_data_tableWidget->setRowCount(dataList.size());for (int i=0;i<dataList.size();++i){const auto curSvgData = dataList.at(i);ui.db_data_tableWidget->setItem(i, 0, CreateTableItem(QString::number(curSvgData->id), true));QSvgWidget* svgWidget = new QSvgWidget();svgWidget->setFixedSize(50, 50);svgWidget->load(curSvgData->svgContent.toUtf8());ui.db_data_tableWidget->setCellWidget(i, 1, svgWidget);ui.db_data_tableWidget->setItem(i, 2, CreateTableItem(curSvgData->name, false));ui.db_data_tableWidget->setItem(i, 3, CreateTableItem("SVG", true));ui.db_data_tableWidget->setRowHeight(i, 50);}ui.db_data_tableWidget->blockSignals(false);
}QTableWidgetItem* DBTool::CreateTableItem(const QString& _text, const bool& _isReadOnly)
{QTableWidgetItem* curItem = new QTableWidgetItem();curItem->setText(_text);curItem->setTextAlignment(Qt::AlignCenter);if (_isReadOnly)curItem->setFlags(Qt::ItemIsEnabled);return curItem;
}void DBTool::SetControlDbBtnEnable(bool _is_enable)
{ui.export_select_pushButton->setEnabled(_is_enable);ui.update_select_pushButton->setEnabled(_is_enable);ui.import_pushButton->setEnabled(_is_enable);ui.delete_select_pushButton->setEnabled(_is_enable);
}void DBTool::ImportPng()
{QStringList importFileList = QFileDialog::getOpenFileNames(this, "导入图片资源", "../../", "Images(*.jpg *.png *.JPG *.PNG)");if (importFileList.size() == 0)return;for (const auto& picFilePath:importFileList){QFile picFile(picFilePath);picFile.open(QIODevice::ReadOnly);QByteArray readBuf = picFile.readAll();QFileInfo picFileInfo(picFilePath);ControlDB::PictureType picType = picFileInfo.suffix().compare("png") == 0 ? ControlDB::PNG : ControlDB::JPG;control_db_Ptr_->ImportPicture(picFileInfo.baseName(), readBuf, picType);picFile.close();}statusBar()->showMessage(QStringLiteral("导入图像成功"));
}void DBTool::ImportSvg()
{QStringList importFileList = QFileDialog::getOpenFileNames(this, "导入SVG资源", "../../", "Images(*.svg)");if (importFileList.size() == 0)return;for (const auto& picFilePath:importFileList){QFile picFile(picFilePath);picFile.open(QIODevice::ReadOnly);QByteArray readBuf = picFile.readAll();QFileInfo picFileInfo(picFilePath);control_db_Ptr_->ImportSvg(picFileInfo.baseName(), readBuf);picFile.close();}
}QVector<int> DBTool::GetTableSelectRows()
{QVector<int> selectRowList;QList<QTableWidgetItem*> selectItemList = ui.db_data_tableWidget->selectedItems();for (const auto& selectItem : selectItemList){int curRow = selectItem->row();if(selectRowList.contains(curRow))continue;selectRowList.push_back(curRow);}return selectRowList;
}

主函数

#include "DBTool.h"
#include <QtWidgets/QApplication>int main(int argc, char *argv[])
{//system("chcp 65001");QApplication a(argc, argv);DBTool w;w.show();return a.exec();
}

源码链接:https://gitee.com/strange-tree-qian/qt-dbcontrol

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

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

相关文章

笔记本如何调节亮度?笔记本亮度调节方法

对于经常长时间面对笔记本电脑的小伙伴们来说&#xff0c;屏幕亮度过暗或者过亮&#xff0c;都会对眼睛造成伤害。那么&#xff0c;我们如何调节笔记本亮度至适中呢?下面为大家介绍3种简单的调节屏幕亮度的方法&#xff0c;一起来看看吧! 笔记本亮度调节方法一&#xff1a; 1、…

Amuse:.NET application for stable diffusion

目录 Welcome to Amuse! Features Why Choose Amuse? Key Highlights Paint To Image Text To Image Image To Image Image Inpaint Model Manager Hardware Requirements Compute Requirements Memory Requirements System Requirements Realtime Requirements…

Electron 入门 - 创建应用的全流程 - npm 踩坑版

说明 本文记录一下&#xff0c;使用Electron创建一个简单的客户端应用的全流程。 在官方文档的基础上&#xff0c;针对依赖安装过程中出现的异常&#xff0c;进行了补充&#xff0c;确保可以正常的创建应用。 创建步骤 0、校验node版本 官方文档建议使用 最新版本的 NodeJS …

Codigger用户篇:安全、稳定、高效的运行环境(一)

在当今数字化时代&#xff0c;个人数据的安全与隐私保护显得尤为重要。为了满足用户对数据信息的安全需求&#xff0c;我们推出Codigger分布式操作系统&#xff0c;它提供了一个运行私有应用程序的平台&#xff0c;旨在为用户提供一个安全、稳定、高效的私人应用运行环境。Codi…

html 元素宽度自适应 占据剩余宽度

弹性盒实现 父元素设置display: flex; 需要自适应宽度的子元素设置flex: 1; <html lang"en"> <head><style>*{margin: 0;padding: 0;}.main{display: flex;}.box1,.box2{width: 100px;height: 200px;}.box1{background: rgb(134 187 233);}.box2…

【javaWeb 第五篇】后端-Http协议学习

HTTP协议 HTTP概述HTTP-请求数据格式HTTP响应格式HTTP-协议解析 HTTP概述 Hyper Text Transfer Protocol,超文本传输协议&#xff0c;规定了浏览器和服务器之间的数据传输规则 简述概念就是&#xff0c;浏览器需要向服务器发送请求&#xff0c;想要得到服务器中的数据&#xff…

2014年认证杯SPSSPRO杯数学建模B题(第一阶段)位图的处理算法全过程文档及程序

2014年认证杯SPSSPRO杯数学建模 B题 位图的处理算法 原题再现&#xff1a; 图形&#xff08;或图像&#xff09;在计算机里主要有两种存储和表示方法。矢量图是使用点、直线或多边形等基于数学方程的几何对象来描述图形&#xff0c;位图则使用像素来描述图像。一般来说&#…

React组件如何通信

组件之间的通信,有四种类型: 父组件向子组件传递子组件向父组件传递兄弟组件之间传递父组件向子组件传递 由于React有单向数据流动的特性,所以父组件向子组件传递是最常见的方式。 父组件在调用子组件的时候,在组件标签内传递参数,子组件通过props属性获取父组件传递过来…

Share-ChatGPT官网UI/文件上传/联网搜索/GPTS 一并同步

地址&#xff1a;Share-ChatGPT 文章目录 界面UI&#xff0c;GPTS&#xff0c;读论文&#xff0c;数据分析&#xff0c;写论文视频演示仓库地址 界面 支持多账号同时管理&#xff0c;合理利用资源&#xff1a; UI&#xff0c;GPTS&#xff0c;读论文&#xff0c;数据分析&a…

【node】Missing script start or file server.js

错误 项目中没有找到启动脚本 start 或者 server.js 文件。pnpm start 命令默认会去寻找 start 脚本或者 server.js 文件来启动应用&#xff0c;但是在你的项目中没有找到这些文件&#xff0c;所以报错了。 $ pnpm startERR_PNPM_NO_SCRIPT_OR_SERVER  Missing script start…

论文篇06-论文范文-论基于架构的软件设计方法ABSD及应用(2024年软考高级系统架构设计师冲刺知识点总结系列文章)

试题 试题:论基于架构的软件设计方法(ABSD)及应用 基于架构的软件设计(Architecture-Based Software Design,ABSD)方法以构成软件架构的商业、质量和功能需求等要素来驱动整个软件开发过程。ABSD是一个自顶向下,递归细化的软件开发方法,它以软件系统功能的分解为基础…

Springboot vue elementui 在线考试系统案例源码

Springboot vue elementui 在线考试系统案例源码 链接地址

Go语言学习Day3:数据类型、运算符与流程控制

名人说&#xff1a;莫愁千里路&#xff0c;自有到来风。 ——钱珝 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 1、数据类型①布尔类型②整型③浮点型④string⑤类型转换 2、运算符①算术运算符②逻辑运算符③关…

基于微信小程序电影院订票选座系统 (后台JSP+JDBC+Mysql)答辩常规问题和如何回答(答辩指导)

博主介绍&#xff1a;黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者&#xff0c;CSDN博客专家&#xff0c;在线教育专家&#xff0c;CSDN钻石讲师&#xff1b;专注大学生毕业设计教育和辅导。 所有项目都配有从入门到精通的基础知识视频课程&#xff…

竞赛 python 爬虫与协同过滤的新闻推荐系统

1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; python 爬虫与协同过滤的新闻推荐系统 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;3分创新点&#xff1a;4分 该项目较为新颖&…

Go-Gin-Example 第八部分 优化配置接口+图片上传功能

文章目录 前情提要本节目标 优化配置结构讲解落实修改配置文件优化配置读取及设置初始化顺序第一步 验证 抽离file 实现上传图片接口图片名加密封装image的处理逻辑编写上传图片的业务逻辑增加图片上传的路由 验证实现前端访问 http.FileServerr.StaticFS修改文章接口新增、更新…

Spark RDD、DataFrame和DataSet的区别

Spark RDD、DataFrame和DataSet的区别 在比较这三者的区别之前&#xff0c;先看看他们各自的定义是什么。 Spark RDD RDD是一种弹性分布式数据集&#xff0c;是一种只读分区数据。它是spark的基础数据结构&#xff0c;具有内存计算能力、数据容错性以及数据不可修改特性。 S…

[CISCN2019 华东北赛区]Web2

[CISCN2019 华东北赛区]Web2 随便注册一个登录&#xff0c;发现 还有反馈页面&#xff0c;一看就知道大概率是xss&#xff0c;应该是为了得到管理员cookie扫描了一下&#xff0c;果然有admin.php后台登录 buu可以连接访问外网了&#xff0c;所以内部的xss平台关闭了&#xff0…

静态住宅IP好用吗?怎么选择?

在进行海外 IP 代理时&#xff0c;了解动态住宅 IP 和静态住宅 IP 的区别以及如何选择合适的类型非常重要。本文将介绍精态住宅 IP 特点和&#xff0c;并提供选择建议&#xff0c;帮助您根据需求做出明智的决策。 静态住宅 IP 的特点 静态住宅 IP 是指 IP 地址在一段时间内保…

深度理解文件操作

目录 文件 文件名&#xff1a; 标准流 文件指针 文件的打开和关闭 文件的顺序读写&#xff1a; 使用部分 文件的打开和关闭 文件 文件分两种&#xff0c;第一种是程序文件&#xff0c;后一种是数据文件。 程序文件&#xff1a;包括源程序文件&#xff08;后缀为.c&…