Qt操作主/从视图和XML

本文介绍了一个使用Qt5实现的主从视图应用程序案例,该应用结合了数据库和XML文件来展示汽车制造商及其生产的汽车详情,并通过主从视图方式实现了数据的关联浏览。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

mainwindow.h

[cpp]  view plain  copy
  1. /** 
  2. * 书本:【Qt5开发及实例】 
  3. * 功能:Qt操作主/从视图和XML 
  4. * 文件:mainwindow.h 
  5. * 时间:2015年2月20日21:20:25 
  6. * 作者:cutter_point 
  7. */  
  8. #ifndef MAINWINDOW_H  
  9. #define MAINWINDOW_H  
  10.   
  11. #include <QMainWindow>  
  12. #include <QGroupBox>  
  13. #include <QTableView>  
  14. #include <QListWidget>  
  15. #include <QLabel>  
  16. #include <QDomDocument>  
  17. #include <QDomNode>  
  18. #include <QFile>  
  19. #include <QSqlRelationalTableModel>  
  20. #include <QSqlTableModel>  
  21. #include <QDebug>  
  22.   
  23. class MainWindow : public QMainWindow  
  24. {  
  25.   Q_OBJECT  
  26.   
  27. public:  
  28.   MainWindow(QWidget *parent = 0);  
  29.   //汽车制造商列表名,汽车表名,汽车详细信息对应XML文件指针  
  30.   MainWindow(const QString &factoryTable,const QString &carTable,QFile *carDetails,QWidget *parent = 0);   //构造函数  
  31.   ~MainWindow();  
  32.   
  33. private:  
  34.   QGroupBox *createCarGroupBox();  
  35.   QGroupBox *createFactoryGroupBox();  
  36.   QGroupBox *createDetailsGroupBox();  
  37.   void createMenuBar();   //菜单  
  38.   
  39.   QTableView *carView;  
  40.   QTableView *factoryView;  
  41.   
  42.   QListWidget *attribList;  
  43.   
  44.   QLabel *profileLabel;  
  45.   QLabel *titleLabel;  
  46.   
  47.   QDomDocument carData;     //对应XML文件的源  
  48.   QFile *file;      //XML文件指针  
  49.   QSqlRelationalTableModel *carModel;     //对应的汽车模型表  
  50.   QSqlTableModel *factoryModel;     //工厂模型表  
  51.   
  52.   void readCarData();   //读入XML文件爱你根目录  
  53.   
  54. };  
  55.   
  56. #endif // MAINWINDOW_H  


mainwindow.cpp

