Qt 5:如何制作“纯 C++”客户端套接字?
Posted
技术标签:
【中文标题】Qt 5:如何制作“纯 C++”客户端套接字?【英文标题】:Qt 5: how to make a "pure c++" client socket? 【发布时间】:2013-12-17 15:59:26 【问题描述】:我正在构建一个 QtQuick 应用程序,我需要一个 TCPSocket 来轮询设备并填充我想要显示的数据结构。我找到了很多关于套接字和 Qt 5 小部件的示例,但我无法将套接字创建为不是从 QObject 派生的 C++ 类。
我的理解是,如果我想与我的 QML 视图交换数据,我只需要从 QObject 派生。我编写了一个额外的类来执行此操作,因此我的套接字类不需要将任何数据传递给我的 QML 代码。
【问题讨论】:
你看过 QTcpSocket 吗? 是的。我的出发点是使用 QTcpSocket 的“FortuneCookie”示例。我剥离了几乎所有的代码,直到我有了一个 QObject,它一旦创建,就可以从我的机器上获取 localhostname 和其他基本属性。我试图避免使用 QOBject 派生类,但我不知道如何在我的 c++ 代码之间创建“事件”,而不是在 QML 的信号和插槽之间创建。此外,当类不再是 QObject 时,一些方法停止编译 要么使用 Qt,要么不使用。如果您不想使用 Qt,为什么还要打扰它? QObjects 在某种程度上不好的想法通常是错误的。他们做的正是你需要他们做的。您想编写能够为您提供良好用户体验的异步代码。你需要 QObjects、QEvents 和事件循环,以及它所需要的一切。此外,您对套接字是什么有一个错误的认识。套接字是愚蠢的。您所说的套接字被世界上其他所有人称为网络客户端。如果您不想使用 moc 生成的代码,通常是因为您没有处理您的构建系统。学习它,使用它。 1st:很抱歉我的英语不够流利。我尽力了。第二:“学习”:这正是我想要做的。所以这就是我现在向你提出的问题:QObject 派生类不是用于 QML 文件吗?还是我错了,我误解了它们,即使 UI 不必使用它们,我也应该使用 QObject 派生类?我的目标是拥有一个不知道谁在提供数据的 UI(串行、tcp 客户端或模拟)......这就是我不想使用 QObject 的原因......基于假设它们存在以在 QML UI 中使用。谢谢 QObject 不是一个特定于 GUI 的类,只要你想要一个可以使用信号和槽的对象,它就很有用。 QObject 可以追溯到 Qt 的原始版本,它比 QML 更古老,并且绝不是 QML 特定的。 【参考方案1】:这个问题似乎几乎不是 Qt 问题,而是 C++ 网络编程问题。我收集到您基本上不喜欢明确地使用自定义QObject
派生类,因为您不想在构建过程中运行moc
。虽然有人可能会争论它有什么不好,但由于 moc
在 Qt 本身的构建过程中运行了很多,所以让我们按照目前的要求进行吧。
如果您正在寻找基于非 Qt 的纯 C++ 网络,那么Boost ASIO 是一个非常可靠的解决方案。
如果您希望在没有自定义 QObject
派生类的情况下使用 Qt 网络,那么您可以在单独的线程中运行代码并仅使用阻塞 QTCPSocket
调用。毕竟,它是QIODevice
并提供阻塞接口。
最终,您会得到一些已填充的数据结构,应将其传递给 QML。
从逻辑上讲,您的数据是一个数据模型,视图位于 QML 代码中。您可以为此使用QStandardItemModel
- 也就是说,如果您正在编写真正的模型视图代码,就像数据会随着时间而变化一样。同样,您重用了现有的 QObject
派生类,没有派生您自己的类,也没有编写任何自定义信号或槽。
一个真正穷人的解决方法是获取一个赤裸裸的QObject
,并通过QObject::setProperty
使用动态属性系统将数据放入其中。我不记得如果通过 QML 引擎看到动态属性更改,您需要验证或简单地将此类对象视为常量。
对于一个相当愚蠢的预订,所有这些似乎都是很多变通方法。代码生成器很好,它们可以节省时间。一个复杂的基于 C++ 的产品的构建过程可能会使用几种不同的代码生成器,例如词法分析器/解析器生成器、状态机生成器、远程过程调用生成器、表生成器、测试用例生成器等。随着 C++ 的成熟,找到了一些方法来哄骗编译器替换其中的一些生成器,但这只是将问题推到不同的可执行文件,有时还会将其推过一个非常小的针孔。
【讨论】:
以上是关于Qt 5:如何制作“纯 C++”客户端套接字?的主要内容,如果未能解决你的问题,请参考以下文章