Qt數據庫項目實例程序(各數據庫通用)

【Qt數據庫程序實例】

首先放幾張程序運行的截圖:

數據庫登陸界面
數據庫顯示界面

 

程序運行效果

【備註】源碼下載地址(可以直接運行):

https://download.csdn.net/download/zqxdsy/11049683


程序部分

程序介紹:

    以主主從視圖的形式展示汽車製造廠和生產汽車的關係。

    當在汽車製造商中xuan選取某製造商時,下面的汽車列表中將顯示出與製造商生產的所有產品;當選中某個車型時,右邊的列表將顯示出該車車型和製造商的詳細信息,車型的相關信息信息存儲在XML的文件中。PS:各部分程序的相關注釋解析會在後續過程中逐漸加上,先把代碼貼上。

一.主界面佈局

1.主窗口MianWindow定義主顯示界面

頭文件mainmainwindow.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:
    //MainWindow(QWidget *parent = 0);
    MainWindow(const QString &factoryTable,const QString &carTable,QFile *carDetails,QWidget *parent = 0);   //構造函數
    ~MainWindow();
private slots:
    void addCar();
    void changeFactory(QModelIndex index);
    void delCar();
    void showCarDetails(QModelIndex index);
    void showFactorytProfile(QModelIndex index);
private:
    QGroupBox *createCarGroupBox();
    QGroupBox *createFactoryGroupBox();
    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;
};

#endif // MAINWINDOW_H

2.源文件mainwindow.cpp,各函數的實現

2.1 構造函數的始化和析構函數 

#include "mainwindow.h"
#include <QGridLayout>
#include <QAbstractItemView>
#include <QHeaderView>
#include <QAction>
#include <QMenu>
#include <QMenuBar>
#include <QMessageBox>
#include <QSqlRecord>
#include "editdialog.h"
extern int uniqueCarId;
extern int uniqueFactoryId;

MainWindow::MainWindow(const QString &factoryTable,const QString &carTable,QFile *carDetails,QWidget *parent)
    : QMainWindow(parent)
{
    file = carDetails;
    readCarData();

    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 = createFactoryGroupBox();
    QGroupBox *cars = createCarGroupBox();
    QGroupBox *details = createDetailsGroupBox();
    uniqueCarId = carModel->rowCount();
    uniqueFactoryId = factoryModel->rowCount();

    //佈局
    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()
{
    
}

2.2 創建企業顯示佈局

createFactoryGroupBox()
{
    factoryView = new QTableView;
    factoryView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    factoryView->setSortingEnabled(true);
    factoryView->setSelectionBehavior(QAbstractItemView::SelectRows);
    factoryView->setSelectionMode(QAbstractItemView::SingleSelection);
    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;
}

  2.3 創建汽車顯示佈局

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;
}

 2.4 創建詳細信息佈局

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;
}

2.5 創建菜單欄佈局

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()));
}

2.6 選擇企業操作

changeFactory(QModelIndex  index)
{
    QSqlRecord record = factoryModel->record(index.row());
    QString factoryId = record.value("id").toString();
    carModel->setFilter("id = '"+ factoryId +"'") ;
    showFactorytProfile(index);
}

2.7 顯示企業信息

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();
}

2.8 顯示汽車的詳細信息

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();
}

2.9 顯示列表

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));
    }
}

2.10 從數據庫裏刪除汽車

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("請選擇要刪除的記錄。"));
        }
    }
}

2.11 移除汽車記錄

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;
        }
    }
}

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

2.12 更新汽車數量

decreaseCarCount(QModelIndex index)
{
    int row = index.row();
    int count = carModel->rowCount();
    if (count == 0)
        factoryModel->removeRow(row);
}

2.13 讀取汽車數據

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

2.14 

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();
}

2.15 添加汽車操作

addCar()
{
    Dialog *dialog = new Dialog(carModel,factoryModel,carData,file,this);
    int accepted = dialog->exec();

    if (accepted == 1)
    {
        int lastRow = carModel->rowCount() - 1;
        carView->selectRow(lastRow);
        carView->scrollToBottom();
        showCarDetails(carModel->index(lastRow, 0));
    }
}

二、連接數據庫

以上是主界面佈局,下面是數據庫連接功能,用戶在圖形界面中配置數據庫連接參數信息。