[cpp]  view plain  copy
  1. /** 
  2. * 书本:【Qt5开发及实例】 
  3. * 功能:Qt操作主/从视图和XML 
  4. * 文件:mainwindow.cpp 
  5. * 时间:2015年2月20日21:20:25 
  6. * 作者:cutter_point 
  7. */  
  8. #include "mainwindow.h"  
  9.   
  10. #include <QGridLayout>  
  11. #include <QAbstractItemView>  
  12. #include <QHeaderView>  
  13. #include <QAction>  
  14. #include <QMenu>  
  15. #include <QMenuBar>  
  16.   
  17. MainWindow::MainWindow(const QString &factoryTable,const QString &carTable,QFile *carDetails,QWidget *parent)  
  18.     : QMainWindow(parent)  
  19. {  
  20.     file = carDetails;      //得到文件指针  
  21.     readCarData();      //得到XML根元素开始  
  22.   
  23.     carModel = new QSqlRelationalTableModel(this);      //为汽车表创建一个模型  
  24.     carModel->setTable(carTable);     //为模型设定表  
  25.     carModel->setRelation(2, QSqlRelation(factoryTable, "id""manufactory"));    //按0, 1, 2,3顺序来的在carTable中第3列是外键连接在factoryTable表中的id,  
  26.     //用来展示的是manufactory来在car表中代替id号  
  27.     carModel->select();   //这个是为了直接显示出效果出来,不用等你点他进行响应  
  28.   
  29.     factoryModel = new QSqlTableModel(this);      //同上  
  30.     factoryModel->setTable(factoryTable);  
  31.     factoryModel->select();      //这个是为了直接显示出效果出来,不用等你点他进行响应  
  32.   
  33.     QGroupBox *factory = createFactoryGroupBox();  
  34.     QGroupBox *cars = createCarGroupBox();  
  35.     QGroupBox *details = createDetailsGroupBox();   //创建三块显示区域  
  36.   
  37. //    uniqueCarId = carModel->rowCount();  
  38. //    uniqueFactoryId = factoryModel->rowCount();  
  39.   
  40.     //布局  
  41.     QGridLayout *layout = new QGridLayout;  
  42.     layout->addWidget(factory, 0, 0);  
  43.     layout->addWidget(cars, 1, 0);  
  44.     layout->addWidget(details, 0, 1, 2, 1);  
  45.     layout->setColumnStretch(1, 1);  
  46.     layout->setColumnMinimumWidth(0, 500);    //第一列的列宽  
  47.   
  48.     QWidget *widget = new QWidget;  
  49.     widget->setLayout(layout);  
  50.     setCentralWidget(widget);  
  51.     createMenuBar();  
  52.   
  53.     resize(850, 400);  
  54.     setWindowTitle(tr("主从视图"));  
  55. }  
  56.   
  57. //MainWindow::MainWindow(QWidget *parent)  
  58. //  : QMainWindow(parent)  
  59. //{  
  60. //  QGroupBox *factory = createFactoryGroupBox();  
  61. //  QGroupBox *cars = createCarGroupBox();  
  62. //  QGroupBox *details = createDetailsGroupBox();   //创建三块显示区域  
  63.   
  64. //  //布局  
  65. //  QGridLayout *layout = new QGridLayout;  
  66. //  layout->addWidget(factory, 0, 0);  
  67. //  layout->addWidget(cars, 1, 0);  
  68. //  layout->addWidget(details, 0, 1, 2, 1);  
  69. //  layout->setColumnStretch(1, 1);  
  70. //  layout->setColumnMinimumWidth(0, 500);    //第一列的列宽  
  71.   
  72. //  QWidget *widget = new QWidget;  
  73. //  widget->setLayout(layout);  
  74. //  this->setCentralWidget(widget);  
  75. //  createMenuBar();  
  76.   
  77. //  resize(850, 400);  
  78. //  setWindowTitle(tr("主从视图"));  
  79. //}  
  80.   
  81. //QGroupBox *createCarGroupBox();  
  82. QGroupBox* MainWindow::createCarGroupBox()  
  83. {  
  84.   //汽车的区域  
  85.   QGroupBox *box = new QGroupBox(tr("汽车"));  
  86.   
  87.   carView = new QTableView;  
  88.   carView->setEditTriggers(QAbstractItemView::NoEditTriggers);    //不准用户编辑视图中的字段  
  89.   carView->setSortingEnabled(true);  
  90.   carView->setSelectionBehavior(QAbstractItemView::SelectRows);  
  91.   carView->setSelectionMode(QAbstractItemView::SingleSelection);  
  92.   carView->setShowGrid(false);        //不显示网格  
  93.   carView->verticalHeader()->hide();  //隐藏水平头部的计数1,2,3,4,。。。  
  94.   carView->setAlternatingRowColors(true);  
  95.   
  96.   carView->setModel(carModel);  
  97.   
  98.   QVBoxLayout *layout = new QVBoxLayout;  
  99.   layout->addWidget(carView, 0, 0);  
  100.   box->setLayout(layout);  
  101.   
  102.   return box;  
  103.   
  104. }  
  105.   
  106. //QGroupBox *createFactoryGroupBox();  
  107. QGroupBox* MainWindow::createFactoryGroupBox()  
  108. {  
  109.   //汽车制造商  
  110.   factoryView = new QTableView;  
  111.   factoryView->setEditTriggers(QAbstractItemView::NoEditTriggers);  //不准编辑  
  112.   factoryView->setSortingEnabled(true);  
  113.   factoryView->setSelectionBehavior(QAbstractItemView::SelectRows);  
  114.   factoryView->setSelectionMode(QAbstractItemView::SingleSelection);  
  115.   factoryView->setShowGrid(false);        //不显示网格  
  116.   factoryView->verticalHeader()->hide();    //隐藏水平头部的计数1,2,3,4,。。。  
  117.   factoryView->setAlternatingRowColors(true);  
  118.   
  119.   factoryView->setModel(factoryModel);      //设置模型显示出来  
  120.   
  121.   
  122.   QGroupBox *box = new QGroupBox(tr("汽车制造商"));  
  123.   QGridLayout *layout = new QGridLayout;  
  124.   layout->addWidget(factoryView, 0, 0);  
  125.   box->setLayout(layout);  
  126.   
  127.   return box;  
  128. }  
  129.   
  130. //QGroupBox *createDetailsGroupBox();  
  131. QGroupBox* MainWindow::createDetailsGroupBox()  
  132. {  
  133.   QGroupBox *box = new QGroupBox(tr("详细信息"));  
  134.   
  135.   profileLabel = new QLabel;  
  136.   profileLabel->setWordWrap(true);  
  137.   profileLabel->setAlignment(Qt::AlignBottom);  
  138.   titleLabel = new QLabel;  
  139.   titleLabel->setWordWrap(true);  
  140.   titleLabel->setAlignment(Qt::AlignBottom);  
  141.   
  142.   attribList = new QListWidget;  
  143.   
  144.   QGridLayout *layout = new QGridLayout;  
  145.   layout->addWidget(profileLabel, 0, 0, 1, 2);  
  146.   layout->addWidget(titleLabel, 1, 0, 1, 2);  
  147.   layout->addWidget(attribList, 2, 0, 1, 2);  
  148.   layout->setRowStretch(2, 1);  
  149.   box->setLayout(layout);  
  150.   
  151.   return box;  
  152. }  
  153.   
  154.   
  155. //oid createMenuBar();   //菜单  
  156. void MainWindow::createMenuBar()  
  157. {  
  158.   QAction *addAction = new QAction(tr("添加"), this);  
  159.   QAction *deleteAction = new QAction(tr("删除"), this);  
  160.   QAction *quitAction = new QAction(tr("quit"), this);  
  161.   
  162.   addAction->setShortcut(tr("Ctrl+A"));  
  163.   deleteAction->setShortcut(tr("Ctrl+D"));  
  164.   quitAction->setShortcut(tr("Ctrl+Q"));  
  165.   
  166.   QMenu *fileMenu = menuBar()->addMenu(tr("操作菜单"));  
  167.   fileMenu->addAction(addAction);  
  168.   fileMenu->addAction(deleteAction);  
  169.   fileMenu->addSeparator();  
  170.   fileMenu->addAction(quitAction);  
  171. }  
  172.   
  173. MainWindow::~MainWindow()  
  174. {  
  175.   
  176. }  
  177.   
  178. //void readCarData();   //读入XML文件爱你根目录  
  179. void MainWindow::readCarData()  
  180. {  
  181.   if(!file->open(QIODevice::ReadOnly))  
  182.     return;  
  183. //  else  
  184. //    {  
  185. //      qDebug()<<"..ok";  
  186. //    }  
  187.   if(!carData.setContent(file))   //设置XML源  
  188.     {  
  189.       qDebug()<<"..ok";  
  190.       file->close();  
  191.       return;  
  192.     }  
  193.   file->close();  
  194. }  




