使用sql制作数据库表格

效果

image

代码

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QSqlDatabase>
#include <QSqlQuery>
#include <QMainWindow>
#include <QLabel>
#include <QSqlTableModel>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QGridLayout>
#include <QTableView>
#include <QComboBox>
#include <QLineEdit>
#include <QDataWidgetMapper>
#include <QSqlQueryModel>
#include <QItemSelectionModel>
#include <QSpinBox>

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private:

    /* 数据库连接类 */
    QSqlDatabase sqlDatabase;

    /* 用于查询数据 */
    QSqlQueryModel *sqlQueryModel;

    /* 数据映射 */
    QDataWidgetMapper *dataWidgetMapper;

    /* 选择模型 */
    QItemSelectionModel * itemSelectionModel;

    /* 水平布局 */
    QHBoxLayout *hBoxLayout[2];

    /* 垂直布局 */
    QVBoxLayout *vBoxLayout;

    /* 网格布局 */
    QGridLayout *gridLayout;

    /* 用于显示的表格*/
    QTableView *tableView;

    /* 主Widget */
    QWidget *mainWidget;

    /* 底部容器 */
    QWidget *bottomWidget;

    /* 底部网格布局容器 */
    QWidget *gridWidget;

    /* 照片容器 */
    QWidget *photoWidget;

    /* Label,用于显示照片 */
    QLabel *imageLabel;

    /* Label,底部显示文本 */
    QLabel *label[4];

    /* 性别下拉选择框,选择信息 */
    QComboBox *comboBox;

    /* 数值选择框,[0, 100] */
    QSpinBox *spinBox[2];

    /* 单行输入框  */
    QLineEdit *lineEdit;

