pezy / QtLab

:wrench: Qt Primer
GNU Lesser General Public License v2.1
84 stars 35 forks source link

想学习下Qt,讨论一下关注点. #13

Closed ender233 closed 7 years ago

ender233 commented 7 years ago

目标:深入学习c++ 群体:非Qt程序员(c++工作上也好久没用了)

  1. 这几年感觉c++的发展有点快,c++11/14/17 标准库的功能越来越强大,对于深入学习c++来说, Qt本身的涉及的设计模式&接口&效率 是否仍有一些无可替代的优点或者值得学习之处?
  2. 剥离开GUI,单纯用Qt的库,最小系统是否搭建简单,这部分的文档是不是隔离性比较好?
  3. 顺带一问,当前Qt在业界应用的怎么样,据我所知嵌入式应用的比较多?应用领域是在拓展还是在紧缩.

多谢 : )

pezy commented 7 years ago

对于深入学习c++来说, Qt本身的涉及的设计模式&接口&效率 是否仍有一些无可替代的优点或者值得学习之处?

当然有优点和值得学习之处. 但我个人认为, 它对于"深入学习C++" 并没有什么益处. 原因如下:

  1. Qt 的年纪太大, 历史包袱很重, 你看一些 Qt 底层的代码, 写的很不"现代化", 没有什么学习价值.
  2. Qt 的优势在于其强大的工程能力, 而非用到的语言, 完全可以用 PyQt, 一样强大.
  3. Qt 的接口很有很多设计失败的地方, 如 GraphicView框架, 接口设计的很失败, 稍微深入运用, 就会发现埋了很多坑. 设计模式也并没有 .Net 或 Java SE 那么看重, 其大量运用的 MV 模式, 还很过时.
  4. Qt 在 5 以后, 存在一个极其滞后的转型, 即开始看重界面脚本化, 前端化. 这与其传统路线脱节, 却迎合了主流. 这让其使用者陷入两难, 你想学最新的主流技术吧, 就直接上 Electron, 学习纯粹的前端知识. 如果你依然需要维护传统工业软件, 那么你也不会去碰 Qt Quick 那些东西. 无论怎么选, Qt 5 推崇的那一套都不是最好的选择.
  5. 就底层数据结构来说, Qt 的效率堪忧. 就连 qSort 的文档下面都直接写到: "Use std::sort instead." 示例代码中最常见的容器 QList, 简直是巨坑, 在实际项目中, 实际上是最需要谨慎使用的. 还不如老老实实的用 std::vector 可靠. 随着 C++ 标准库的发展, Qt 的灵活性和方便性, 越来越不明显.

剥离开GUI,单纯用Qt的库,最小系统是否搭建简单,这部分的文档是不是隔离性比较好?

这个问题我没太明白, Qt 5.7 粗略数数有三十多个模块(不算 Quick 那些), GUI 只是其中一部分, 即使剥离开依然很庞大啊, 无所谓最小的系统. 如果就搭建环境来说, Qt 这方面是最友好的了, 收费版不必说, 开源版集成的超级方便, 下对应的安装包装就行了, 连以前 4.x 时代的编译都省了. 文档也都是分开的, 隔离性指什么呢?

顺带一问,当前Qt在业界应用的怎么样,据我所知嵌入式应用的比较多?应用领域是在拓展还是在紧缩.

这么说吧, 我从 2014年开始, 陆续去参加了三次 Qt 开发者大会, 一次比一次寒碜, 场地越来越小, 时间越来越短, 就连伙食, 也从最初的高档自助餐沦为盒饭...

所以, 我个人猜测, Qt 的业务下坡应该是挺明显的... 用 Qt 开发桌面客户端的, 基本都是传统工业领域, 图形图像领域. 另外就是你说的 嵌入式, 跨平台的优势明显, 所以在嵌入式上的体现最为突出. 这一般都是军工, GIS, 和物联网行业.

5.5 的时候想进军游戏行业, 整了个 Qt3D. 5.7 的时候想进军企业级数据管理, 整了个 Data Visualization 和 QChart. 扩张的幅度还是挺大的, 但这仅仅是技术上的一种扩张.

实际上, 这几个新模块也仅限于例子比较华丽, 吸引眼球. 真用来干活就会发现坑挺多的...

pezy commented 7 years ago

回答完你的问题, 我发现我提到 Qt 的问题好多, 主要是我天天都用 Qt, 天天都要面对这些问题, 所以容易总结出这些. 辛亏是在这里, 要是在知乎, 又要被人喷为 Qt 黑了.