1.添加新文件,Qt設計師界面類-Dialog without Buttons,類名爲ConnDlg,頭文件爲connectdlg.h,源文件爲connectdlg.cpp,界面文件爲connectdlg.ui,參考登陸界面將各個控件設置完成,運行程序,以便生成ui_connectdlg.h文件

2.頭文件connectdlg.h

#ifndef CONNECTDLG_H
#define CONNECTDLG_H

#include <QDialog>
#include <QMessageBox>
#include "ui_connectdlg.h"
class QSqlError;

class ConnDlg : public QDialog
{
    Q_OBJECT
public:
    ConnDlg(QWidget *parent = 0);
    //~ConnDlg();

    QString driverName() 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();
private slots:
    void on_okButton_clicked();
    void on_cancelButton_clicked() { reject(); }
    void driverChanged(const QString &);
private:
   Ui::QSqlConnectionDialogUi ui;
};

#endif // CONNECTDLG_H

3.源文件connect.cpp,構造函數完成了初始化ui界面以及查找當前數據庫驅動,並將其加入ui界面的驅動組合框中,以及其他的一些功能。

#include "connectdlg.h"
#include "ui_connectdlg.h"

#include <QSqlDatabase>
#include <QtSql>

//構造函數賦初值
ConnDlg::ConnDlg(QWidget *parent) :
    QDialog(parent)
{
    ui.setupUi(this);
    QStringList drivers = QSqlDatabase::drivers();
    ui.comboDriver->addItems(drivers);
    connect(ui.comboDriver,SIGNAL(currentIndexChanged( const QString & )),this,SLOT(driverChanged(const QString &)));
    ui.status_label->setText(tr("準備連接數據庫!"));
}

3.1 選擇數據庫驅動函數

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);
    }
}

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();
}

 3.2 選擇數據庫函數的實現

void ConnDlg::on_okButton_clicked()
{
    if (ui.comboDriver->currentText().isEmpty())
    {
        ui.status_label->setText(tr("請選擇一個數據庫驅動!"));
        ui.comboDriver->setFocus();
    }
    else if(ui.comboDriver->currentText() =="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();
        }
}

3.3 添加數據庫連接函數的實現

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;
}

3.4 創建sqlite數據庫

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數據庫成功!"));
}

3.5 創建表

void ConnDlg::creatDB()
{
    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, '標緻307',2, 2001)"));
    query.exec(QObject::tr("insert into cars values(7, '桑塔納',3, 1995)"));
    query.exec(QObject::tr("insert into cars values(8, '帕薩特',3, 2000)"));
}

4.修改main.cpp的程序如下

#include "mainwindow.h"
#include <QApplication>
#include <QDialog>
#include <QFile>
#include "connectdlg.h"

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

5.在SQLEx.pro文件中添加如下內容

QT    += sql

6.運行程序,會出現登陸界面,單機”連接“按鈕,狀態欄出現”創建sqlite數據庫成功”,接下來實現主從視圖模式瀏覽數據庫中的

信息。

三、主從視圖應用

1.在main.cpp、maindown.h和mianwindow.cpp中已經添加了主從視圖相關程序,可以查看上面的源碼。

2.新建一個XML文件attribs.xml,將該文件放在該工程目錄下,以下是文件內容。

<?xml version="1.0" encoding="gb2312"?>
  <archive>
	<car id="1">
	  <attrib number="01" >排量:2393ml</attrib>
	  <attrib number="02" >價格:43.26萬元</attrib>
	  <attrib number="03" >排放:歐 4</attrib>
	  <attrib number="04" >油耗:7.01(km/h)</attrib>
	  <attrib number="05" >功率:130/6000</attrib>
	</car>
	<car id="2">
	  <attrib number="01" >排量:2393ml</attrib>
	  <attrib number="02" >價格:43.26萬元</attrib>
	  <attrib number="03" >排放:歐 4</attrib>
	  <attrib number="04" >油耗:7.01(km/h)</attrib>
	  <attrib number="05" >功率:130/6000</attrib>
	</car>
	</archive>
	  

5.在SQLEx.pro文件中添加以下內容

QT     += xml

四、添加記錄功能

1.頭文件editdialog.h

#ifndef EDITDIALOG_H
#define EDITDIALOG_H

#include <QDialog>
#include <QtGui>
#include <QtSql>
#include <QtXml>
#include "ui_connectdlg.h"
#include <QtWidgets/QDialogButtonBox>

