• 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();
    }
    执行结果:

     

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

  • 相关阅读:
    读书笔记--SQL必知必会07--创建计算字段
    读书笔记--SQL必知必会06--用通配符进行过滤
    读书笔记--SQL必知必会05--高级数据过滤
    FontMetrics ----- 绘制文本,获取文本高度
    Android 防止控件被重复点击
    提高zxing生成二维码的容错率及zxing生成二维码的边框设置
    Android 异常解决方法【汇总】
    setFocusable、setEnabled、setClickable区别
    getView 数据最后加一项
    TextView字体和背景图片 设置透明度
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4731891.html
Copyright © 2020-2023  润新知