实际上, Qt 的优点太明显也太多, 学习它还是非常有必要的.

因为 Qt 能教给你的, 是一种解决各类问题的经验汇总. 譬如客户给你提了一大堆需求, 你用不着一个个去网上搜成熟的解决方案, 只需要翻翻 Qt 的文档和例子, 就大概明白实现的难度了.

Qt 博大精深, 几乎无所不包. 是接私活的最佳工具, 几乎通吃各行各业, 无论你是传统行业的, 还是新兴行业, 甚至是互联网, 游戏行业, 都有能用到 Qt 的地方. 其跨平台能力, 远超其他同类工具. 甚至你有时想写点小工具自己用, Qt 依然是最佳选择, 会开发的又快又好.

微软系能带给你的方便, Qt 同样可以; 开源系能带给你的开放, Qt 也可以. 你可以信赖它, 把它当作一套完整的工作流. 遇到问题时, 也可以随时翻看其源码, 看它的实现原理.

用的多了, 它就像一个脚手架, 工具环境的问题你都不需要考虑了, 只需要考虑要实现的功能. 专注于业务逻辑. 有时, 需要华丽丽的界面, 它也完全可以胜任.

总之, 你要学习他, 关注点不应该是 C++ 语言这个层面, 而是工程的视角. 关注它是如何帮你组建起一个项目的基础环境的, 关注它是如何解决跨平台问题, 如何管理成千上万个页面, 如何流畅规整的实现千奇百怪的业务需求而不乱的.

这很考验重构能力, 代码整洁能力, 甚至是编码习惯. 就连它接口的命名, 也很值得玩味. 对于工程能力的锻炼, 实在大有裨益.

ender233 commented 7 years ago

所以我在这里问你了 :)

隔离性指代的是如此庞大的Qt 是否只关注或者安装想要学习的部分就可以run起来 无关的部分就不用管了,省着扰乱视线,隔离差就跟代码耦合一样带来高学习成本。 从你的描述看,隔离性是不错的。

当成个人工具包也不错,够全能。就冲这一点,学会也是大有裨益。感谢分享 Qt纳入今年学习计划里面去。

另外,有没有感觉c++势头不错呢,我看YouTube上越来越多的人关注讲解新标准,会议越来越多;矛盾的是 最近收集了几个同事的公司技术栈,后台从c++转go的倒是还多。期待今年的c++大会我能听懂他们在说啥。

stlcours commented 7 years ago

马上就要出qt lite了,估计就是你想要的东西。

  1. Qt 的年纪太大, 历史包袱很重, 你看一些 Qt 底层的代码, 写的很不"现代化", 没有什么学习价值. 不可能,QT是完全的OO框架,不存在不现代化的问题。就连许多全局变量,就非要写成Qt:red这种方式,名字短点还好,名字长了简直要疯掉,但其目的就是为了OO,也就是现代化。 就算QT底层有所谓的“非现代化”,那也是C时代的技巧,也就是黑客的高超技巧,难道就不值得你学习吗?不学习也可以,毕竟我们都是开发应用为主,但你也用不着鄙视吧。 何况QT5大规模重构过一次,这还不叫现代化,那什么叫做现代化? 更别说马上就要推出的Qt Lite

  2. Qt 的优势在于其强大的工程能力, 而非用到的语言, 完全可以用 PyQt, 一样强大. 我没用过PyQT,但是用过分别用过Python和Qt。不知道你到底做过什么项目。PyQt都是给给个人玩或者企业内部使用,发布桌面产品,根本就不是Py这种语言所能胜任的。

  3. Qt 的接口很有很多设计失败的地方, 如 GraphicView框架, 接口设计的很失败 没用过GraphicView,但是见过非常复杂的例子,效果非常炫。不知道你说的那些坑,到底是Qt的,还是你自己造成的?

  4. Qt 在 5 以后, 存在一个极其滞后的转型, 即开始看重界面脚本化, 前端化. 这与其传统路线脱节 两项不冲突的东西,居然被你这样评价。QWidget实在是成熟的不能再成熟了,你还想叫它怎么发展。我最喜欢的是Delphi,其VCL也是成熟的不能再成熟了,最近5年的改动都很小,但是并行发展出了FMX框架,与Qt简直是异曲同工之妙。看来这是一个趋势。 另外,QML有QML的用处,而且写起来比较简单,只是你不习惯使用而已。

  5. 就底层数据结构来说, Qt 的效率堪忧. 就连 qSort 的文档下面都直接写到: "Use std::sort instead." 示例代码中最常见的容器 QList, 简直是巨坑, 在实际项目中, 实际上是最需要谨慎使用的. 还不如老老实实的用 std::vector 可靠. 随着 C++ 标准库的发展, Qt 的灵活性和方便性, 越来越不明显. Qt是主动吸收标准C++的一切优点,如果有觉得不好再重新实现。如果std::sort已经很好,为什么还要重新实现qSort?根本没必要啊。QList为什么是巨坑?我就一直用,没觉得有什么问题啊。 Qt的灵活性和方便性, 越来越不明显?隐式共享方便不方便?foreach语法方便不方便?QString空前强大、好用。qmake简单不简单、好用不好用?信号槽好用不好用?QSS美轮美奂,多语言天生自带,XML/JSON全平台自带、好用不好用?不像MFC,许多人还要额外添加tinyxml才能用,功能弱不说,第三方库天然容易造成各种不匹配。