class Dialog : public QDialog
{
    Q_OBJECT
public:
    Dialog(QSqlRelationalTableModel *cars,QSqlTableModel *factory,QDomDocument details,QFile *output,QWidget *parent = 0);

private slots:
    void revert();
    void submit();
private:
    int addNewCar(const QString &name, int factoryId);
    int addNewFactory(const QString &factory,const QString &address);
    void addAttribs(int carId, QStringList attribs);
    QDialogButtonBox *createButtons();
    QGroupBox *createInputWidgets();
    int findFactoryId(const QString &factory);
    int generateCarId();
    int generateFactoryId();

    QSqlRelationalTableModel *carModel;
    QSqlTableModel *factoryModel;
    QDomDocument carDetails;
    QFile *outputFile;

    QLineEdit *factoryEditor;
    QLineEdit *addressEditor;
    QLineEdit *carEditor;
    QSpinBox *yearEditor;
    QLineEdit *attribEditor;
};

#endif // EDITDIALOG_H

2.源文件editdialog.cpp

 2.1 構造函數初始化

#include "editdialog.h"
#include <QMessageBox>
int uniqueCarId;
int uniqueFactoryId;

Dialog::Dialog(QSqlRelationalTableModel *cars,QSqlTableModel *factory,QDomDocument details,QFile *output,QWidget *parent) :
    QDialog(parent)
{
    carModel = cars;
    factoryModel = factory;
    carDetails = details;
    outputFile = output;

    QGroupBox *inputWidgetBox = createInputWidgets();
    QDialogButtonBox *buttonBox = createButtons();

    //界面佈局
    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(inputWidgetBox);
    layout->addWidget(buttonBox);
    setLayout(layout);

    setWindowTitle(tr("添加產品"));
}

2.2 提交操作

submit()
{
    QString factory = factoryEditor->text();
    QString address = addressEditor->text();
    QString name = carEditor->text();

    if (factory.isEmpty() || address.isEmpty()||name.isEmpty())
    {
        QString message(tr("請輸入廠名、廠址和商品名稱!"));
        QMessageBox::information(this, tr("添加產品"), message);
    }
    else
    {
        int factoryId = findFactoryId(factory);
        if(factoryId == -1)
        {
            factoryId = addNewFactory(factory,address);
        }
        int carId = addNewCar(name, factoryId);
        QStringList attribs;
        attribs = attribEditor->text().split(";",QString::SkipEmptyParts);
        addAttribs(carId, attribs);
        accept();
    }
}

2.3 查找企業ID號

findFactoryId(const QString &factory)
{
    int row = 0;
    while (row < factoryModel->rowCount())
    {
        QSqlRecord record = factoryModel->record(row);
        if (record.value("manufactory") == factory)
            return record.value("id").toInt();
        else
            row++;
    }
    return -1;
}

2.4 添加企業操作

addNewFactory(const QString &factory,const QString &address)
{
    QSqlRecord record;

    int id = generateFactoryId();

    QSqlField f1("id", QVariant::Int);
    QSqlField f2("manufactory", QVariant::String);
    QSqlField f3("address", QVariant::String);

    f1.setValue(QVariant(id));
    f2.setValue(QVariant(factory));
    f3.setValue(QVariant(address));
    record.append(f1);
    record.append(f2);
    record.append(f3);
    factoryModel->insertRecord(-1, record);
    return id;
}

2.5 添加新車

addNewCar(const QString &name, int factoryId)
{
    int id = generateCarId();
    QSqlRecord record;

    QSqlField f1("carid", QVariant::Int);
    QSqlField f2("name", QVariant::String);
    QSqlField f3("factoryid", QVariant::Int);
    QSqlField f4("year", QVariant::Int);

    f1.setValue(QVariant(id));
    f2.setValue(QVariant(name));
    f3.setValue(QVariant(factoryId));
    f4.setValue(QVariant(yearEditor->value()));
    record.append(f1);
    record.append(f2);
    record.append(f3);
    record.append(f4);

    carModel->insertRecord(-1, record);
    return id;
}

2.6 

