QT纯代码数据库汽车案例

步骤

第一步:绘制连接数据库的ui
第二步:创建数据库,往数据表中写数据
第三步:解析xml文件,匹配汽车类型

绘制如下
在这里插入图片描述
点击连接跳转到主页面
在.pro文件中添加sql和xml

代码实现

connectdlg.h

#ifndef CONNECTDLG_H
#define CONNECTDLG_H

#include <QDialog>
#include<QMessageBox>
#include"ui_connectlg.h"
class QSqlError;
namespace Ui {
class ConnDlg;
}

class ConnDlg : public QDialog
{
    Q_OBJECT

public:
    explicit ConnDlg(QWidget *parent = 0);
    QString driverName() const;//确保该函数再任何对象都可以使用,需要使用const,const代表常量成员函数
    QString databaseName() const;
    QString userName() const;
    QString password() const;
    QString hostName() const;
    int port() const;
    QSqlError addConnection(const QString &driver,const QString &dbName,const QString &host,const
                            QString &user,const QString &passwd,int port=-1);//数据库连接
    void creatDB();
    void addSqliteConnection();

    ~ConnDlg();

private:
    Ui::QSqlConnectionDialogUi ui;
private slots:
    void on_okButton_clicked();
    void on_cancelButton_clicked() { reject(); }//调用了reject函数
    void driverChanged(const QString &);//&表示引用,你可以修改这个传递进来的变量
};

#endif // CONNECTDLG_H

connectdlg.cpp

#include "connectdlg.h"
#include "ui_connectlg.h"
#include <QSqlDatabase>
#include <QtSql>
ConnDlg::ConnDlg(QWidget *parent) :
    QDialog(parent)
    //ui(new Ui::ConnDlg)
{
    ui.setupUi(this);

    QStringList drivers=QSqlDatabase::drivers();//查找数据库驱动
    ui.comboDriver->addItems(drivers);//将这些驱动加入ui界面的组合框中
    connect(ui.comboDriver,SIGNAL(currentIndexChanged(const QString &)),this,SLOT(driverChanged(const QString &)));
    ui.status_label->setText(tr("准备连接数据库!"));
}

QString ConnDlg::driverName() const
{
    return ui.comboDriver->currentText();
}

QString ConnDlg::databaseName() const
{
    return ui.editDatabase->text();
}

QString ConnDlg::userName() const
{
    return ui.editUsername->text();
}

QString ConnDlg::password() const
{
    return ui.editPassword->text();
}

QString ConnDlg::hostName() const
{
    return ui.editHostname->text();
}

int ConnDlg::port() const
{
    return ui.portSpinBox->value();
}

QSqlError ConnDlg::addConnection(const QString &driver, const QString &dbName, const QString &host,
                                 const QString &user, const QString &passwd, int port)
{
    QSqlError err;
    QSqlDatabase db=QSqlDatabase::addDatabase(driver);
    db.setDatabaseName(dbName);
    db.setHostName(host);
    db.setPort(port);
    if(!db.open(user,passwd))//当数据库打开失败,记录最后错误,然后引用默认数据库连接,并删除刚才打开的失败连接
    {
        err=db.lastError();
    }
    return err;
}

void ConnDlg::creatDB()
{
    //创建QSqlQuery对象,支持sql语句
    QSqlQuery query;
    query.exec("create table factory(id int primary key,manufactory varchar(40),address varchar(40))");
    query.exec(QObject::tr("insert into factory values(1,'一汽大众','长春')"));
    query.exec(QObject::tr("insert into factory values(2,'二汽神龙','武汉')"));
    query.exec(QObject::tr("insert into factory values(3,'上海大众','上海')"));
    query.exec("create table cars (carid int primary key,name varchar(50),factoryid int,year int,foreign key(factoryid) references factory)");
    query.exec(QObject::tr("insert into cars values(1,'奥迪A6',1,2005)"));
    query.exec(QObject::tr("insert into cars values(2,'捷达',1,1993)"));
    query.exec(QObject::tr("insert into cars values(3,'宝来',1,2000)"));
    query.exec(QObject::tr("insert into cars values(4,'毕加索',2,1999)"));
    query.exec(QObject::tr("insert into cars values(5,'富康',2,2004)"));
    query.exec(QObject::tr("insert into cars values(6,'标志',2,2001)"));
    query.exec(QObject::tr("insert into cars values(7,'桑塔纳',3,1995)"));
    query.exec(QObject::tr("insert into cars values(8,'帕萨特',3,2000)"));
}

