【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卸載完全,可以重新進行安裝了,安裝教程可以參考下面博文: