• Qt开发经验小技巧241-245


    1. QString类是我个人认为Qt所有类中的精华,封装的无可挑剔。内置了各种进制数据的转换,比如将数据转成10进制、16进制显示,或者将10进制、16进制数据转成字符串显示。这里很容易忽略的一点就是,很多人以为就是支持2进制、10进制、16进制之类的,其实不是的,里面实现了 2-36 之间的任意进制转换,可以自行翻阅源码查看实现。
    char data[2];
    data[0] = 0x10;
    data[1] = 25;
    
    //输出 2进制显示 "10000" "11001"
    qDebug() << "2进制显示" << QString::number(data[0], 2) << QString::number(data[1], 2);
    //输出 5进制显示 "31" "100"
    qDebug() << "5进制显示" << QString::number(data[0], 5) << QString::number(data[1], 5);
    //输出 10进制显示 "16" "25"
    qDebug() << "10进制显示" << QString::number(data[0]) << QString::number(data[1]);
    //输出 16进制显示 "10" "19"
    qDebug() << "16进制显示" << QString::number(data[0], 16) << QString::number(data[1], 16);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    1. QtSql模块封装了各种数据库操作,使得Qt操作各种数据库非常的简单,支持各种各样的数据库,最基础的ODBC方式也支持连接到各种数据库。有个很容易忽视的要点就是在连接sqlserver数据库的时候,你会发现第三方的数据库工具也没有配置数据库,但是可以连接成功,而在Qt中的常规数据库连接写法却不行,那是因为你代码写错了,要用另外一种写法。
    //连接sqlite数据库
    QSqlDatabase database = QSqlDatabase::addDatabase("QSQLITE");
    //只需要指定数据库文件的绝对路径即可
    database.setDatabaseName("d:/test.db");
    
    //连接mysql数据库
    QSqlDatabase database = QSqlDatabase::addDatabase("QMYSQL");
    database.setDatabaseName("test");
    database.setHostName("127.0.0.1");
    database.setPort(3306);
    database.setUserName("root");
    database.setPassword("root");
    
    //连接到sqlserver数据库
    //方式一通过odbc数据源,前提是必须配置好数据源。
    QSqlDatabase database = QSqlDatabase::addDatabase("QODBC");
    database.setDatabaseName("数据源名称");
    database.setUserName("sa");
    database.setPassword("123456");
    
    //方式二通过驱动字符串,无需配置数据源。设置数据库名称就带了主机地址端口和用户信息所有后面这些设置不需要,强烈建议推荐此方法。
    QSqlDatabase database = QSqlDatabase::addDatabase("QODBC");
    QStringList list;
    list << QString("DRIVER={%1}").arg("SQL SERVER");
    list << QString("SERVER=%1,%2").arg("127.0.0.1").arg(1433);
    list << QString("DATABASE=%1").arg("test");
    list << QString("UID=%1").arg("sa");
    list << QString("PWD=%1").arg("123456");
    database.setDatabaseName(list.join(";"));
    
    //连接到postgresql数据库
    QSqlDatabase database = QSqlDatabase::addDatabase("QPSQL");
    database.setDatabaseName("test");
    database.setHostName("127.0.0.1");
    database.setPort(5432);
    database.setUserName("postgres");
    database.setPassword("123456");
    
    //连接到oracle数据库
    QSqlDatabase database = QSqlDatabase::addDatabase("QOCI");
    database.setDatabaseName("test");
    database.setHostName("127.0.0.1");
    database.setPort(1521);
    database.setUserName("system");
    database.setPassword("123456");
    
    //连接到人大金仓kingbase数据库(内核就是postgresql)
    QSqlDatabase database = QSqlDatabase::addDatabase("QPSQL");
    database.setDatabaseName("test");
    database.setHostName("127.0.0.1");
    database.setPort(54321);
    database.setUserName("SYSTEM");
    database.setPassword("123456");
    
    //通过odbc数据源连接到各种数据库,前提是必须配置好数据源,只需要设置数据库名称为数据源的名称,填写用户名和密码就行,其他的主机地址和端口不需要。
    QSqlDatabase database = QSqlDatabase::addDatabase("QODBC");
    database.setDatabaseName("数据源名称");
    database.setUserName("system");
    database.setPassword("123456");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    1. 如果信号槽关联函数 connect(obj, SIGNAL(), this, SLOT()); 执行多次则会重复关联(意味着会执行多次),而取消信号槽关联函数 disconnect(obj, SIGNAL(), this, SLOT()); 只需要执行一次就可以将之前关联的(哪怕是重复关联过)全部清除。很多初学者会遇到为什么点一下居然执行多次的原因就在这里,很可能代码中写了 on_objName_clicked(); 这种Qt内置自动生成关联的槽函数,然后自己又在代码中调用 connect 绑定了一次,导致重复绑定。提个建议:其实Qt可以过滤下如果是完全一样的绑定则认为是一个而不是多个。
    //为了保证永远只有一个关联可以在关联前面执行一次取消关联
    disconnect(obj, SIGNAL(), this, SLOT());
    connect(obj, SIGNAL(), this, SLOT());
    
    • 1
    • 2
    • 3
    1. 通过对Qt自带Examples的源码研究你会发现,越往后的版本,越喜欢用智能指针QScopedPointer来定义对象,这样有个好处就是用的地方只管new就行,一直new下去,不用担心资源释放问题,智能指针会给你在合适的时机释放,相当于可以少些一行代码 xxx->deleteLater(); ,而且避免不必要的麻烦,不然很多地方你要判断 if (!xxx) 看下对象是否ok。
    QWidget *widget;
    //用的地方先new
    widget = new QWidget;
    //用完释放对象
    widget->deleteLater();  
        
    //智能指针写法
    QScopedPointer<QWidget> widget;
    //只管new尽管new不用管释放
    widget.reset(new QWidget);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    1. 如果控件中存在布局,在调用setLayout重新设置布局的时候,会提示 QWidget::setLayout: Attempting to set QLayout … 之类的信息,说是已经存在了布局,需要删除之前的布局才能重新设置布局,按道理Qt推荐的是调用 layout()->deleteLater() 方法去删除对象,更安全,但是在这里不起作用,你需要用 delete layout() 来删除,着实奇怪。

    国内站点:https://gitee.com/feiyangqingyun
    国际站点:https://github.com/feiyangqingyun

  • 相关阅读:
    C# PaddleDetection 安全帽检测
    前端入门链接汇总
    1、【开始】【简介】Qlib:量化平台
    C++PrimerPlus跟读记录【第五章】循环和关系表达式
    使用【Blob、Base64】两种方式显示【文本、图片、视频】 & 使用 video 组件播放视频
    创建commons和cart模块
    《用Go语言自制解释器》之第2章 语法分析
    Leetcode—547.省份数量【中等】
    IPS: Instance Profile for Shapelet Discovery for Time Series Classification
    SNMP简单网络管理协议总结
  • 原文地址:https://blog.csdn.net/feiyangqingyun/article/details/126616708