• Qt开发经验小技巧196200


    1. 关于Qt延时的几种方法。
    void QUIHelperCore::sleep(int msec)
    {
        if (msec <= 0) {
            return;
        }
    
    #if 1
        //非阻塞方式延时,现在很多人推荐的方法
        QEventLoop loop;
        QTimer::singleShot(msec, &loop, SLOT(quit()));
        loop.exec();
    #else
    #if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
        //阻塞方式延时,如果在主线程会卡住主界面
        QThread::msleep(msec);
    #else
        //非阻塞方式延时,不会卡住主界面,据说可能有问题
        QTime endTime = QTime::currentTime().addMSecs(msec);
        while (QTime::currentTime() < endTime) {
            QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
        }
    #endif
    #endif
    }
    
    1. 随着国产化的兴起,各种国产系统和国产数据库等逐渐进入开发者的世界,罗列几个要点。
    • 中标麒麟neokylin基于centos。
    • 银河麒麟kylin早期版本比如V2基于freebsd,新版本V4、V10基于ubuntu。
    • 优麒麟ubuntukylin就是ubuntu的汉化版本,加了点农历控件啥的。
    • deepin基于debian。
    • uos基于deepin或者说是deepin的商业分支。
    • ubuntu基于debian。
    • linux界主要分两种发行版本,debian(ubuntu、deepin、uos、银河麒麟kylin等)和redhat(fedora、centos、中标麒麟neokylin、中兴新支点newstart等),分别对应apt-get和yum安装命令。绝大部分的linux系统都基于或者衍生自这两种发行版本。
    • 理论上基于同一种系统内核的,在其上编译的程序可以换到另外的系统运行,前提是编译器版本一致,比如都是gcc4.9,在ubuntu14.04 64位用gcc4.9编译的Qt程序,是能够在uos 64位上运行的。
    • 高版本编译器的系统一般能够兼容低版本的,比如你用gcc4.9编译的程序是能够在gcc7.0上运行,反过来不行。
    • 意味着如果你想尽可能兼容更多的系统,尽量用低版本的编译器编译你的程序,当然要你的程序代码语法支持,比如c++11就要从gcc4.7开始才支持,如果你的代码用了c++11则必须至少选择gcc4.7版本及以上。
    • 用Qt编写linux程序为了发布后的可执行文件可以兼容各种linux系统,只要在这两种内核(debian、redhat)的系统上用低版本的编译器比如gcc4.7编译qt程序发布即可。
    • 2022-01-27补充:根据Qt官方安装包,发现基于redhat的gcc4.9编译器发布的,通用各种linux系统(亲测ubuntu各个版本、fedora、centos、deepin、uos、银河麒麟kylin、中标麒麟neokylin、中兴新支点newstart等),自己按照这个版本也亲测打包发布了亲测可用,我擦,redhat系统的也可以在debian系统跑。
    • 2022-02-10补充:debian上静态编译的程序也可以在redhat系统跑,可能静态编译去掉了很多依赖吧。
    • 2022-03-01补充:低调大佬补充,如果没有特定的依赖关系,高版本的编译器编译的程序也可以在低版本编译器的系统运行,比如alpine Linux下用gcc11/clang13编译生成的可执行二进制,依然可以在cenos5/ubuntu10上运行。并不是编译器版本的问题,也不是C++11特性的问题,这个问题涉及到太多,内核版本、gnu libc、ABI兼容等等,两句话说不清。
    • 按照QtCreator软件采用的编译器环境规则,一般来说就是低版本的可以在高版本运行,比如Qt5可以在ubuntu14/16/18/20运行,但是高版本编译器编译的就无法在低版本编译器系统运行,会提示缺少GLBC、LIBCXX、symbol xxxxxx等,比如Qt6可以在ubuntu20运行而无法在ubuntu18/16/14等运行。
    • 在uos上做开发,建议采用系统自带的Qt库环境开发,以及命令行安装开发环境,不建议使用Qt官方的安装包搭建环境,因为uos的Qt是魔改过的,用Qt官方的标准安装包的环境开发出来的程序,打包发布很可能会有依赖问题而无法运行,而用系统自带的就不存在这个问题。
    • 国产人大金仓数据库用的是postgresql数据库改的,意味着你在Qt中用postgresql数据库插件也是能够连接到人大金仓数据库的。
    • 以上未必完全正确,欢迎各位指正。
    1. 纵观Qt的发展历史,也几乎经历着合久必分、分久必合的逻辑,比如最开始QPushButton等UI控件类都是在QtGui模块中,后面越发臃肿不方便管理和升级迭代,又分离出一个QtWidgets模块;到Qt6又将QList和QVector合并了成了一个类,搞得像分久必合;而且一些数学函数以及封装的c++标准函数库的方法,逐渐放弃了Qt自己的封装改用c++标准函数库,从开始的分到现在的合统一。

    2. Qt一直在持续升级迭代,尽管新增加的代码质量明显不如诺基亚时代,但最起码有行动,慢慢完善。目前主要的升级改善在qml模块,底层也有完善,毕竟无论是widget还是qml都是公用一套底层逻辑类,底层基础一定要扎实稳固,个人这几年一直对比测试过不同Qt版本(从旧版本到新版本)很多类和函数的性能,发现官网列出来的新版本对应类和方法的性能提升改善,确实没有说谎,至于提升了多少这块有没有吹牛逼那就不清楚。

    • base64算法性能提升很大。
    • QStringList等凡是使用了QList相关的类,性能提升巨大。
    • 对比测试大概从5.12版本开始QStringList和QMap性能相当。
    • 早期版本QStringList如果查找的值先插入则时间越短,QMap则没有这个区别。
    QStringList list1, list2;
    QMap<QString, QString> map;
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        for (int i = 0; i < 100000; ++i) {
            QString s1 = QString("%1").arg(i);
            QString s2 = QString("A%1").arg(i);
            list1 << s1;
            list2 << s2;
            map.insert(s1, s2);
        }
    }
    
    void MainWindow::on_pushButton_clicked()
    {
        QElapsedTimer time;
        time.start();
        qDebug() << "111" << time.nsecsElapsed() << list2.at(list1.indexOf("9999"));
    }
    
    void MainWindow::on_pushButton_2_clicked()
    {
        QElapsedTimer time;
        time.start();
        qDebug() << "222" << time.nsecsElapsed() << map.value("9999");
    }
    
    1. 关于QtCreator中三种不同编译版本 debug、release、profile 的区别。
    • debug调试模式,编译后的可执行文件很大,带了很多调试符号信息等,方便开发阶段调试的时候进入具体的堆栈查看值。会打开所有的断言,运行阶段性能差速度慢,可能会有卡顿感觉。
    • release发布模式,编译后的可执行文件很小,不带任何调试符号信息,一般用于打包发布程序。由于经过了各种优化,会关闭所有断言,运行阶段性能最好,如果有卡顿那肯定是你的程序问题。
    • profile概述模式,编译后的可执行文件比debug小很多比release大一点,带有部分调试符号信息,在debug和release之间取一个平衡,兼顾性能和调试,性能更优但是又方便调试。
    • 使用Qt5.7版本对应三种模式编译的空白窗体程序大小:debug(1319kb)、release(24kb)、profile(90kb)。
    • debug链接的库是带d结尾的,release和profile链接的库是不带d结尾的,很多人以为profile链接的是带d结尾的其实是错误的。
    • 新的Qt在线安装程序在安装的时候,可以勾选是否安装debug调试库(对应lib目录下一堆带d结尾的文件),以前的版本是默认都安装,现在可选安装以便减少体积。
    • 无论是否安装了debug调试库,你都可以选择debug模式生成对应debug的文件,这个不知道怎么做到的。
    • 无论是哪种模式,都可以在程序中开启日志钩子输出日志信息,方便收集运行阶段的各种信息反馈给开发人员查看问题。
    • 最初的开发工具一般是具有debug和release两种模式,随着用户需求的增加和场景的需要,部分开发工具衍生出了profile模式,更有甚者比如flutter还有第四种test模式。
  • 相关阅读:
    salmon 报错:ESC[00mException : [rapidjson internal assertion failure: IsObject()] salmon quant was invoked improperly.
    报错:RSEM can not recognize reference sequence name chr1!(基因组的bam不能直接用rsem进行表达值计算)
    R: 使用tapply根据相同ID合并指定列
    linux:去除特定列为空格的行
    知乎一答:程序员为什么要关注管理
    如何掌握一门编程语言的运用
    谈谈程序员这个职业及前景
    Oracle学习笔记(2)--Centos 7 下11gR2部署
    用flask写一个简单的接口
    iptables命令详解
  • 原文地址:https://www.cnblogs.com/feiyangqingyun/p/15978991.html
Copyright © 2020-2023  润新知