Qt开发经验小技巧合集 (6)

QVariant类型异常的强大,可以说是万能的类型,在进行配置文件的存储的时候,经常会用到QVariant的转换,QVariant默认自带了toString、toFloat等各种转换,但是还是不够,比如有时候需要从QVariant转到QColor,而却没有提供toColor的函数,这个时候就要用到万能办法。

if (variant.typeName() == "QColor") { QColor color = variant.value<QColor>(); QFont font = variant.value<QFont>(); QString nodeValue = color.name(QColor::HexArgb); }

Qt中的QString和const char *之间转换,最好用toStdString().c_str()而不是toLocal8Bit().constData(),比如在setProperty中如果用后者,字符串中文就会不正确,英文正常。

Qt的信号槽机制非常牛逼,也是Qt的独特的核心功能之一,有时候我们在很多窗体中传递信号来实现更新或者处理,如果窗体层级比较多,比如窗体A的父类是窗体B,窗体B的父类是窗体C,窗体C有个子窗体D,如果窗体A一个信号要传递给窗体D,问题来了,必须先经过窗体B中转到窗体C再到窗体D才行,这样的话各种信号关联信号的connect会非常多而且管理起来比较乱,可以考虑增加一个全局的单例类AppEvent,公共的信号放这里,然后窗体A对应信号绑定到AppEvent,窗体D绑定AppEvent的信号到对应的槽函数即可,干净清爽整洁。

QTextEdit右键菜单默认英文的,如果想要中文显示,加载widgets.qm文件即可,一个Qt程序中可以安装多个翻译文件,不冲突。

Qt中有个全局的焦点切换信号focusChanged,可以用它做自定义的输入法。Qt4中默认会安装输入法上下文,比如在main函数打印a.inputContext会显示值,这个默认安装的输入法上下文,会拦截两个牛逼的信号QEvent::RequestSoftwareInputPanel和QEvent::CloseSoftwareInputPanel,以至于就算你安装了全局的事件过滤器依然识别不到这两个信号,你只需要在main函数执行a.setInputContext(0)即可,意思是安装输入法上下文为空。

在Qt5.10以后,表格控件QTableWidget或者QTableView的默认最小列宽改成了15,以前的版本是0,所以在新版的qt中,如果设置表格的列宽过小,不会应用,取的是最小的列宽。所以如果要设置更小的列宽需要重新设置ui->tableView->horizontalHeader()->setMinimumSectionSize(0);

Qt源码中内置了一些未公开的不能直接使用的黑科技,都藏在对应模块的private中,比如gui-private widgets-private等,比如zip文件解压类QZipReader、压缩类QZipWriter就在gui-private模块中,需要在pro中引入QT += gui-private才能使用。

#include "QtGui/private/qzipreader_p.h" #include "QtGui/private/qzipwriter_p.h" QZipReader reader(dirPath); QString path(""); //解压文件夹到当前目录 reader.extractAll(path); //文件夹名称 QZipReader::FileInfo fileInfo = reader.entryInfoAt(0); //解压文件 QFile file(filePath); file.open(QIODevice::WriteOnly); file.write(reader.fileData(QString::fromLocal8Bit("%1").arg(filePath))); file.close(); reader.close(); QZipWriter *writer = new QZipWriter(dirPath); //添加文件夹 writer->addDirectory(unCompress); //添加文件 QFile file(filePath); file.open(QIODevice::ReadOnly); writer->addFile(data, file.readAll()); file.close(); writer->close();

理论上串口和网络收发数据都是默认异步的,操作系统自动调度,完全不会卡住界面,网上那些说收发数据卡住界面主线程的都是扯几把蛋,真正的耗时是在运算以及运算后的处理,而不是收发数据,在一些小数据量运算处理的项目中,一般不建议动用线程去处理,线程需要调度开销的,不要什么东西都往线程里边扔,线程不是万能的。只有当真正需要将一些很耗时的操作比如编码解码等,才需要移到线程处理。

在构造函数中获取控件的宽高很可能是不正确的,需要在控件首次显示以后再获取才是正确的,控件是在首次显示以后才会设置好正确的宽高值,记住是在首次显示以后,而不是构造函数或者程序启动好以后,如果程序启动好以后有些容器控件比如QTabWidget中的没有显示的页面的控件,你去获取宽高很可能也是不正确的,万无一失的办法就是首次显示以后去获取。

数据库处理一般建议在主线程,如果非要在其他线程,务必记得打开数据库也要在那个线程,即在那个线程使用数据库就在那个线程打开,不能打开数据库在主线程,执行sql在子线程,很可能出问题。

新版的QTcpServer类在64位版本的Qt下很可能不会进入incomingConnection函数,那是因为Qt5对应的incomingConnection函数参数变了,由之前的int改成了qintptr,改成qintptr有个好处,在32位上自动是quint32而在64位上自动是quint64,如果在Qt5中继续写的参数是int则在32位上没有问题在64位上才有问题,所以为了兼容Qt4和Qt5,必须按照不一样的参数写。

#if (QT_VERSION > QT_VERSION_CHECK(5,0,0)) void incomingConnection(qintptr handle); #else void incomingConnection(int handle); #endif

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzxjpf.html