开发者大会能说明什么问题?只能说明中国买正版的人实在太少了,或者大家都忙着挣钱、没工夫搭理这些最新的技术。

也不是我非要为QT护犊子、说好话,而是确实好用,几乎没有任何问题。非要说问题,我认为C++编译太慢了,有点受不了,另外就是QT没有能够和Delphi一样做到完全可视化开发,所以开发速度有点慢,不过比MFC还是要强很多了。

Mooophy commented 7 years ago

同意 @pezy , 有工程需要的话,拿过来用就是。个人提高而言,Qt不值得深入了解。有这个精力不如去学个新语言,接触一下新社区。

stlcours commented 7 years ago

@Mooophy 你说的新语言和新社区是指什么?能举个例子吗? Qt万分好用,是挣钱的好帮手,你以为学技术是为了什么,还不是为了挣钱!

ender233 commented 7 years ago

讨论的主题越来越宏大啊. 可以具体点. 针对std::sort的能力,很久以前读过源码,在我的眼界范围内,感觉已经实现的很好不能再好了 看过的时候写过sort大概的流程,真是针对不同数据量&分布煞费苦心.

  1. 数据量少, 快排的优势体现不了, 好, 那就用插入排序
  2. 数据量大的时候, 快排比较给力, 好, 用快排
  3. 初始数据分布不好的话, 快排时间复杂度会恶化到O(n2), 好, 上自省排序, 分割次数达到一定值的时候, 改成堆排序. 其中, 还有各种动用心机的地方, 比如插入排序的时候最优先比较first(小区间队列本身就是有序的了), 如果小于first的值, 那直接上copy_backward, 遍历也不用了.

虽然复杂度给出的都是N*Log(N), 性能还是有差异,Qt官网给出的建议是:

Use STL algorithms for sorting, except in the case of QT_NO_STL.

为啥Qt要重新实现一遍std::sort呢, 没重新实现吧,Qt出来的更早.  不知道*sort各自的版本合入的时间点都是啥时候. 对于Qt容器和STL容器的讨论很多, 算法对比讨论的比较少. 以后学习的时候我可以继续关注下.

@stlcours 多谢推荐 Qt Lite.

Mooophy commented 7 years ago

从来没觉得Qt不好,而是不值得花时间。C++在应用层的萎缩是大势所趋,而Qt主要覆盖的就是应用层,其凋零也是必然的。C++在非应用层仍有非常重要的地位,这些环节往往都是对performance要求很高,诸如:编译器、解释器、浏览器、高频交易工具、服务器中间件、3D引擎、高性能算法的实现等等,这些领域的C++产品更值得研究,这些领域哪个用得上Qt?

非要在应用层折腾,想多赚钱的话,不如去玩JavaScript。来钱又快,需求量又大。

Qt(及其他类似的C++工具)就好像19世纪的刀法,在冷兵器时代确实拔群。可人家都开始玩枪了。。

Mooophy commented 7 years ago

JavaScript,Python, R, Ruby, ML, Haskell, Matlab, F#, Scala, Java, C# 这些语言及其社区都很值得接触。

pezy commented 7 years ago

对于Qt容器和STL容器的讨论很多, 算法对比讨论的比较少. 以后学习的时候我可以继续关注下.

你可以看下这篇文章: https://marcmutz.wordpress.com/effective-qt/containers/

讲的很深入很详尽. 软工方面没有什么万能药, 量体裁衣才是比较理性的做法.

pezy commented 7 years ago

Qt万分好用,是挣钱的好帮手,你以为学技术是为了什么,还不是为了挣钱!

Qt 的确可以挣钱, 但不是所有人学技术都是为了挣钱. 您此话一出, 我都没有与您争论的欲望了. 挣钱开心就好~ :smiley_cat:

stlcours commented 7 years ago

@Mooophy 你对这么多语言感兴趣,必然不精。我其实也都是一直忍着不学新语言、新框架,因为门门不精的话,会更加郁闷的。

@pezy 我也非常有探索技术本身的欲望,但是没办法,人还是要现实一点,而技术本身是几辈子都学不完、研究不完的,只能挑其中很小一部分深入研究,剩下大部分时间还是要做挣钱的项目,这就是我的学习编程的哲学。

Mooophy commented 7 years ago

一个合格的CS毕业生都是应该掌握六七种,接触十多种甚至更多编程语言的。当具备一定基础之后,特别是编译功底之后,看待不同语言其实是看待不同的模型解决同样的问题。

比如内存碎片化问题,C++在没有额外处理的情况下,一定会导致内存碎片化。而C#,VB, F#这方面就有所缓解。因为CLR会把碎片化了内存重新连在一起。简单的讲就是把内存里的所有对象看成一个object graph,CLR会从graph的某个入口进入,遍历整个graph,然后把较细碎的对象重新连在一起。

再比如各语言对数据结构的原生支持。C基本没啥数据结构,都得自己搭。C++的标准库支持一定的底层的数据结构。而到了php, python之类的脚本化语言,提供的是更复杂的数据结构,然后再把数据结构的API开放给程序员使用,提供更高的便利性和更为强大的功能性。而到了JavaScript,这语言本身就是个复杂数据结构,而且JS就直接把这个数据结构开放给程序员自己玩了。

再比如元编程,不同语言的支持方式和支持程度是不一样的。C通过Macro,发生在编译前。C++保留Macro的前提下,又提供了模板,于是C++具备了编译前和编译中两种元编程模式。C#大大弱化了编译前的预处理,把主要的元编程能力放在了运行时的反射,这样的好处是避免了Macro和模板本身存在的阅读性差、难于维护、延长编译时间的问题。但C#毕竟是个静态语言,这就导致他永远无法达到Ruby之类极其强大的运行时元编程能力。

总之,接触一门不熟悉的语言,就像去一个陌生的地方旅行。我们知道的是:这个地方会有食物、会有人、会有建筑。我们不知道的是:那里食物的味道、人的习惯、建筑的风格。我们完全可能会因为一次旅行而爱上一个新的城市。可谁会因为旅行而生疏了家乡?

pezy commented 7 years ago

我们完全可能会因为一次旅行而爱上一个新的城市。可谁会因为旅行而生疏了家乡?

意味深长, 一语双关啊.... :sweat_smile:

stlcours commented 7 years ago

我们完全可能会因为一次旅行而爱上一个新的城市。可谁会因为旅行而生疏了家乡?

其实还是会生疏的。我已经在外面漂泊很久很久了,家乡是什么样都已经不知道了。光有感情也没用啊。

就语言来说,我最喜欢的还是Delphi(看我的头像就知道了),但是最近几年因为工作关系天天QT,导致只有精力去收集一些Delphi资料、看一眼新特征、了解一下大致的情况,这不是生疏是什么?反倒是对天天使用的QT有了不少感情。

另外,语言本身很简单、甚至没有什么区别,但是各种库的熟悉和使用,都要耗费大量的精力啊。这可不是闹着玩的。同样一个中型项目,也许各种语言都能实现,写到20%的时候,可能没多大区别,到50%的时候区别已经很大了,到100%的时候就已经完全不一样了。无它,除了语言之外的各种类、各种控件、各种RTL、各种UI的特征实在太不一样了。其实我手里的项目的上一个版本就是Delphi做的,新版本全部推翻后使用C++ QT做,两种语言我都比较熟悉,但是可借鉴的方法不到3%(还主要是因为某些功能需要使用相同的WinAPI),因为在相似的语法的背后,伴随的是巨量的工作量,冷暖自知。

pezy commented 7 years ago

根本没必要啊。QList为什么是巨坑?我就一直用,没觉得有什么问题啊。

今天偶然看到 CppCon 2017 的一个针对 Qt 的演讲,里面对 Qt 的容器的弊端有比较理性的讲述,远比我从工程实践上感受的深一些。 😸

感兴趣的可以看看。

附上 ppt 链接:https://github.com/CppCon/CppCon2017/blob/master/Presentations/Effective%20Qt%20-%202017%20Edition/Effective%20Qt%20-%202017%20Edition%20-%20Giuseppe%20D%27Angelo%20-%20CppCon%202017.pdf