private slots:
    /* 表格当前行变化执行的槽函数 */
    void on_currentRowChanged(const QModelIndex&, const QModelIndex&);
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include <QDebug>
#include <QHeaderView>
#include <QSqlError>
#include <QApplication>
#include <QSqlRecord>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 设置主窗体的显示位置与大小 */
    this->setGeometry(0, 0, 800, 480);

    /* 查看本机可用的数据库驱动 */
    QStringList drivers = QSqlDatabase::drivers();
    foreach(QString driver, drivers) {
        qDebug()<<driver;
    }

    /* 以QSQLITE驱动方式打开或者创建数据库 */
    sqlDatabase = QSqlDatabase::addDatabase("QSQLITE");
    sqlDatabase.setDatabaseName("employee.db");
    /* 以open的方式打开employee.db数据库,则会创建一个employee.db */
    if (!sqlDatabase.open())
        qDebug()<<"连接数据库错误"<<sqlDatabase.lastError()<<endl;
    else
        qDebug()<<"连接数据库成功"<<endl;

    QSqlQuery query(sqlDatabase);
    /* 使用指令式创建表 */
    query.exec("create table employee (id int primary key, name vchar(10), "
               "age int, sex vchar(3), photo text)");

    QStringList photoPath;
    /* 当前可执行程序的路径 */
    QString path(QApplication::applicationDirPath());
    photoPath<< path + "/photos/啊万.jpg"<< path + "/photos/啊棠.jpg";

    /* 以指令的方式插入数据,如果数据已经存在则不会成功不能插入 */
    query.exec(tr("insert into employee values(1, '啊万', 27, '男', '%1')").arg(photoPath[0]));
    query.exec(tr("insert into employee values(2, '啊棠', 28, '男', '%1')").arg(photoPath[1]));

    //    /* 初始化表格模型 */
    //    QSqlTableModel *model = new QSqlTableModel(this, sqlDatabase);

    //    /* 设置要选中的表格名称 */
    //    model->setTable("employee");
    //    /* 如果有修改则同步修改到数据库,
    //     * 注意这个规则需要与tabview这样的控件才生效,
    //     * 因为tabview可以直接编辑表里的内容 */
    //    model->setEditStrategy(QSqlTableModel::OnFieldChange);
    //    /* 成功则返回true,查看数据库里是否有employee这个表格 */
    //    model->select();
    //    /* 设置表格的头信息,若不设置则显示数据库里的英文字段头信息 */
    //    model->setHeaderData(model->fieldIndex("id"),
    //                         Qt::Horizontal, tr("编号"));
    //    model->setHeaderData(model->fieldIndex("name"),
    //                         Qt::Horizontal, tr("姓名"));
    //    model->setHeaderData(model->fieldIndex("age"),
    //                         Qt::Horizontal, tr("年龄"));
    //    model->setHeaderData(model->fieldIndex("sex"),
    //                         Qt::Horizontal, tr("性别"));

    //    QTableView *view = new QTableView;

    //    /* 设置表格的模型为model */
    //    view->setModel(model);
    //    /* 不显示图片路径信息行 */
    //    view->hideColumn(4);
    //    /* 表格居中 */
    //    setCentralWidget(view);
    //    return;

    /* QSqlQueryModel适合用于查询数据,不能修改数据 */
    sqlQueryModel = new QSqlQueryModel(this);

    /* 选择编号,姓名,年龄和性别的内容,显示到tableView上,
     * 图片最后通过数据选择再读取Label上 */
    sqlQueryModel->setQuery("select id, name, age, sex from employee");

    if (sqlQueryModel->lastError().isValid())
        qDebug()<<"选择数据失败!"<<endl;

    sqlQueryModel->setHeaderData(0, Qt::Horizontal, "编号");
    sqlQueryModel->setHeaderData(1, Qt::Horizontal, "姓名");
    sqlQueryModel->setHeaderData(2, Qt::Horizontal, "年龄");
    sqlQueryModel->setHeaderData(3, Qt::Horizontal, "性别");

    tableView = new QTableView();
    tableView->setModel(sqlQueryModel);

    /* 设置显示平均分列 */
    tableView->horizontalHeader()
            ->setSectionResizeMode(QHeaderView::Stretch);

    mainWidget = new QWidget();
    bottomWidget = new QWidget();
    gridWidget = new QWidget();
    photoWidget = new QWidget();
    imageLabel = new QLabel();

    /* 设置照片属性 */
    imageLabel->setScaledContents(true);
    imageLabel->setMaximumSize(200, 200);


    vBoxLayout = new QVBoxLayout();
    hBoxLayout[0] = new QHBoxLayout();
    hBoxLayout[1] = new QHBoxLayout();
    gridLayout = new QGridLayout();

    for (int i = 0; i < 4; i++)
        label[i] = new QLabel();

    for (int i = 0; i < 2; i++) {
        spinBox[i] = new QSpinBox();
        spinBox[i]->setRange(1, 100);
    }

    comboBox = new QComboBox();
    comboBox->addItem("男");
    comboBox->addItem("女");

    lineEdit = new QLineEdit();

    bottomWidget->setMinimumHeight(this->height() / 2 - 30);
    gridWidget->setMaximumWidth(this->width() / 2 - 30);

    /* 垂直布局 */
    vBoxLayout->addWidget(tableView);
    vBoxLayout->addWidget(bottomWidget);

    mainWidget->setLayout(vBoxLayout);
    setCentralWidget(mainWidget);

    /* 水平布局 */
    hBoxLayout[0]->addWidget(gridWidget);
    hBoxLayout[0]->addWidget(photoWidget);
    bottomWidget->setLayout(hBoxLayout[0]);

    QStringList list;
    list<<"姓名:"<<"编号:"<<"年龄:"<<"性别:";

    /* 网格布局 */
    for (int i = 0; i < 4; i++) {
        gridLayout->addWidget(label[i], i, 0);
        label[i]->setText(list[i]);
        switch (i) {
        case 0:
            gridLayout->addWidget(lineEdit, i, 1);
            break;
        case 1:
            gridLayout->addWidget(spinBox[0], i, 1);
            break;
        case 2:
            gridLayout->addWidget(spinBox[1], i, 1);
            break;
        case 3:
            gridLayout->addWidget(comboBox, i, 1);
            break;
        default:
            break;
        }
    }

    gridWidget->setLayout(gridLayout);
    hBoxLayout[1]->addWidget(imageLabel);
    photoWidget->setLayout(hBoxLayout[1]);

    itemSelectionModel = new QItemSelectionModel(sqlQueryModel);
    tableView->setSelectionModel(itemSelectionModel);

    /* 信号槽连接,表示表中行数据变化时,触发槽函数 */
    connect(itemSelectionModel,
            SIGNAL(currentRowChanged(QModelIndex, QModelIndex)),
            this,
            SLOT(on_currentRowChanged(QModelIndex, QModelIndex)));

    dataWidgetMapper = new QDataWidgetMapper(this);
    /* 设置为自动提交 */
    dataWidgetMapper->setSubmitPolicy(QDataWidgetMapper::AutoSubmit);
    dataWidgetMapper->setModel(sqlQueryModel);
    /* 创建数据映射,将前面的数据库内容映射到控件上 */
    dataWidgetMapper->addMapping(lineEdit, 1);
    dataWidgetMapper->addMapping(spinBox[0], 0);
    dataWidgetMapper->addMapping(spinBox[1], 2);
    dataWidgetMapper->addMapping(comboBox, 3);
}

MainWindow::~MainWindow()
{
    /* 关闭数据库 */
    sqlDatabase.close();
}

void MainWindow::on_currentRowChanged(const QModelIndex &current,
                                      const QModelIndex &previous)
{
    Q_UNUSED(previous)
    /* 更新数据映射行号,初始化时映射到第0行 */
    dataWidgetMapper->setCurrentModelIndex(current);
    /* 获取当前行号 */
    int row =  itemSelectionModel->currentIndex().row();
    /* 获取当前模型记录 */
    QSqlRecord record = sqlQueryModel->record(row);
    /* 获取id信息 */
    int id = record.value("id").toInt();
    QSqlQuery query;
    /* 使用bindValue绑定prepare里语句的值,需要使用":",":"是占位符 */
    query.prepare("select photo from employee where id = :ID");
    query.bindValue(":ID", id);
    query.exec();
    /* 返回到选择的第一条记录,因为id是唯一的,也只有一条记录 */
    query.first();

    /* 获取字段为photo的值,也就是存储照片的路径 */
    QVariant temp = query.value("photo");
    if (!temp.isValid()) {
        qDebug()<<"数据无效!"<<endl;
        return;
    }

    /* 清空图片显示 */
    imageLabel->clear();

    QImage image(temp.toString());

    if (image.isNull()) {
        qDebug()<<"未找到"<<temp.toString()<<endl;
        return;
    }

    /* 显示照片 */
    imageLabel->setPixmap(QPixmap::fromImage(image));
}

posted @ 2022-06-05 09:45  蘑菇王国大聪明  阅读(278)  评论(0编辑  收藏  举报