addAttribs(int carId, QStringList attribs)
{
    QDomElement carNode = carDetails.createElement("car");
    carNode.setAttribute("id", carId);
    for (int i = 0; i < attribs.count(); i++)
    {
        QString attribNumber = QString::number(i+1);
        if (i < 10)
            attribNumber.prepend("0");
        QDomText textNode = carDetails.createTextNode(attribs.at(i));
        QDomElement attribNode = carDetails.createElement("attrib");
        attribNode.setAttribute("number", attribNumber);
        attribNode.appendChild(textNode);
        carNode.appendChild(attribNode);
    }
    QDomNodeList archive = carDetails.elementsByTagName("archive");
    archive.item(0).appendChild(carNode);
    if (!outputFile->open(QIODevice::WriteOnly))
    {
        return;
    }
    else
    {
        QTextStream stream(outputFile);
        archive.item(0).save(stream, 4);
        outputFile->close();
    }
}

2.7 清除操作

revert()
{
    factoryEditor->clear();
    addressEditor->clear();
    carEditor->clear();
    yearEditor->setValue(QDate::currentDate().year());
    attribEditor->clear();
}

2.8 

createInputWidgets()
{
    QGroupBox *box = new QGroupBox(tr("添加產品"));

    QLabel *factoryLabel = new QLabel(tr("製造商:"));
    QLabel *addressLabel = new QLabel(tr("廠址:"));
    QLabel *carLabel = new QLabel(tr("品牌:"));
    QLabel *yearLabel = new QLabel(tr("上市時間:"));
    QLabel *attribLabel = new QLabel(tr("產品屬性 (由分號;隔開):"));

    factoryEditor = new QLineEdit;
    carEditor = new QLineEdit;
    addressEditor = new QLineEdit;
    yearEditor = new QSpinBox;
    yearEditor->setMinimum(1900);
    yearEditor->setMaximum(QDate::currentDate().year());
    yearEditor->setValue(yearEditor->maximum());
    yearEditor->setReadOnly(false);
    attribEditor = new QLineEdit;

    QGridLayout *layout = new QGridLayout;
    layout->addWidget(factoryLabel, 0, 0);
    layout->addWidget(factoryEditor, 0, 1);
    layout->addWidget(addressLabel, 1, 0);
    layout->addWidget(addressEditor, 1, 1);

    layout->addWidget(carLabel, 2, 0);
    layout->addWidget(carEditor, 2, 1);
    layout->addWidget(yearLabel, 3, 0);
    layout->addWidget(yearEditor, 3, 1);
    layout->addWidget(attribLabel, 4, 0, 1, 2);
    layout->addWidget(attribEditor, 5, 0, 1, 2);
    box->setLayout(layout);

    return box;
}

2.9 操作槽函數的實現

createButtons()
{
    QPushButton *closeButton = new QPushButton(tr("關閉"));
    QPushButton *revertButton = new QPushButton(tr("撤銷"));
    QPushButton *submitButton = new QPushButton(tr("提交"));

    closeButton->setDefault(true);

    connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
    connect(revertButton, SIGNAL(clicked()), this, SLOT(revert()));
    connect(submitButton, SIGNAL(clicked()), this, SLOT(submit()));

    QDialogButtonBox *buttonBox = new QDialogButtonBox;
    buttonBox->addButton(submitButton, QDialogButtonBox::ResetRole);
    buttonBox->addButton(revertButton, QDialogButtonBox::ResetRole);
    buttonBox->addButton(closeButton, QDialogButtonBox::RejectRole);

    return buttonBox;
}

2.10  更新企業和汽車ID

generateFactoryId()
{
    uniqueFactoryId += 1;
    return uniqueFactoryId;
}

generateCarId()
{
    uniqueCarId += 1;
    return uniqueCarId;
}

  以上就是該程序各個函數的實現、界面佈局以及數據庫的具體操作應用,希望能夠對大家有所幫助和啓發。 

【備註】如果需要直接下載源碼可以點下面連接:

https://download.csdn.net/download/zqxdsy/11049683


    這裏我使用的時MySQL數據庫,其他數據庫也可以,因爲Qt中對數據庫的操作有內置的模塊和驅動,各個數據庫通用。

    1.安裝MySQL數據庫可以參考這篇博文,很詳細,按照教程一步步來肯定不會出錯。

https://blog.csdn.net/zqxdsy/article/details/88566381

    2.使用Qt打開數據庫時可能會出現錯誤:

Qt連接MySQL的時候提示“QSqlDatabase: QMYSQL driver not loaded”,解決方法如下:

