theArcticOcean

博观而约取,厚积而薄发

QT 窗体上放GIF动态图

开发背景是这样的:当后台开始进行数据库更新,用户会看到一个等待界面。数据库更新完成后,等待界面自动消失。

操作数据库

QT提供多种数据存储方式,我们可以选择一种driver,然后用标准查询语句进行系列操作。
下面是非常简单的例子:

#include <QtSql/QSqlDatabase>
#include <QCoreApplication>
#include <QStringList>
#include <QDebug>
#include <QSqlError>
#include <QSqlQuery>

int main(int argc, char **argv){
    QCoreApplication app(argc, argv);
    QStringList drivers = QSqlDatabase::drivers();
    foreach (QString it, drivers) {
        qDebug()<<it;
    }
    qDebug()<<"";
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("./student");
    if(db.open()){
        QSqlQuery query;
        if(!query.exec("create table today(title text)")){
            qDebug()<<"create: "<<query.lastError();
        }
        if(!query.exec("insert into today values('hello world')")){
            qDebug()<<"insert: "<<query.lastError();
        }
        if(!query.exec("select * from today")){
            qDebug()<<"create: "<<query.lastError();
        }
        while(query.next()){
            QString title = query.value(0).toString();
            qDebug()<<"title: "<<title;
        }
        db.close();
    }
    else qDebug()<<"db open failed.";
    return app.exec();
}

执行(先打印出能用的driver,然后使用QSlite存储数据):

"QSQLITE"
"QMYSQL"
"QMYSQL3"
"QODBC"
"QODBC3"
"QPSQL"
"QPSQL7"

title:  "hello world"

存储的数据库以二进制文件的方式存放在相应的路径下。
需要注意的是:
QSqlQuery的查询语句最好不要使用字符串拼接方式构造。那样不容易处理语句中的特殊字符,比如\n, \"等。
如下:

"insert into MessageTable values(1, 29, \"Warning\", 0, \"BluetoothController, NULL == argv\")"
"insert into MessageTable values(1, 30, \"Warning\", 0, \"mkdir(\"/pps/foryou/bluetooth\", 0777) = -1\")"
insert:  QSqlError("1", "Unable to execute statement", "near \"\", 0777) = -1\"\": syntax error")

"insert into MessageTable values(31, 27, \"Warning\", 0, \"CEQMcuFile::ParseRecDataPacket:CEQMcuFile, Unknown case:%d\\n\", pBuf[nTypePos]\")"
insert:  QSqlError("1", "Unable to execute statement", "near \"[nTypePos]\": syntax error")

"insert into MessageTable values(40, 3, \"LEVEL_WARNING\", 0, \"getProcessPid:opendir(\"/proc\")failed\")"
insert:  QSqlError("1", "Unable to execute statement", "near \"\")failed\"\": syntax error")

bindValue是我们需要的。

// 少用拼接查询字符串,避免语法错误
query.prepare("INSERT INTO MessageTable "
"VALUES (:Id, :Code, :Level, :Param, :Desc)");
query.bindValue(":Id", Id);
query.bindValue(":Code", Code);
query.bindValue(":Level", Level);
query.bindValue(":Param", Param);
query.bindValue(":Desc", Desc);

放置背景图片

  • 静态背景图片
  •     pic = new QImage(":/wait.png");
        this->setAutoFillBackground(true);
        QPalette palette;
        palette.setBrush(QPalette::Background,QBrush(*pic));
        this->setPalette(palette);

  • 动态背景图片 (gif)
  •     QMovie *movie = new QMovie(":/wait.gif");
        ui->label->setMovie(movie);
        movie->start();

    放置动态GIF图,我想多说两句。
    时钟就在一个新的线程中,属于开启了事件循环的线程
    我企图自己创建一个线程,然后在线程函数run中调用QMovie::jumpToNextFrame().

    gifRun::gifRun()
    {
        waitW = new waitWin();
        waitW->movie->start();
    }
    
    gifRun::~gifRun()
    {
        if(waitW != NULL){
            delete waitW;
            waitW = NULL;
        }
    }
    
    void gifRun::run()
    {
        while(1){
            qDebug()<<"hello";
            waitW->movie->jumpToNextFrame();
        }
    }

    当运行的时候出现问题了:

    QObject::killTimer: Timers cannot be stopped from another thread
    QObject::startTimer: Timers cannot be started from another thread

    而且父进程一旦进行其他操作,就会停止动态图。
    当我将父进程中的后台数据处理放在一个独立线程中(具体工作内容写于run函数,QThread::start()会调用run()),GIF图由QMovie自己管理(另一个线程)。两者可以同时正常工作:
    如图:

    阅读更多
    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/theArcticOcean/article/details/78503875
    个人分类: qt
    想对作者说点什么? 我来说一句

    没有更多推荐了,返回首页

    不良信息举报

    QT 窗体上放GIF动态图

    最多只允许输入30个字

    加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
    关闭
    关闭