void ConnDlg::addSqliteConnection()
{
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("databasefile");
    if(!db.open())
    {
        ui.status_label->setText(db.lastError().text());
        return;
    }
    ui.status_label->setText(tr("创建sqlite数据库成功"));
}

ConnDlg::~ConnDlg()
{
    //delete ui;
}

void ConnDlg::on_okButton_clicked()
{
    if(ui.comboDriver->currentText().isEmpty())//检查用户是否选择了一个数据库驱动
    {
        ui.status_label->setText(tr("请选择一个数据库驱动!"));
        ui.comboDriver->setFocus();
    }
    else if(ui.comboDriver->currentText()=="QSQLITE")//如果是QSQLITE驱动,则调用函数创建一个内存数据库
    {
        addSqliteConnection();
        //创建数据库表,如已经存在则无需执行
        creatDB();
        accept();
    }
    else
    {
        //如果是其他驱动,则调用函数创建一个其他所选类型的数据库连接
        QSqlError err=addConnection(driverName(),databaseName(),hostName(),userName(),password(),port());
        if(err.type()!=QSqlError::NoError)//在连接出错时显示错误信息
            ui.status_label->setText(err.text());
        else
            ui.status_label->setText(tr("连接数据库成功"));
        accept();
    }
}

void ConnDlg::driverChanged(const QString &text)
{
    if(text == "QSQLITE")
    {
        ui.editDatabase->setEnabled(false);
        ui.editUsername->setEnabled(false);
        ui.editPassword->setEnabled(false);
        ui.editHostname->setEnabled(false);
        ui.portSpinBox->setEnabled(false);
    }
    else
    {
        ui.editDatabase->setEnabled(true);
        ui.editUsername->setEnabled(true);
        ui.editPassword->setEnabled(true);
        ui.editHostname->setEnabled(true);
        ui.portSpinBox->setEnabled(true);
    }
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include<QGroupBox>
#include<QTableView>
#include<QListWidget>
#include<QLabel>

#include<QFile>
#include<QSqlRelationalTableModel>
#include<QSqlTableModel>
#include<QModelIndex>
#include<QDomNode>
#include<QDomDocument>
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    //构造函数,factoryTable是需要传入汽车制造商表名
    MainWindow(const QString &factoryTable,const QString &carTable,QFile *carDetails,QWidget *parent = 0);
    ~MainWindow();

private:
    QGroupBox *createCarGroupBox();
    QGroupBox *createFactorGroupBox();
    QGroupBox *createDetailsGroupBox();
    void createMenuBar();
    QTableView *carView;
    QTableView *factoryView;
    QListWidget *attribList;
    QLabel *profileLabel;
    QLabel *titleLabel;

    void decreaseCarCount(QModelIndex index);
    void getAttribList(QDomNode car);
    QModelIndex indexOfFactory(const QString &factory);
    void readCarData();
    void removeCarFromDatabase(QModelIndex index);
    void removeCarFromFile(int id);
    QDomDocument carData;
    QFile *file;
    QSqlRelationalTableModel *carModel;
    QSqlTableModel *factoryModel;
private slots:
    void addCar();
    void changeFactory(QModelIndex index);
    void delCar();
    void showCarDetails(QModelIndex index);
    void showFactorytProfile(QModelIndex index);
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include<QGridLayout>
#include<QAbstractItemView>
#include<QHeaderView>
#include<QAction>
#include<QMenu>
#include<QMenuBar>
#include<QMessageBox>
#include<QSqlRecord>
MainWindow::MainWindow(const QString &factoryTable,const QString &carTable,QFile *carDetails,QWidget *parent)
    : QMainWindow(parent)
{
    file = carDetails;
    readCarData();//将xml文件里的车型信息读入QDomDocument类实例carData中
    carModel=new QSqlRelationalTableModel(this);
    carModel->setTable(carTable);
    carModel->setRelation(2,QSqlRelation(factoryTable,"id","manufactory"));
    carModel->select();
    factoryModel=new QSqlTableModel(this);
    factoryModel->setTable(factoryTable);
    factoryModel->select();


    QGroupBox *factory=createFactorGroupBox();
    QGroupBox *cars=createCarGroupBox();
    QGroupBox *details=createDetailsGroupBox();
    //布局
    QGridLayout *layout=new QGridLayout;
    layout->addWidget(factory,0,0);
    layout->addWidget(cars,1,0);
    layout->addWidget(details,0,1,2,1);
    layout->setColumnStretch(1,1);
    layout->setColumnMinimumWidth(0,500);
    QWidget *widget=new QWidget;
    widget->setLayout(layout);
    setCentralWidget(widget);
    createMenuBar();
    resize(850,400);
    setWindowTitle(tr("主从视图"));


}

MainWindow::~MainWindow()
{

}

QGroupBox *MainWindow::createCarGroupBox()
{
    QGroupBox *box=new QGroupBox(tr("汽车"));
    carView=new QTableView;
    carView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    carView->setSortingEnabled(true);
    carView->setSelectionBehavior(QAbstractItemView::SelectRows);
    carView->setSelectionMode(QAbstractItemView::SingleSelection);
    carView->setShowGrid(false);
    carView->verticalHeader()->hide();
    carView->setAlternatingRowColors(true);

    carView->setModel(carModel);
    connect(carView,SIGNAL(clicked(QModelIndex)),this,SLOT(showCarDetails(QModelIndex)));
    connect(carView,SIGNAL(activated(QModelIndex)),this,SLOT(showCarDetails(QModelIndex)));

    QVBoxLayout *layout=new QVBoxLayout;
    layout->addWidget(carView,0,0);
    box->setLayout(layout);
    return box;
}

QGroupBox *MainWindow::createFactorGroupBox()
{
    factoryView=new QTableView;
    factoryView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    factoryView->setSortingEnabled(true);
    factoryView->setSelectionBehavior(QAbstractItemView::SelectRows);
    factoryView->setShowGrid(false);
    factoryView->setAlternatingRowColors(true);

    factoryView->setModel(factoryModel);
    connect(factoryView,SIGNAL(clicked(QModelIndex)),this,SLOT(changeFactory(QModelIndex)));

    QGroupBox *box=new QGroupBox(tr("汽车制造商"));
    QGridLayout *layout=new QGridLayout;
    layout->addWidget(factoryView,0,0);
    box->setLayout(layout);
    return box;
}

QGroupBox *MainWindow::createDetailsGroupBox()
{
    QGroupBox *box=new QGroupBox(tr("详细信息"));
    profileLabel=new QLabel;
    profileLabel->setWordWrap(true);
    profileLabel->setAlignment(Qt::AlignBottom);
    titleLabel=new QLabel;
    titleLabel->setWordWrap(true);
    titleLabel->setAlignment(Qt::AlignBottom);
    attribList=new QListWidget;
    QGridLayout *layout=new QGridLayout;
    layout->addWidget(profileLabel,0,0,1,2);
    layout->addWidget(titleLabel,1,0,1,2);
    layout->addWidget(attribList,2,0,1,2);
    layout->setRowStretch(2,1);
    box->setLayout(layout);
    return box;
}

void MainWindow::createMenuBar()
{
    QAction *addAction=new QAction(tr("添加"),this);
    QAction *deleteAction=new QAction(tr("删除"),this);
    QAction *quitAction=new QAction(tr("退出"),this);
    addAction->setShortcut(tr("Ctrl+A"));
    deleteAction->setShortcut(tr("Ctrl+D"));
    quitAction->setShortcut(tr("Ctrl+Q"));
    QMenu *fileMenu=menuBar()->addMenu(tr("操作菜单"));
    fileMenu->addAction(addAction);
    fileMenu->addAction(deleteAction);
    fileMenu->addSeparator();
    fileMenu->addAction(quitAction);

    connect(addAction,SIGNAL(triggered(bool)),this,SLOT(addCar()));
    connect(deleteAction,SIGNAL(triggered(bool)),this,SLOT(delCar()));
    connect(quitAction,SIGNAL(triggered(bool)),this,SLOT(close()));
}

void MainWindow::decreaseCarCount(QModelIndex index)
{
    int row = index.row();
    int count=carModel->rowCount();
    if(count==0)
        factoryModel->removeRow(row);
}
void MainWindow::showCarDetails(QModelIndex index)
{
    QSqlRecord record=carModel->record(index.row());
    QString factory=record.value("manufactory").toString();
    QString name=record.value("name").toString();
    QString year = record.value("year").toString();
    QString carId=record.value("carid").toString();
    showFactorytProfile(indexOfFactory(factory));
    titleLabel->setText(tr("品牌:%1 (%2)").arg(name).arg(year));
    titleLabel->show();
    QDomNodeList cars=carData.elementsByTagName("car");
    for(int i=0;i<cars.count();i++)
    {
        QDomNode car=cars.item(i);
        if(car.toElement().attribute("id") == carId)
        {
            getAttribList(car.toElement());
            break;
        }
    }
    if(!attribList->count() == 0)
        attribList->show();
}
void MainWindow::getAttribList(QDomNode car)
{
    attribList->clear();
    QDomNodeList attribs=car.childNodes();
    QDomNode node;
    QString attribNumber;
    for(int j=0;j<attribs.count();j++)
    {
        node=attribs.item(j);
        attribNumber=node.toElement().attribute("number");
        QListWidgetItem *item=new QListWidgetItem(attribList);
        QString showText(attribNumber + ": " + node.toElement().text());
        item->setText(tr("%1").arg(showText));
    }
}

QModelIndex MainWindow::indexOfFactory(const QString &factory)
{
    for(int i=0;i<factoryModel->rowCount();i++)
    {
        QSqlRecord record=factoryModel->record(i);
        if(record.value("manufactory")==factory)
            return factoryModel->index(i,1);
    }
    return QModelIndex();
}

void MainWindow::readCarData()
{
    if(!file->open(QIODevice::ReadOnly))
        return;
    if(!carData.setContent(file))
    {
        file->close();
        return;
    }
    file->close();
}

void MainWindow::removeCarFromDatabase(QModelIndex index)
{
    carModel->removeRow(index.row());
}

void MainWindow::removeCarFromFile(int id)
{
    QDomNodeList cars=carData.elementsByTagName("car");
    for(int i=0;i<cars.count();i++)
    {
        QDomNode node=cars.item(i);
        if(node.toElement().attribute("id").toInt() == id)
        {
            carData.elementsByTagName("archive").item(0).removeChild(node);
            break;
        }
    }
}

void MainWindow::addCar()
{

}

void MainWindow::changeFactory(QModelIndex index)
{
    QSqlRecord record=factoryModel->record(index.row());//取出用户选择的这条制造商记录
    QString factoryId=record.value("id").toString();//获取以上选择汽车制造商的主键
    carModel->setFilter("id='"+ factoryId +"'");
    showFactorytProfile(index);
}

void MainWindow::delCar()
{
    QModelIndexList selection=carView->selectionModel()->selectedRows(0);
    if(!selection.empty())
    {
        QModelIndex idIndex=selection.at(0);
        int id=idIndex.data().toInt();
        QString name=idIndex.sibling(idIndex.row(),1).data().toString();
        QString factory=idIndex.sibling(idIndex.row(),2).data().toString();
        QMessageBox::StandardButton button;
        button=QMessageBox::question(this,tr("删除汽车记录"),
                          QString(tr("确认删除由'%1'生产的'%2'吗?").arg(factory).arg(name)),QMessageBox::Yes | QMessageBox::No);

        if(button == QMessageBox::Yes)
        {
            removeCarFromFile(id);
            removeCarFromDatabase(idIndex);
            decreaseCarCount(indexOfFactory(factory));
        }
        else
        {
            QMessageBox::information(this,tr("删除汽车记录"),tr("请选择要删除的记录。"));
        }
    }
}



void MainWindow::showFactorytProfile(QModelIndex index)
{
    QSqlRecord record=factoryModel->record(index.row());
    QString name=record.value("manufactory").toString();
    int count=carModel->rowCount();
    profileLabel->setText(tr("汽车制造商:%1\n产品数量:%2").arg(name).arg(count));
    profileLabel->show();
    titleLabel->hide();
    attribList->hide();
}

创建xml文件,右键创建resourse文件夹,将xml文件放在res文件下
在这里插入图片描述

将xml文件命名为attribs.xml

<?xml version="1.0" encoding="UTF-8"?>
    <archive>
        <car id="1" >
            <attrib number="01">排量:2393ml</attrib>
            <attrib number="02">价格:8.98万元</attrib>
            <attrib number="03">排放:欧4</attrib>
            <attrib number="04">油耗:7.01(90km/h) 8.31(120km/h)</attrib>
            <attrib number="05">功率:130/6000</attrib>
        </car>
        <car id="2" >
            <attrib number="01">排量:1600ml</attrib>
            <attrib number="02">价格:43.26万元</attrib>
            <attrib number="03">排放:欧3</attrib>
            <attrib number="04">油耗:7.01(90km/h) 8.31(120km/h)</attrib>
            <attrib number="05">功率:68/5800</attrib>
        </car>
        <car id="3" >
            <attrib number="01">排量:2393ml</attrib>
            <attrib number="02">价格:11.25万元</attrib>
            <attrib number="03">排放:欧3带</attrib>
            <attrib number="04">油耗:7.01(90km/h) 8.31(120km/h)</attrib>
            <attrib number="05">功率:74/6000</attrib>
        </car>
        <car id="4" >
            <attrib number="01">排量:1997ml</attrib>
            <attrib number="02">价格:15.38万元</attrib>
            <attrib number="03">排放:欧3带</attrib>
            <attrib number="04">油耗:7.01(90km/h) 8.31(120km/h)</attrib>
            <attrib number="05">功率:99/6000</attrib>
        </car>
        <car id="5" >
            <attrib number="01">排量:1600ml</attrib>
            <attrib number="02">价格:6.58万元</attrib>
            <attrib number="03">排放:欧3</attrib>
            <attrib number="04">油耗:7.01(90km/h) 8.31(120km/h)</attrib>
            <attrib number="05">功率:65/5600</attrib>
        </car>
        <car id="6" >
            <attrib number="01">排量:1997ml</attrib>
            <attrib number="02">价格:16.08万元</attrib>
            <attrib number="03">排放:欧4</attrib>
            <attrib number="04">油耗:7.01(90km/h) 8.31(120km/h)</attrib>
            <attrib number="05">功率:108/6000</attrib>
        </car>
        <car id="7" >
            <attrib number="01">排量:1781ml</attrib>
            <attrib number="02">价格:7.98万元</attrib>
            <attrib number="03">排放:国3</attrib>
            <attrib number="04">油耗:7.01(90km/h) 8.31(120km/h)</attrib>
            <attrib number="05">功率:70/5200</attrib>
        </car>
        <car id="8" >
            <attrib number="01">排量:1984ml</attrib>
            <attrib number="02">价格:19.58万元</attrib>
            <attrib number="03">排放:欧4</attrib>
            <attrib number="04">油耗:7.01(90km/h) 8.31(120km/h)</attrib>
            <attrib number="05">功率:85/5400</attrib>
        </car>
    </archive>

main.cpp

#include "mainwindow.h"
#include <QApplication>
#include<QDialog>
#include<QFile>
#include "connectdlg.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    ConnDlg dialog;
    if(dialog.exec() != QDialog::Accepted)
        return -1;
    QFile *carDetails=new QFile(":/attribs.xml");
    MainWindow window("factory","cars",carDetails);
    window.show();
    //dialog.show();
    //MainWindow w;
    //w.show();

    return a.exec();
}

运行截图

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

残念惭忆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值