`

不愉快的 Qt 之旅

阅读更多

今天尝试用 Qt 来写一个小程序,从网上抓取一些东西,并解析一下保存到本地。很简单的功能,但是却写得非常不舒服。

大致看了一下 Qt 提供的库,似乎应有尽有了。一大堆 GUI Widget 可以构建丰富的界面,方便的 QHttp 可以用于下载 Web 页面,并使用 QRegExp 进行解析,还有 Qt 强大的 QTextCodec 可以在各种编码之间进行转换。并且 Qt 4 提供了 MCV 方式,让我能轻松地把事务和视图分开处理。一切都是那么完美,似乎是专门为我准备的一样。然而它们并不是为我准备的。

我相信使用 QHttp 下载文件是非常容易的事情,于是我决定先做界面。我打算做一个列表,其中每一项对应于 Model 的一个下载会话,里面使用 QLabel 以及 QProgressBar 之类的 Widget 组装出一个会话的详细内容的展示,如果可能的话,我还想做成 Compact View 和 Expanded View 两种模式,只对当前选中的项使用 Expanded View 。看上去就像 Esperanza 的播放列表那样。

在翻看了 Qt 所带的示例以及 QListView 、QTableView 等类的 API 等文档之后,我大致了解了 Qt 的 MCV 模式:

  • Model 持有数据。
  • View 负责显示数据。也担当了一种 Controller 的角色。
  • 还有一个叫做 Delegate 的东西,它可以用于实现单项数据的编辑 (通常你有一个 List 或者是 Table 的数据) ,如果要做精细的显示,也可以让 Delegate 取代 View 的显示功能。

现在我只要从 QAbstractItemModel 继承一个自己的 Model 来保存和管理自己的下载会话,再继承一个 QAbstractItemDelegate 用于展示会话, View 应该可以用默认的 QTableView 之类的了。

到这里一切顺利。我再具体查看了下 Model 的工作方式:

  • Model 提供函数让 View 得以知道数据的行数和列数。
  • View 会调用 Model 的 index 函数,得到某行某列的一个元素的索引,这是一个 QModelIndex
  • View 会调用 Model 的 data 函数,传递一个先前获得的索引,来取得特定元素的值。
  • Model 使用诸如 dataChanged 之类的信号通知 View 数据改变了。

于是我决定在 Model 维护一个会话的 List ,每个会话通过信号通知 Model 状态改变,而 Model 再通知 View 更新视图。但是细节上比较麻烦,一堆的会话连接到 Model 上,信号发过来,无法区分是哪个会话,可以为每个会话加一个 id ,然后由 Model 来管理 id ,并在发送信号的时候带上 id 。但是现在是 View 来向 Model 索取数据,它使用行和列的索引作为标识,一个想法是把 id 就做成行号,于是某个 id 的会话发送信号说状态改变了,我正好可以就那个 id 告诉 View 第几行的数据改变了。可是如果我想要移除下载完成的会话的话,这样就不好办了,移除会话以后剩下的会话的行号就要变了,而 id 并没有得到自动同步。每次,某个 id 的会话报告状态改变, Model 需要查找一下所有的行,看哪一行对应到该 id ,然后通知 View 该行改变了。这显得非常麻烦,似乎是由于 View 强行使用行列作为数据的索引造成的。不过没关系,我干脆直接报告所有的行都变化了就好了。

而 Delegate 也相当复杂,想要实现编辑,可以提供一个 Widget ,然后显示的时候却要实现 paint 函数。我更希望使用一系列 Widget 组装起来实现一个 View 的显示,而不是自己去画。我搜索了一下邮件列表,发现 Qt 现在确实不提供这种便利,只有自己画,还好 Qt 提供了一些可以画出基本 Widget 的函数,可是诸如 Layout 之类的功能就只能自己来管理了。还有一个地方相当奇怪,我在下载了一些真实程序的源代码浏览了之后,发现 View 从 Model 那里取数据的时候还有一个 Role 参数,而 Role 不同的时候期望返回不同的东西,其中有字体、颜色、背景以及图标等,这些原本应该由 View 来处理的东西竟然全部要从 Model 那里取!最近时常用 Ruby on Rails 写一点 Web 应用,觉得 MCV 模式使用起来很顺,但是现在用 Qt 的这套构架却觉得异常别扭。

经过痛苦地编码,最后终于实现了一个还比较理想的 UI 界面。现在看来,还是 HTML + CSS 写界面舒服啊,虽然 HTML 这么多年也饱经沧桑了,但是毕竟是专门用于做界面的语言。我想不久以后在桌面应用程序这一块的专用 UI 语言也该大行其道了吧 (如果那个时候还有桌面应用的话) ,好像 Mozilla 和微软都有这类似的东西吧 ( XUL 以及 XAML 之类的东西 ) ?

接下来是下载,QHttp 用起来还是很方便的,下载之后用 QTextCodec 进行编码转换,然后使用 QRegExp 进行解析。查看了文档,发现 QRegExp 居然不支持多行搜索!后来发现下载的文件一直不对。跟踪了好久,发现是 QHttp 在指定要下载的路径的时候比较麻烦,而用了 QUrl 反而好像是在帮倒忙,结果资源位置都指定错了。

我决定让 Qt 的体验和这个程序暂时告一段落。今天的经历实在是让原本在我心目中地位很高的 Qt 程序库一下子降低了许多。用 Qt 构建出来的 KDE 用起来觉得处处设计都很贴心,而今天用 Qt 却好像感觉很多地方该有的功能没有,不该有的功能一大堆,特别别扭。所谓更换工作就是最好的休息,先把这个小程序放一放好了,要不然要对 Qt 积攒太多偏见了。

分享到:
评论

相关推荐

    QT入门之qt软件安装指南

    至此,你已经成功地在Windows 10上安装了Qt 6.3.1和Qt Creator 8.0.0,可以开始你的Qt编程之旅了。记得不断实践,查阅文档,探索更多Qt的功能和特性,你会发现它是一个强大而灵活的开发工具。祝你在Qt编程的世界里...

    QT萤石代码 QT萤石代码 QT萤石代码

    QT萤石代码QT萤石代码QT萤石代码QT萤石代码QT萤石代码QT萤石代码QT萤石代码QT萤石代码QT萤石代码QT萤石代码QT萤石代码QT萤石代码QT萤石代码QT萤石代码QT萤石代码QT萤石代码QT萤石代码QT萤石代码QT萤石代码QT萤石代码...

    Qt 5.7.0 静态编译库(不含qtwebengine、qtwebview、qt3d),亲测可用

    刁肥宅自己编译的Qt 5.7.0的静态编译库,亲测用这个库编译的exe程序,不需要任何dll和其他附加文件便可以在不带Qt环境的电脑上运行。

    QT学习之路2+QT5教程+范例

    QT学习之路2+QT5教程+范例这个资料集合,显然是为了帮助初学者快速掌握QT开发技能,通过实例来深化理解。 首先,让我们关注《QT5教程 完整版.pdf》。这份文档应该详尽地介绍了QT5的各个方面,包括QT5的基础概念、...

    Qt下实现WebServer的调用之qtsoap

    如果qtsoap不在标准的Qt库路径中,可能需要手动指定其路径。 2. **创建SOAP请求**:使用`qtsoap::SoapRequest`类创建一个SOAP请求。你需要提供SOAP消息的XML格式,包括方法名、参数等。例如: ```cpp qtsoap::...

    [Qt]Qt Creator汉化方法 qt汉化包

    【Qt Creator汉化方法】 Qt Creator是一款强大的跨平台集成开发环境(IDE),广泛用于C++和Qt应用程序的开发。为了方便中国用户使用,Qt Creator提供了汉化包,使其界面能够显示为中文。以下是一个详细的Qt Creator...

    Qt之C++开发框架基础入门-Markdown文档.zip

    Qt之C++开发框架基础入门:探索编程的新世界 亲爱的编程爱好者,你是否渴望在C++的海洋中乘风破浪,...不要再犹豫,现在就点击查看这份文档,开始你的Qt与C++开发之旅吧!让我们一起在编程的世界里探索、学习、成长!

    Qt之路qt网页版.zip

    【Qt之路:构建Qt网页版应用】 Qt是一个跨平台的应用程序开发框架,广泛用于桌面、移动和嵌入式系统的GUI编程。它由The Qt Company提供,并遵循LGPL和商业许可。在本教程中,我们将深入探讨如何使用Qt来创建一个...

    QT中文参考手册(QT help)

    关于Qt Qt的版本 常见问题解答 Window系统特性注释 如何购买Qt 安装 如何学习Qt 教程一, 教程二 实例 循序渐进实例 白皮书 Qt 3.0的关键特征 修改历史 从Qt 2.x移植到Qt 3.x 简体中文汉化日志 Qt...

    Qt学习之路---尤其适用Qt初学者

    ** —— 开始Qt之旅的第一步,了解如何构建简单的Qt应用程序。 2. **初探信号槽** —— 探讨Qt的核心机制之一:信号与槽,这是实现组件之间通信的基础。 3. **组件布局** —— 学习如何使用Qt的布局管理器来组织窗口...

    Qt 5.15.2在线下载工具

    Qt 5.15.2 是一个流行的...通过使用“qt在线下载工具5.15.2”,你可以方便地获取到这个版本,开始你的Qt项目开发之旅。记得在实际应用中结合Qt的官方文档和社区资源,以便更好地理解和利用Qt 5.15.2提供的所有功能。

    Qt镜像源_qt_mirror

    在线安装Qt时,使用Qt镜像源可以显著提高下载速度,尤其是在网络环境不佳或者官方服务器访问较慢的情况下。 Qt镜像源是Qt官方仓库的镜像,它存储了Qt的不同版本、模块和组件,供用户下载使用。镜像源通常由世界各地...

    QT学习教程PDF(《Qt Creator快速入门》;C++ GUI Qt4 编程(第二版) ;Qt及Qt+Quick开发实战精解)

    QT,全称Qt,是一个跨平台的C++图形用户界面应用程序开发框架,由挪威的Trolltech公司(现为The Qt Company)开发,被广泛应用于桌面应用、移动应用以及嵌入式系统中。Qt Creator是Qt开发环境的主要IDE(集成开发...

    适用于Qt4、Qt5的mqtt客户端

    它基于发布/订阅模型,使得消息传递高效、可靠,尤其适合低带宽、高延迟或不可靠的网络环境。MQTT协议的核心特性包括最小化协议开销、发布/订阅消息模式以及QoS(Quality of Service)等级,确保了消息的可靠传输。 ...

    qt之QComboBox定制

    下拉框到处可见,作为一个图形库,qt也提供了QtComboBox类来供我们使用,但是有些时候简单的下拉列表已经满足不了我们的需求,如58上选择岗位是一个下拉表格,这个时候就需要我们自己定制一下QComboBox。

    qt5版本log4qt

    每个类通常有一个与之关联的logger,用于记录该类的日志信息。Logger具有继承性,未定义的logger会默认继承其父logger的配置。 2. **Appender**: 负责将日志消息输出到特定的目标,如控制台、文件、数据库、网络等...

    Qt及QtQuick开发实战精解高清PDF

    Qt基础知识包括但不限于: 1. 安装与配置:如何在不同的操作系统中安装Qt开发环境,以及如何配置所需的编译器和工具。 2. 信号与槽机制:Qt中的核心机制,用于对象间通信和事件处理。 3. 基本控件使用:Qt提供的...

    QT帮助文档_中文版.rar_QT_qt 界面_qt帮助中文版_qt文档_中文版qt界面

    QT界面中文帮助文档,QT界面比MFC要好用

    log4qt qt5版本

    在软件开发过程中,日志记录是必不可少的一个环节,它能够帮助开发者追踪程序运行状态,定位错误,优化性能。在Qt框架下,log4qt是一个广泛使用的日志记录库,它借鉴了Java的log4j设计模式,为Qt应用程序提供了强大...

    期末大作业C++课程设计基于QT的赛车小游戏设计源码.zip

    玩家可通过键盘对赛车进行操控,开启精彩的游戏之旅,感受全新的体验。代码注释全,新手也可操作。 期末大作业C++课程设计基于QT的赛车小游戏设计源码。玩家可通过键盘对赛车进行操控,开启精彩的游戏之旅,感受全新...

Global site tag (gtag.js) - Google Analytics