conndlg.h

[cpp]  view plain  copy
  1. #ifndef CONNDLG_H  
  2. #define CONNDLG_H  
  3.   
  4. #include <QDialog>  
  5. #include <QMessageBox>  
  6.   
  7. namespace Ui  
  8. {  
  9.   class ConnDlg;  
  10. }  
  11.   
  12. class QSqlError;  
  13.   
  14. class ConnDlg : public QDialog  
  15. {  
  16.   Q_OBJECT  
  17.   
  18. public:  
  19.   explicit ConnDlg(QWidget *parent = 0);  
  20.   ~ConnDlg();  
  21.   
  22.   QString driverName() const;     //驱动名  
  23.   QString databaseName() const;   //数据库  
  24.   QString userName() const;   //用户  
  25.   QString password() const;   //密码  
  26.   QString hostName() const;   //主机  
  27.   int port() const;       //端口  
  28.   QSqlError addConnection(const QString &driver, const QString &dbName, const QString &host,const QString &user,  
  29.                                               const QString &passwd, int port = -1);    //打开数据库连接,并判断是否打开  
  30.   //创建一个连接  
  31.   void createDB();  
  32.   void addSqliteConnection();  
  33.   
  34. private slots:  
  35.   void on_okButton_clicked();  
  36.   
  37.   void on_cancelButton_clicked() { reject(); }  
  38.   void driverChanged(const QString &);  
  39.   
  40. private:  
  41.   Ui::ConnDlg *ui;  
  42. };  
  43.   
  44. #endif // CONNDLG_H  

