目的:
整理Qt在研发过程中易忽略的问题。
1.std::map 与QMap再插入重复键时 前者会忽略插入的值,后者会更新值。
QMap intmap;
intmap[10]=“10”,会插入键值(10,10)
QMap QHash性能差距
QMap的性能,只要超过10个元素,就被QHash彻底拉开差距
2. 隐藏的rootitem
QTreeWidget中有一个invisibleRootItem其子节点是顶级的topLevelItem
3.数字与字符转换
QStringLiteral(“XXX%1”).arg(a) a为整形或者double型
QString::number(long a,int base=10) 进行格式化控制
4. tablewidget 清除策略
clear 清楚表头与表项 clearcontents 只清除表项
表头有两种伸缩策略
1.setstretchlastsection(true)最后一列自适应,每一列可以拉伸。
2.setsectionresizemode(QHeaderView::strection)每一列均等,不可拉伸。
5. 关于把数据存储在数据结构
引用只能初始化一次。
指针:
int a=10;
int* b =&a;
QList<int*> list;
list.append(b);
qDebug()<<“-----before--------”<<(list.at(0));
a = 12;
qDebug()<<“-----after--------”<<(list.at(0));
引用
int a=10;
int &b =a;
QList < int> list;
list.append(b);
qDebug()<<“-----before--------”<<(list.at(0));
a = 12;
qDebug()<<“-----after--------”<<(list.at(0));
6. at比[]效率高
- 因为at()进行了边界检查,如果访问超过了vector的范围,将抛出异常。operator[]主要是为了与C语言进行兼容。
- []操作会复制拷贝一份原数组,导致效率变慢。
7. i++ 比 ++i 效率慢
参看网址
对于内置类型,单独的i++和++i语句,现在的编译器基本上都会优化成++i,所以就没什么区别了。
8. 能用加减法替代乘除法,或者位移(左右移动)也行
9. 不应该将大型对象或者具有大量复制构造函数进行传值,而应该引用
10. 切记不要返回局部变量地址或者引用。返回引用的好处是不产生返回值的临时副本。
因为一旦撤出函数后,局部变量就是释放了,地址返回的是空的或者野指针。
11. 一般而言,如果一个类中含有多个virtual函数,则应包含一个虚析构函数。
12. 注意重写方法、方法重载、隐藏方法—父类与子类。
方法重载:
指的是同一作用域下不同的函数签名,当然const能改变函数签名。方法重写:
指的是子类将基类中的方法进行重写,其中不仅函数签名、而且函数返回类型也一样。方法隐藏:
13. 如果可以使用前置声明,就不要用#include XXX声明头文件。避免循环依赖,相互包含。
14. QImage中有个fill函数功能,依据像素值填充,会更新当前QImage中的像素(填充的颜色)。
QImage fill(uint pixelValue)
Fills the entire image with the given pixelValue.
15.不能使用含有Q_OBJECT类再次成为模板类。
每一个Q_OBJECT都需要通过moc为其生成代码,并且moc并未智能到如何生成模板类的特化。
16. 可能在某个项目中,判断某个窗口isVisible为true,将其show()出来发现在屏幕中没有见到,可能在某处将其move到窗口中屏幕范围之外。
17. 对于定制、流程化的东西必须文档化,在研发某个功能模块时,最好将其思路在文档,思维导图形式将其细节点、功能点东西写出来,避免脑中思路过杂导致紊乱。最好对实现东西有多种方案实现,依据项目寻找合适的方案。
18. 弄清逗号表达式与赋值表达式复杂结合,明白逗号表达式是左结合性,赋值表达式是右结合性。
19. 参数传递为引用依据情况设置,对于内置型数据(c类型的)一般传值比传引用效率高,对于面向C++一些自定义(构造函数与析构函数存在)的一般引用比传值效率高,对于Template C++也一样。对于STL类型,迭代器与函数对象都是C指针之上,传值效率高些。
20. 信号与槽 ,槽中参数可以比信号中的参数少,但是会按照顺序进行对应的(从左往右对应),如果发现某个不能对应,会进行隐式转换。但是参数不能比其信号多。
21. (windows)创建路径可以隔个空目录,但是创建目录时不能隔个空目录。
//路径可以隔空 但是dir不行
QDir dir("C:\\Users\\Administrator\\Desktop\\test");
if(!dir.exists())
{
dir.mkdir("C:\\Users\\Administrator\\Desktop\\test");
}
22. QTableWidget设置setcellWidget 如果设置了行数,列数但是没显示表格,可能是没设置行高(行高为0)。
23. switch 程序只会走case分支 ,哪怕你在{} 里,却不在case包含中,程序是不会走case之外分支。表达式的结果必须是整数,字符,布尔类型,而不能使用小数类型,也不能为一个字符串。
int c = 10;
switch(c)
{
c = 11;
qDebug() << " c1 = " << c;
case 10:
{
qDebug() << " c2= " << c;
break;
}
case 11:
{
qDebug() << " c3= " << c;
break;
}
defaut:
break;
}
c2= 10
结果:
24. Qt 翻译切换(会触发QEvent::LanguageChange)时, 注意界面有些控件设置tr的是静态的, 有些是动态的, 动态的需要设置对应的翻译。
25. QTreeWidget item绑定QWidget 注意事项
1. tree->setItemWidget(topItem, 0, headWidget); //需要通过treewidgetd调用setItemWidget 将与某列item与窗口绑定
2. topItem->setSizeHint(0, headWidget->size());//最好将item与窗口的size进行sizeHint设置,使item通过setSizeHint去确定大小
3. tree->collapseItem(topItem); //如果你要把某个item绑定的窗口能够伸缩, 那就要调用collapseItem同时,还要保证整个treewidget 也要collapseAll一次,不然对应的item widget不会以正常逻辑伸缩, 会悬浮在item上面。
26. 在研发过程中, 如果某个变量能影响到界面或者其他的值建议在初始化统一默认值。
27. QFont 是指对字体进行设置, 但是不包括字体颜色。
28. 两个整数相除/(仍然是整数) %取模
29. QTimer 启动与结束不能在不同线程
In multithreaded applications, you can use QTimer in any thread that has an event loop. To start an event loop from a non-GUI thread, use QThread::exec(). Qt uses the timer's thread affinity to determine which thread will emit the timeout() signal. Because of this, you must start and stop the timer in its thread; it is not possible to start a timer from another thread.
在多线程应用程序中,您可以在任何具有事件循环的线程中使用 QTimer。
要从非 GUI 线程启动事件循环,请使用 QThread::exec()。
Qt 使用计时器的线程关联来确定哪个线程将发出 timeout() 信号。
因此,您必须在其线程中启动和停止计时器; 不可能从另一个线程启动计时器。