Qt操作小技巧
1、将QstringList列表中的所有字符串连接成一个字符串,每个元素由给定的分隔符分隔,可以使用join函数,例:
QstringList list;
list << “a” << “b” << “c”;
list.join(“,”); // “a,b,c”
2、改变一个信号和槽的连接响应类型
- 可以在连接信号槽的时候对connect的第五个参数进行复制,
enum ConnectionType {
AutoConnection, // 自动连接,根据当前执行所在线程决定
DirectConnection, // 直接连接(同步执行,在同一线程时)
QueuedConnection, // 队列连接(异步执行,在接收者的线程执行)
BlockingQueuedConnection, // 阻塞连接(信号线程阻塞直到槽函数返回,注意如果接收者驻留在信号的同一线程则不能使用此连接,会造成程序死锁)
UniqueConnection = 0x80 // 组合连接(如果连接已经存在,connect将连接失败)
};
- 通过元对象类(QMetaObject)的invoke函数对需要修改的对象进行操作,例:
int methodIndex = pushButton->metaObject()->indexOfMethod("animateClick()");
QMetaMethod method = metaObject->method(methodIndex);
method.invoke(pushButton, Qt::QueuedConnection);
在对象上调用此方法,如果成员可以被调用则返回true,如果没有这样的成员或者参数不匹配,则返回false。
调用可以是同步也可以是异步,取决于connectionType。
3、程序分辨率自适应
- 封装一个分辨率自适应类型,逐一对每个控件进行分辨率适应操作,该方法计算方式比较复杂,但是封装好后简单易用
- 如果对Qt的视图场景比较熟悉的话,可以将界面嵌入到视图场景里面,场景会根据分辨率自适应大小,需要注意的是要对最外层的view进行一个分辨率比较的计算,确保view自适应。
4、使用FTP下载远端文件夹又不知道文件夹里面的文件名时,可以使用QFtp的list函数,传入文件路径后,ftp在连接上远端后会获取该文件夹下的所有文件列表,只需要连接listInfo信号就可以获取到文件夹的内容,
connect(m_ftp, SIGNAL(listInfo(const QUrlInfo &)), this, SLOT(slot_showFileList(const QUrlInfo &)));
然后再对文件进行逐一下载即可。
5、在定义结构体时经常需要对结构体的内容进行字节对齐,因为Qt默认是4字节对齐,可能会对一些数据类型进行补零操作,这时就可以造成部分数据位无法对应,这时就需要修改字节对齐方式,例:
#pragma pack(push)
#pragma pack(1)
struct ModuleObsMsg
{
int m_ModuleID;
ObsStateMsg m_ObsMsg;
};
#pragma pack(pop)
设置为1字节对齐(pack(1)中1就在需要设置的字节对齐数)。
6、在需要制作复杂表单(需要有复选框,按钮,进度条,各类文字显示等)时,可以采用如下几种方法:
- 将item中需要显示的内容封装成一个独立的item类,然后再将item添加到列表中,该方法好处在于可以快速的将需要显示的内容添加到列表中,但是当数据量变大时就会造成大量的资源浪费和程序卡顿刷新慢,适用于入门学习。
- 通过模型委托的方式对数据表格进行操作,在委托中对item进行绘制,在模型中进行数据操作,该方法好在在于将控件显示可数据操作分开更节省资源,且灵活多变,便于大量数据的处理和显示,对开发者要求有一定的自绘控件基础和模型委托需要有一定的了解。
7、当信号槽需要通过多个类进行通信信号转发通信时可以建立一个独立的信号中转类进行信号传递,从而解决信号在多个类之间传递导致管理混乱,代码逻辑混乱等问题。信号中转类建议写成单例模式)。
8、大型工程建议采用独立模块子工程模式,或者插件模式进行框架设计。
9、简单的输入框输入限制可以采用QDoubleValidator, QIntValidator, QRegExpValidator, and QRegularExpressionValidator这几个类型进行简单处理,例:
// 正则限制
QRegExp rx("-?\\d{1,3}");
QValidator *validator = new QRegExpValidator(rx, this);
QLineEdit *edit = new QLineEdit(this);
edit->setValidator(validator);
// int类型限制
QValidator *validator = new QIntValidator(100, 999, this);
QLineEdit *edit = new QLineEdit(this);
edit->setValidator(validator);
10、当QString中需要输入中文又需要设置文本格式时可以采用简便写法:QString(u8”中文”),这样设置后台输入的文本格式就是utf-8格式的了。
11、对控件进行样式设置时经常会遇到需要将某一类控件设置成统一样式如:QPushButton,但是又会有几个按钮不需要设置成这类样式,这时有两种方法可以对这类按钮设置。
- 在样式中加入控件名进行精准设置:
QPushButton#pushButton_alarm {
样式内容;
}
这种方法可以针对个别控件进行设置,但是当需要设置样式的两种控件都比较多时,一一写控件名的话就会显得比较臃肿,这时可以使用第二种方法。
- 可以利用控件的动态属性对类型进行区分,例:
QPushButton[type="type1"]{
样式内容;
}
12、在网络通信中需要将结构体数据以QByteArray发送到远端时可以使用reinterpret_cast
进行转换,例:
QByteArray byteData;
byteData.append(reinterpret_cast<const char *>(this), sizeof(InsCalcDataMsg) - 4);
byteData.append(reinterpret_cast<const char *>(data.constData()), data.size());
return byteData;
接收后再根据传递的结构体数据进行解析,
return reinterpret_cast<const T *>(data);
T为需要的类型。
13、在对QString进行分割时,可能会遇到分割后有空字符的情况,例:
QString str = “a,,b,c,,”;
str.split(“,”); // 输出:”a” ,“”, “b”,”c”,””
这时如果需要去除空字符则可以在分割时加入过滤条件:
str.split(“,”, QString::SkipEmptyParts); // 输出:”a”,“b”,”c”,