conndlg.cpp

[cpp]  view plain  copy
  1. #include "conndlg.h"  
  2. #include "ui_conndlg.h"  
  3.   
  4. #include <QSqlDatabase>  
  5. #include <QtSql>  
  6.   
  7. ConnDlg::ConnDlg(QWidget *parent) :  
  8.   QDialog(parent),  
  9.   ui(new Ui::ConnDlg)  
  10. {  
  11.   ui->setupUi(this);  
  12.   QStringList drivers = QSqlDatabase::drivers();  
  13.   ui->comboDriver->addItems(drivers);   //显示可以用的所有驱动  
  14.   connect(ui->comboDriver, SIGNAL(currentIndexChanged(QString)), this, SLOT(driverChanged(QString)));  
  15.   ui->strtus_label->setText(tr("准备连接数据库!"));  
  16.   
  17. }  
  18.   
  19. //void driverChanged(const QString &);  
  20. void ConnDlg::driverChanged(const QString &text)  
  21. {  
  22.   if(text =="QSQLITE")  
  23.       {  
  24.           ui->editDatabase->setEnabled(false);  
  25.           ui->editUsername->setEnabled(false);  
  26.           ui->editPassword->setEnabled(false);  
  27.           ui->editHostname->setEnabled(false);  
  28.           ui->portSpinBox->setEnabled(false);  
  29.       }  
  30.       else  
  31.       {  
  32.           ui->editDatabase->setEnabled(true);  
  33.           ui->editUsername->setEnabled(true);  
  34.           ui->editPassword->setEnabled(true);  
  35.           ui->editHostname->setEnabled(true);  
  36.           ui->portSpinBox->setEnabled(true);  
  37.       }  
  38. }  
  39.   
  40. QString ConnDlg::driverName() const  
  41. {  
  42.   return ui->comboDriver->currentText();    //得到当前选择的驱动  
  43. }  
  44.   
  45. QString ConnDlg::databaseName() const  
  46. {  
  47.     return ui->editDatabase->text();    //得到数据库名  
  48. }  
  49.   
  50. QString ConnDlg::userName() const  
  51. {  
  52.     return ui->editUsername->text();      //用户名  
  53. }  
  54.   
  55. QString ConnDlg::password() const  
  56. {  
  57.     return ui->editPassword->text();      //密码  
  58. }  
  59.   
  60. QString ConnDlg::hostName() const  
  61. {  
  62.     return ui->editHostname->text();        //主机  
  63. }  
  64.   
  65. int ConnDlg::port() const  
  66. {  
  67.     return ui->portSpinBox->value();    //端口号  
  68. }  
  69.   
  70. ConnDlg::~ConnDlg()  
  71. {  
  72.   delete ui;  
  73. }  
  74.   
  75. void ConnDlg::on_okButton_clicked()  
  76. {  
  77.   if (ui->comboDriver->currentText().isEmpty())  
  78.       {  
  79.           ui->strtus_label->setText(tr("请选择一个数据库驱动!"));  
  80.           ui->comboDriver->setFocus();      //显示选中  
  81.       }  
  82.       else if(ui->comboDriver->currentText() =="QSQLITE")  
  83.       {  
  84.           addSqliteConnection();        //添加连接  
  85.           //创建数据库表,如已存在则无须执行  
  86.           createDB();  
  87.           accept();   //接受事件,免得返回父类  
  88.       }  
  89.       else  
  90.       {  
  91.           QSqlError err = addConnection(driverName(), databaseName(), hostName(),userName(), password(), port());  
  92.           if (err.type() != QSqlError::NoError)  
  93.               ui->strtus_label->setText(err.text());  
  94.           else  
  95.               ui->strtus_label->setText(tr("连接数据库成功!"));  
  96.           //创建数据库表,如已存在则无须执行  
  97.           accept();  
  98.           }  
  99. }  
  100.   
  101. //QSqlError addConnection(const QString &driver, const QString &dbName, const QString &host,const QString &user,  
  102. //                                            const QString &passwd, int port = -1);  
  103. QSqlError ConnDlg::addConnection(const QString &driver, const QString &dbName, const QString &host,const QString &user, const QString &passwd, int port)  
  104. {  
  105.     QSqlError err;  
  106.     QSqlDatabase db = QSqlDatabase::addDatabase(driver);  
  107.     db.setDatabaseName(dbName);  
  108.     db.setHostName(host);  
  109.     db.setPort(port);  
  110.     if (!db.open(user, passwd))  
  111.     {  
  112.         err = db.lastError();  
  113.     }  
  114.     return err;  
  115. }  
  116.   
  117. void ConnDlg::addSqliteConnection()  
  118. {  
  119.     QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");  
  120.     db.setDatabaseName("databasefile");  
  121.     if (!db.open())  
  122.     {  
  123.         ui->strtus_label->setText(db.lastError().text());  
  124.         return;  
  125.     }  
  126.     ui->strtus_label->setText(tr("创建sqlite数据库成功!"));  
  127. }  
  128.   
  129. void ConnDlg::createDB()  
  130. {  
  131.   QSqlQuery query;  
  132.   query.exec("create table factory (id int primary key, manufactory varchar(40), address varchar(40))");  
  133.   query.exec(QObject::tr("insert into factory values(1, '一汽大众', '长春')"));  
  134.   query.exec(QObject::tr("insert into factory values(2, '二汽神龙', '武汉')"));  
  135.   query.exec(QObject::tr("insert into factory values(3, '上海大众', '上海')"));  
  136. //  query.exec(QObject::tr("insert into factory values(4, '一汽大众', '长春')"));  
  137.   
  138.   query.exec("create table cars (carid int primary key, name varchar(50), factoryid int, year int, foreign key(factoryid) references factory)");  
  139.   query.exec(QObject::tr("insert into cars values(1,'奥迪A6',1,2005)"));  
  140.   query.exec(QObject::tr("insert into cars values(2, '捷达', 1, 1993)"));  
  141.   query.exec(QObject::tr("insert into cars values(3, '宝来', 1, 2000)"));  
  142.   query.exec(QObject::tr("insert into cars values(4, '毕加索',2, 1999)"));  
  143.   query.exec(QObject::tr("insert into cars values(5, '富康', 2, 2004)"));  
  144.   query.exec(QObject::tr("insert into cars values(6, '标致307',2, 2001)"));  
  145.   query.exec(QObject::tr("insert into cars values(7, '桑塔纳',3, 1995)"));  
  146.   query.exec(QObject::tr("insert into cars values(8, '帕萨特',3, 2000)"));  
  147. }  

main.cpp

[cpp]  view plain  copy
  1. #include "mainwindow.h"  
  2. #include "conndlg.h"  
  3.   
  4. #include <QApplication>  
  5. #include <QDebug>  
  6.   
  7. int main(int argc, char *argv[])  
  8. {  
  9.   QApplication a(argc, argv);  
  10.   
  11.   ConnDlg dialog;  
  12.   if (dialog.exec() != QDialog::Accepted)  
  13.       return -1;  
  14. //  dialog.show();  
  15.   QFile *carDetails = new QFile("attribs.xml");  
  16. //  if(carDetails->isOpen())  
  17. //    {  
  18. //      qDebug()<<"??ok";  
  19. //    }  
  20.   MainWindow window("factory""cars", carDetails);  
  21.   window.show();  
  22.   
  23. //  MainWindow w;  
  24. //  w.show();  
  25.   
  26.   return a.exec();  
  27. }  

截图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值