zoukankan      html  css  js  c++  java
  • 2.大约QT数据库操作,简单的数据库连接操作,增删改查数据库,QSqlTableModel和QTableView,事务性操作,大约QItemDelegate 代理

    
    1. Linux下的qt安装,命令时:sudoapt-get install qt-sdk

    2. 安装mysql数据库,安装方法參考博客:http://blog.csdn.net/tototuzuoquan/article/details/39565783

    3. 假设行想进数据库开发。须要安装libqt5sql5-mysql.命令是:

    sudo apt-get install libqt5sql5-mysql

    4 创建一个项目

    要调用数据库。须要加上QT += gui widgets sql  也就是说要加上sql

    注意假设是在windows平台下:要将C:/MySQL/bin文件夹下的libmySQL.dll复制到项目编译后的生成的exe文件所在的同级文件夹下(比方文件夹E:QTuild-Database01-Desktop_Qt_5_3_MinGW_32bit-Debugdebug下。在此文件夹下有Database01.exe)。比方截图:

    A 假设是在Linux文件夹下,输入下面命令:mysql-u root -p123456

    创建数据库:

    B使用数据库d0718,并创建所需的数据库表

    表内容例如以下:

    CREATE TABLE `tcontact` (

     `username` varchar(32) NOT NULL,

     `mobile` varchar(16) NOT NULL,

     `mobile2` varchar(16) NOT NULL,

     `telephone` varchar(32) DEFAULT NULL,

     `home` varchar(32) DEFAULT NULL,

     `homeaddr` varchar(1024) DEFAULT NULL,

     `company` varchar(128) DEFAULT NULL,

     `companyaddr` varchar(1024) DEFAULT NULL,

     `title` varchar(16) DEFAULT NULL,

     PRIMARY KEY (`mobile`)

    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    CREATE TABLE `tuser` (

     `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'this is userid',

     `username` varchar(32) NOT NULL COMMENT 'username',

     `password` varchar(32) NOT NULL COMMENT 'password',

     `gender` int(11) NOT NULL COMMENT '1 is male 0 is female',

     PRIMARY KEY (`id`),

     UNIQUE KEY `username` (`username`)

    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

     

    C 编写项目代码:

    Database01.pro

    SOURCES+=

       main.cpp

     

    QT+=gui widgets sql

     

    CONFIG+=C++11

    main.cpp

    #include <QApplication>
    #include <QSqlDatabase>
    #include <QSqlError>
    #include <QDebug>
    #include <QWidget>
     
    int main(int argc,char* argv[])
    {
        QApplication app(argc,argv);
        QWidget w;
     
        /*QT能够操作 QSLITE QODBC,QPLSQL 这些数据库*/
        //以下表示使用mysql数据库
        QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
        db.setHostName("127.0.0.1");  //设置数据库所在位置
        db.setUserName("root");       //设置数据库的username
        db.setPassword("123456");     //设置数据库的password
        db.setDatabaseName("d0718");  //设置数据库名称
        bool bRet = db.open();        //打开数据库连接
        if(bRet == false)
    {
        //说明能够通过db.lastError()的方式得到错误信息
            qDebug() << "error open database" << db.lastError().text();
            exit(0);
        }
        qDebug() << "open database success";
     
        w.show();
        return app.exec();
    }

    执行结果:

     

    案例二:

    Database01.pro的内容例如以下:

    SOURCES += 
        main.cpp 
        Widget01.cpp
     
    QT += gui widgets sql
    #假设用到C++11的才会用到。否则不用
    CONFIG += C++11
     
    HEADERS += 
        Widget01.h

    Widget01.h的内容例如以下:

    #ifndef WIDGET01_H
    #define WIDGET01_H
     
    #include <QWidget>
     
    class Widget01 : public QWidget
    {
        Q_OBJECT
    public:
        explicit Widget01(QWidget *parent = 0);
     
    signals:
     
    public slots:
     
    };
     
    #endif // WIDGET01_H

    Widget01.cpp的内容例如以下:

    #include "Widget01.h"
     
    #include <QSqlDatabase>
    #include <QSqlError>
    #include <QSqlQuery>
    #include <QSqlResult>
     
    #include <QDebug>
     
    Widget01::Widget01(QWidget *parent) :
        QWidget(parent)
    {
        QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
        db.setHostName("127.0.0.1");
        db.setUserName("root");
        db.setPassword("123456");
        db.setDatabaseName("d0718");
        bool bRet = db.open();
        if(bRet == false)
        {
            qDebug() << "error open database" << db.lastError().text();
            exit(0);
        }
        qDebug() << "open database success";
     
        //向数据库中加入数据
        db.exec("insert into tuser(username,password,gender) values('涂作权','123456','1')");
        db.close();
    }

    main.cpp的内容例如以下:

    #include <QApplication>
    #include "Widget01.h"
     
    int main(int argc,char* argv[])
    {
        QApplication app(argc,argv);
        Widget01 w;
        w.show();
        return app.exec();
    }

    执行结果:

     

    案例2,使用QSqlTableModel

    Database01.pro

    SOURCES += 
        main.cpp 
        Widget02.cpp
     
    QT += gui widgets sql
     
    CONFIG += C++11
     
    HEADERS += 
        Widget02.h

    Widget02.h

    #ifndef WIDGET02_H
    #define WIDGET02_H
     
    #include <QWidget>
     
    class Widget02 : public QWidget
    {
        Q_OBJECT
    public:
        explicit Widget02(QWidget *parent = 0);
     
    signals:
     
    public slots:
     
    };
     
    #endif // WIDGET02_H

    Widget02.cpp

    #include "Widget02.h"
    #include <QSqlDatabase>
    #include <QSqlTableModel>
    #include <QSqlRecord>
    #include <QDebug>
    #include <QSqlError>
     
    Widget02::Widget02(QWidget *parent) :
        QWidget(parent)
    {
        // QSqlTableModel: 数据表相应的数据结构
        QSqlTableModel model;
        //设置表名。通过这样的方式不用写sql语句了
        model.setTable("tuser");
        //设置过滤器,当加上这一句的时候仅仅返回username不是"toto"数据
        //model.setFilter("username<>'toto'");
        model.select();  // exec query
        int ret = model.rowCount();
     
        // read data from database
        for(int i=0; i<ret; ++i)
        {
            QSqlRecord record = model.record(i);
            for(int j=0; j<record.count(); j++)
            {
                qDebug() << record.value(j);
            }
        }
     
        // update data to database
        //将第0(脚标以0開始),第1列的数据改成toto
        //注意仅仅能改动上满select出来的结果。

        model.setData(model.index(2, 1), "tototuzuoquan");
        //要想让上面的这一句也运行成功。要放开以下一句
        model.submitAll();
     
        // insert data to database
        QSqlRecord record = model.record();
        //能够指定id的值,通过以下的方式实现向数据库中插入一条记录
        // record.setValue("id", );
        record.setValue("username", "toto12");
        record.setValue("password", "password12");
        record.setValue("gender", 1);
        model.insertRecord(-1, record);
        model.submitAll();
    }

    main.cpp

    #include <QApplication>
    #include "Widget02.h"
    #include <QSqlDatabase>
    #include <QSqlError>
    #include <QDebug>
     
    int main(int argc,char* argv[])
    {
        QApplication app(argc,argv);
     
        /*QT能够操作 QSLITE QODBC,QPLSQL 这些数据库*/
        //以下表示使用mysql数据库。由于这里的db没实用到db。所以能够把它放在main
        //本质:在QT里面打开一个数据库之后,就会保存一个数据库连接,
        //其他的位置就能够随意使用这个全局的变量了
        QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
        db.setHostName("127.0.0.1");  //设置数据库所在位置
        db.setUserName("root");       //设置数据库的username
        db.setPassword("123456");     //设置数据库的password
        db.setDatabaseName("d0718");  //设置数据库名称
        bool bRet = db.open();        //打开数据库连接
     
        if(bRet == false)
        {
            //说明能够通过db.lastError()的方式得到错误信息
            qDebug() << "error open database" << db.lastError().text();
            exit(0);
        }
        qDebug() << "open database success";
     
        //注意Widget02要写在上面代码的以下
        Widget02 w;
        w.show();
        return app.exec();
    }

    执行结果:

    数据库中的变化的内容例如以下:

     

    案例三(QTableView),事务操作:

    Database01.pro

    SOURCES += 
        main.cpp 
        Widget03.cpp
     
    QT += gui widgets sql
     
    CONFIG += C++11
     
    HEADERS += 
        Widget03.h

    Widget03.h

    #ifndef WIDGET03_H
    #define WIDGET03_H
     
    #include <QObject>
    #include <QSqlTableModel>
    #include <QTableView> // show table
     
    class Widget03 : public QWidget
    {
        Q_OBJECT
    public:
        explicit Widget03(QWidget *parent = 0);
     
        QSqlTableModel* _model;
        QTableView* _view;
     
    signals:
     
    public slots:
        void slotSubmitClicked();
        void slotDelClicked();
        void slotAddClicked();
    };
     
    #endif // WIDGET03_H

    Widget03.cpp

    #include "Widget03.h"
    #include <QVBoxLayout>
    #include <QHBoxLayout>
    #include <QPushButton>
    #include <QMessageBox>
    #include <QSqlError>
    #include <QSqlDatabase>
    #include <QSqlRecord>
     
    Widget03::Widget03(QWidget *parent) :
        QWidget(parent)
    {
        _model = new QSqlTableModel;
        _model->setTable("tuser");
        _model->select();
        _model->setEditStrategy(QSqlTableModel::OnManualSubmit);
     
        _model->setHeaderData(0, Qt::Horizontal, "编号");
        _model->setHeaderData(1, Qt::Horizontal, "username");
        _model->setHeaderData(2, Qt::Horizontal, "password");
        _model->setHeaderData(3, Qt::Horizontal, "性别");
     
        _view = new QTableView;
        //_view中加入_model
        _view->setModel(_model);
        //隐藏第3
        //_view->hideColumn(2);
     
        QVBoxLayout* lay = new QVBoxLayout(this);
        lay->addWidget(_view);
     
        QHBoxLayout* hBox = new QHBoxLayout;
        lay->addLayout(hBox);
        hBox->addStretch();
     
        //删除的信号和槽
        QPushButton* del = new QPushButton("del");
        connect(del, SIGNAL(clicked()), this, SLOT(slotDelClicked()));
        hBox->addWidget(del);
     
        //提交的信号和槽
        QPushButton* submit = new QPushButton("submit");
        connect(submit, SIGNAL(clicked()), this, SLOT(slotSubmitClicked()));
        hBox->addWidget(submit);
     
        //加入的信号和槽
        QPushButton* add = new QPushButton("add");
        connect(add, SIGNAL(clicked()), this, SLOT(slotAddClicked()));
        hBox->addWidget(add);
    }
     
    /**
     * @brief Widget03::slotAddClicked 加入的槽
     */
    void Widget03::slotAddClicked()
    {
        //开启事务
        _model->database().transaction();
     
        QSqlRecord record = _model->record();
        _model->insertRecord(-1,record);
    }
     
    /**
     * @brief Widget03::slotDelClicked 删除的信号槽
     */
    void Widget03::slotDelClicked()
    {
        // 通过_view去获取被选中的部分的数据model
        QItemSelectionModel * selectModel = _view->selectionModel();
        // 通过选中的数据结构,获取这些格子的ModelIndex
        QModelIndexList selectList =  selectModel->selectedIndexes();
        QList<int> delRow;
     
        // 遍历这些格子。获取格子所在行,由于可能存在同样的行,所以要去重
        for(int i=0; i<selectList.size(); ++i)
        {
            QModelIndex index = selectList.at(i);
            //  _model->removeRow(index.row());
            delRow << index.row();
        }
     
        while(delRow.size() > 0)
        {
            int row = delRow.at(0);
            delRow.removeAll(row);
            _model->removeRow(row);
        }
     
        _model->submitAll();
    }
     
    void Widget03::slotSubmitClicked()
    {
        if(!_model->submitAll())
        {
            QMessageBox::critical(this, "Error", QSqlDatabase().lastError().text());
            _model->database().rollback();
        }
        else
        {
            _model->database().commit();
        }
    }

    main.cpp

    #include <QApplication>
    #include "Widget03.h"
    #include <QSqlDatabase>
    #include <QSqlError>
    #include <QDebug>
     
    int main(int argc,char* argv[])
    {
        QApplication app(argc,argv);
     
        /*QT能够操作 QSLITE QODBC,QPLSQL 这些数据库*/
        //以下表示使用mysql数据库,由于这里的db没实用到db,所以能够把它放在main
        //本质:在QT里面打开一个数据库之后,就会保存一个数据库连接,
        //其他的位置就能够随意使用这个全局的变量了
        QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
        db.setHostName("127.0.0.1");  //设置数据库所在位置
        db.setUserName("root");       //设置数据库的username
        db.setPassword("123456");     //设置数据库的password
        db.setDatabaseName("d0718");  //设置数据库名称
        bool bRet = db.open();        //打开数据库连接
     
        if(bRet == false)
        {
            //说明能够通过db.lastError()的方式得到错误信息
            qDebug() << "error open database" << db.lastError().text();
            exit(0);
        }
        qDebug() << "open database success";
     
        //注意Widget02要写在上面代码的以下
        Widget03 w;
        w.show();
        return app.exec();
    }

    执行结果:

     

    案例四:关于QItemDelegate代理

    Database01.pro

    SOURCES+=

       main.cpp

       Widget04.cpp

     

    QT+=gui widgets sql

     

    CONFIG+=C++11

     

    HEADERS+=

       Widget04.h

    Widget04.h

    #ifndefWIDGET04_H

    #defineWIDGET04_H

     

    #include<QObject>

    #include<QSqlTableModel>

    #include<QTableView>//showtable

    #include<QItemDelegate>

    #include<QComboBox>

     

    /**

     *@briefTheTUserDelegateclass对整张表进行代理

     */

    classTUserDelegate:publicQItemDelegate

    {

       QWidget*createEditor(QWidget*parent,

                             constQStyleOptionViewItem&option,

                             constQModelIndex&index)const

       {

           if(index.column()==0)

               returnNULL;

           if(index.column()==3)

           {

               QComboBox* combo=newQComboBox(parent);

               combo->addItem("");

               combo->addItem("");

               returncombo;

           }

     

           returnQItemDelegate::createEditor(parent,option,index);

       }

    };

     

    /**

     *@briefTheReadOnlyDelegateclass做一个仅仅读的代理

     */

    classReadOnlyDelegate:publicQItemDelegate

    {

       QWidget*createEditor(QWidget*,

                             constQStyleOptionViewItem&,

                             constQModelIndex&)const

       {

           returnNULL;

       }

    };

     

    /**

     *@briefTheGenderDelegateclass对指定列进行代理

     */

    classGenderDelegate:publicQItemDelegate

    {

    public:

       QWidget*createEditor(QWidget*parent,

                             constQStyleOptionViewItem&,

                             constQModelIndex&)const

       {

           QComboBox* combo=newQComboBox(parent);

           combo->addItem("");

           combo->addItem("");

           returncombo;

       }

    };

     

    /**

     *@briefTheMyTableModelclassTableModel的重写

     */

    classMyTableModel:publicQSqlTableModel

    {

    public:

       QVariantdata(constQModelIndex&idx,introle=Qt::DisplayRole)const

       {

           //  if(role==Qt::DisplayRole)

           //      returnQSqlTableModel::data(idx,role);

           //假设不是第三列,直接返回

           if(idx.column()!=3)

               returnQSqlTableModel::data(idx,role);

     

           //假设是第三列

           QVariantvar=QSqlTableModel::data(idx,role);

           if(var==0)

           {

               return"";

           }

     

           return"";

       }

     

       boolsetData(constQModelIndex&index,constQVariant&value,introle=Qt::EditRole)

       {

           if(index.column()!=3)

               returnQSqlTableModel::setData(index,value,role);

     

           if(value=="")

               returnQSqlTableModel::setData(index,1,role);

           returnQSqlTableModel::setData(index,0,role);

       }

     

    };

     

    classWidget04:publicQWidget

    {

       Q_OBJECT

    public:

       explicitWidget04(QWidget*parent= 0);

     

       MyTableModel*_model;

       QTableView*_view;

     

    signals:

     

    publicslots:

       voidslotSubmitClicked();

       voidslotDelClicked();

       voidslotAddClicked();

    };

     

    #endif//WIDGET04_H

    Widget04.cpp

    #include"Widget04.h"

    #include<QVBoxLayout>

    #include<QHBoxLayout>

    #include<QPushButton>

    #include<QMessageBox>

    #include<QSqlError>

    #include<QSqlDatabase>

    #include<QSqlRecord>

     

    Widget04::Widget04(QWidget*parent):

       QWidget(parent)

    {

       _model=newMyTableModel;

       _model->setTable("tuser");

       _model->select();

       //数据库的提交策略是手动提交

       _model->setEditStrategy(QSqlTableModel::OnManualSubmit);

     

       //改变现实的表的名字

       _model->setHeaderData(0,Qt::Horizontal,"编号");

       _model->setHeaderData(1,Qt::Horizontal,"username");

       _model->setHeaderData(2,Qt::Horizontal,"password");

       _model->setHeaderData(3,Qt::Horizontal,"性别");

     

       _view=newQTableView;

       _view->setModel(_model);

       //   _view->hideColumn(2);

     

       //以下是为指定的列设置代理

       // _view->setItemDelegateForColumn(3,newGenderDelegate);

       //_view->setItemDelegateForColumn(0,newReadOnlyDelegate);

       //为整个表设置代理

       _view->setItemDelegate(newTUserDelegate);

       QVBoxLayout*lay=newQVBoxLayout(this);

       lay->addWidget(_view);

     

       QHBoxLayout*hBox=newQHBoxLayout;

       lay->addLayout(hBox);

       hBox->addStretch();

     

       //删除button

       QPushButton*del=newQPushButton("del");

       connect(del,SIGNAL(clicked()),this,SLOT(slotDelClicked()));

       hBox->addWidget(del);

     

       //提交button

       QPushButton*submit=newQPushButton("submit");

       connect(submit,SIGNAL(clicked()),this,SLOT(slotSubmitClicked()));

       hBox->addWidget(submit);

     

       //加入button

       QPushButton*add=newQPushButton("add");

       connect(add,SIGNAL(clicked()),this,SLOT(slotAddClicked()));

       hBox->addWidget(add);

    }

     

    voidWidget04::slotAddClicked()

    {

     

       QSqlRecordrecord=_model->record();

       _model->insertRecord(-1,record);

    }

     

    voidWidget04::slotDelClicked()

    {

       //通过_view去获取被选中的部分的数据model

       QItemSelectionModel*selectModel=_view->selectionModel();

       //通过选中的数据结构,获取这些格子的ModelIndex

       QModelIndexListselectList= selectModel->selectedIndexes();

       QList<int>delRow;

     

       //遍历这些格子,获取格子所在行,由于可能存在同样的行。所以要去重

       for(inti=0;i<selectList.size();++i)

       {

           QModelIndexindex=selectList.at(i);

           // _model->removeRow(index.row());

           delRow<<index.row();

       }

     

       while(delRow.size()>0)

       {

           introw=delRow.at(0);

           delRow.removeAll(row);

           _model->removeRow(row);

       }

     

       _model->submitAll();

     

    }

     

    /**

     *@briefWidget04::slotSubmitClicked提交button

     */

    voidWidget04::slotSubmitClicked()

    {

       if(!_model->submitAll())

       {

           QMessageBox::critical(this,"Error",QSqlDatabase().lastError().text());

       }

    }

    main.cpp

    #include<QApplication>

    #include"Widget04.h"

    #include<QSqlDatabase>

    #include<QSqlError>

    #include<QDebug>

     

    intmain(intargc,char*argv[])

    {

       QApplicationapp(argc,argv);

     

       /*QT能够操作QSLITEQODBC,QPLSQL这些数据库*/

       //以下表示使用mysql数据库。由于这里的db没实用到db,所以能够把它放在main

       //本质:在QT里面打开一个数据库之后。就会保存一个数据库连接,

       //其他的位置就能够随意使用这个全局的变量了

       QSqlDatabasedb=QSqlDatabase::addDatabase("QMYSQL");

       db.setHostName("127.0.0.1"); //设置数据库所在位置

       db.setUserName("root");      //设置数据库的username

       db.setPassword("123456");    //设置数据库的password

       db.setDatabaseName("d0718"); //设置数据库名称

       boolbRet=db.open();       //打开数据库连接

     

       if(bRet==false)

       {

           //说明能够通过db.lastError()的方式得到错误信息

           qDebug()<<"erroropendatabase"<<db.lastError().text();

           exit(0);

       }

       qDebug()<<"opendatabasesuccess";

     

       //注意Widget02要写在上面代码的以下

       Widget04w;

       w.show();

       returnapp.exec();

    }

    执行结果:

     

     

    Widget05.h

    #ifndef WIDGET05_H

    #define WIDGET05_H

     

    #include <QWidget>

    #include <QSqlQueryModel>

    #include <QTableView>

    class Widget05 : public QWidget

    {

        Q_OBJECT

    public:

        explicit Widget05(QWidget *parent = 0);

     

        QSqlQueryModel* _model;

        QTableView *_view;

     

    signals:

     

    public slots:

     

    };

     

    #endif // WIDGET05_H

    Widget05.cpp

    #include "Widget05.h"

    #include <QSqlQuery>

    #include <QVBoxLayout>

    Widget05::Widget05(QWidget *parent) :

        QWidget(parent)

    {

        _model = new QSqlQueryModel;

        _view = new QTableView(this);

        _view->setModel(_model);

     

        _model->setQuery("select * from tuser");

        _model->query();

     

        QVBoxLayout* lay = new QVBoxLayout(this);

        lay->addWidget(_view);

    }

    main.cpp

    #include <QApplication>
    #include "Widget05.h"
    #include <QSqlDatabase>
    #include <QSqlError>
    #include <QDebug>
    #include "Contact.h"
     
    int main(int argc,char* argv[])
    {
        QApplication app(argc,argv);
     
        /*QT能够操作 QSLITE QODBC,QPLSQL 这些数据库*/
        //以下表示使用mysql数据库,由于这里的db没实用到db。所以能够把它放在main
        //本质:在QT里面打开一个数据库之后,就会保存一个数据库连接,
        //其他的位置就能够随意使用这个全局的变量了
        QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
        db.setHostName("127.0.0.1");  //设置数据库所在位置
        db.setUserName("root");       //设置数据库的username
        db.setPassword("123456");     //设置数据库的password
        db.setDatabaseName("d0718");  //设置数据库名称
        bool bRet = db.open();        //打开数据库连接
     
        if(bRet == false)
        {
            //说明能够通过db.lastError()的方式得到错误信息
            qDebug() << "error open database" << db.lastError().text();
            exit(0);
        }
        qDebug() << "open database success";
     
        //注意Widget02要写在上面代码的以下
        Widget05 w;
        w.show();
        return app.exec();
    }
    执行结果:

     

    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    1.4.2.3. SETUP(Core Data 应用程序实践指南)
    1.4.2.2. PATHS(Core Data 应用程序实践指南)
    1.4.2.1. FILES(Core Data 应用程序实践指南)
    1.4.2. 实现 Core Data Helper 类(Core Data 应用程序实践指南)
    1.4.1. Core Data Helper 简介(Core Data 应用程序实践指南)
    1.4. 为现有的应用程序添加 Core Data 支持(Core Data 应用程序实践指南)
    1.3.2. App Icon 和 Launch Image(Core Data 应用程序实践指南)
    1.3.1. 新建Xcode项目并设置故事板(Core Data 应用程序实践指南)
    php验证邮箱是否合法
    如何使js函数异步执行
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4731891.html
Copyright © 2011-2022 走看看