(1)原因一:缺少文件

    解決辦法:

    將MySQL安裝路徑下的子文件夾lib中將的libmysql.dll 文件複製Qt安裝路徑下的D:\Qt\Qt5.6.1\5.6\mingw49_32\bin中(根據自己的實際情況複製),此時再運行Qt的程序就不會報錯啦!

(2)原因二:Qt Creator與MySQL位數不一致

    如果上面的方法未能解決問題,那麼應該是你安裝的MySQL和QT的位數不同,可以打開MySQL控制檯 
輸入show variables like '%version_%';即可查看MySql位數。提示:Qt5.2及以上版本如果使用的是mingw編譯器,Qt只有32位的。連接64位的mysql,即使把mysql安裝目錄下的libmysql.dll放到qt安裝目錄bin路徑下,也是無法連接數據庫。

    解決辦法:

    A.如果不想重新安裝32位的MySQL,可以安裝一個32的驅動,mysql的官網給出了連接32位的驅動。鏈接爲:

http://dev.mysql.com/downloads/connector/c/下載如下圖標記的驅動。

    下載後把解壓目錄下的libmysql.dll文件拷貝到D:Qt\Qt5.2\5.2.1\mingw48_32\bin(根據自己的實際情況放到對應目錄下),重啓Qt Creator後打開工程就可以正確運行了。 總之,必須保證你拿到libmysql.dll這個文件對應的mysql的位數必須與QT的位數相同。

   B.對於8.0以上的MySQL版本,下載的壓縮包裏可能沒有libmysql.dll這個文件,那就只能重新安裝一個32位的MySQL吧,卸載的時候注意要卸載乾淨,否則安裝的時候會失敗。卸載方法如下。


 

【mysql數據庫完全卸載步驟】

1.運行cmd,執行net start ,查看與mysql相關的服務名稱,並記錄(不需要的話可跳過)。 

2.可以利用Navicat等IDE進行數據備份(若無重要的數據可直接跳過)

主要備份數據有:

(1)業務系統涉及的數據庫;

(2)用戶名和密碼,如果不太多的話,可用不備份,下次重建即可;

(3)my.ini文件,這個文件在mysql的安裝目錄下。其中保存一些mysql端口,最大連結數等配置信息。

3.關閉MySQL服務器,MySQL服務器的關閉有兩種方式。

(1)方法一:在管理員終端命令裏輸入    net stop mysql

(2)方法二:在 控制面板 -----> 管理工具 -----> 服務 -----> 關閉MySQL服務,也可以使用Window鍵 + r ,輸入 services.msc 進入服務界面  關閉服務器。

4.卸載

對於程序安裝版的MySQL, 用控制面板或者電腦管家等卸載MySQL;對於使用壓縮包安裝MySQL的朋友,可能不顯示MySQL程序,可直接跳過這步,不用卸載。

5.刪除MySQL相關文件

找到MySQL目錄將MySQL相關文件刪除;刪除mysql管理工具,如navicat。這一步的目的是爲了避免在註冊用表中有太多的mysql項。如果您有足夠的信息識別出注冊用表中哪些包含mysql的項是與mysql數據庫有關的哪些不是,這一項可跳過。

6.清理註冊表

打開註冊表:方式1:在終端命令裏輸入regedit,搜索mySQL,右鍵全部刪除;或者將下面三個路徑下的MySQL相關文件夾刪除。

HKEY_LOCAL_MACHINE/SYSTEM/ControlSet001/Services/Eventlog/Application/MySQL
HKEY_LOCAL_MACHINE/SYSTEM/ControlSet002/Services/Eventlog/Application/MySQL
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Eventlog/Application/MySQL

這樣MySQL基本卸載完全了,如果還不放心可以在註冊表裏搜索,編輯->查找下一個,挨個搜索一遍,刪除mysql的所有文件夾,以及包含mysql的所有鍵(注意區分下環境變量,儘量跳過去,如果跳過去後發現最後沒卸載乾淨,再回來刪掉一部分)。

7.重啓電腦或者註銷登陸然後再重新登錄。

完成後以管理員身份運行cmd,執行sc delete mysql,(注意:這裏的“mysql”指的是步驟1中記錄的mysql服務名稱,您的mysql服務名稱有可能是mysql99,mysql666等),如果顯示服務不存在,則說明註冊用表刪除乾淨了,否則重複執行第6步。

至此,mysql卸載完全,可以重新進行安裝了,安裝教程可以參考下面博文:

https://blog.csdn.net/zqxdsy/article/details/88566381

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章