>>>Qt6::DBus 是 Qt 6 中用于实现 D-Bus(Desktop Bus)通信的模块。D-Bus 是一种消息总线系统,用于在同一台计算机上的不同进程之间进行通信,非常常用于 Linux 环境中的应用程序之间的交互。
ubuntu22.04
>>>QInputDialog 是 Qt 中用于显示输入对话框的一个类,允许用户通过简单的输入框来输入数据。您可以使用 QInputDialog 来获取字符串、整数、浮点数等类型的输入。
>>> QDBusConnection 是 Qt 中与 D-Bus(Desktop Bus)协议交互的类。D-Bus 是一种用于在同一台计算机上不同进程之间进行通信的系统,广泛用于 Linux 环境。 QDBusConnection 的基本功能 QDBusConnection 提供了对 D-Bus 连接的管理,包括发送信号、调用远程方法、注册对象等功能。它的主要成员包括:
>>>QDBusAbstractAdaptor 是 QtDBus 模块中的一个类,用于创建 D-Bus 适配器。适配器的主要目的是将 C++ 对象的信号和槽映射到 D-Bus 方法和信号,从而使得 C++ 对象可以通过 D-Bus 被外部进程访问。
>>>在 Qt 中,new ChatAdaptor(this) 通常用于创建一个 D-Bus 适配器的实例,以便将当前对象(在上下文中通常是一个聊天窗口对象)与 D-Bus 进行连接。适配器类通常是继承自 QDBusAbstractAdaptor,它简化了方法和信号的暴露过程,使其他通过 D-Bus 的客户端能够访问该对象的功能。
>>>在 C++ 中,using org::example::chat; 是一种命名空间的使用声明。这行代码的目的是在当前作用域中引入 org::example::chat 命名空间,以便可以更方便地访问该命名空间中的类、方法或其他成员,而无需每次都写出完整的命名空间路径。
>>>
# 设置 CMake 最小版本要求cmake_minimum_required(VERSION 3.16)# 声明项目名称和使用的编程语言project(chat LANGUAGES CXX)# 包含当前目录set(CMAKE_INCLUDE_CURRENT_DIR ON)# 如果未定义安装示例目录,则设置默认值if(NOT DEFINED INSTALL_EXAMPLESDIR) set(INSTALL_EXAMPLESDIR "examples")endif()# 设置安装示例目录的路径set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/dbus/chat")# 查找 Qt6 的所需组件find_package(Qt6 REQUIRED COMPONENTS Core DBus Gui Widgets)# 设置 Qt 标准项目qt_standard_project_setup()# 定义一个源文件列表set(chat_SRCS)# 添加 D-Bus 接口文件和生成的源文件qt_add_dbus_interface(chat_SRCS org.example.chat.xml chat_interface)# 添加 D-Bus 适配器qt_add_dbus_adaptor(chat_SRCS org.example.chat.xml qobject.h QObject chat_adaptor)# 创建可执行文件,包含源文件和 UI 文件qt_add_executable(chat chat.cpp ChatMainWindow.h chatmainwindow.ui ${chat_SRCS})# 设置目标属性,确保在 Windows 和 macOS 上以合适的方式构建set_target_properties(chat PROPERTIES WIN32_EXECUTABLE TRUE MACOSX_BUNDLE TRUE)# 指定链接库target_link_libraries(chat PRIVATE Qt6::Core Qt6::DBus Qt6::Gui Qt6::Widgets)# 安装目标设置install(TARGETS chat RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" # 安装运行时文件 BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" # 安装捆绑文件 LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" # 安装库文件)>>>
#ifndef CHATMAINWINDOW_H#define CHATMAINWINDOW_H// 引入 QStringList 类头文件,用于存储消息列表#include <QStringList>// 引入自动生成的用户界面头文件#include "ui_chatmainwindow.h"// 定义 ChatMainWindow 类,继承自 QMainWindow 和 Ui::ChatMainWindowclass ChatMainWindow: public QMainWindow, Ui::ChatMainWindow{ Q_OBJECT // 此宏用于启用 Qt 的信号和槽机制 // 成员变量:存储用户昵称 QString m_nickname; // 成员变量:存储聊天消息的列表 QStringList m_messages;public: // 构造函数,初始化聊天主窗口 ChatMainWindow();private: // 私有方法:用于显示一条消息 void displayMessage(const QString &message);signals: // 信号:发送消息,包含昵称和消息文本 void message(const QString &nickname, const QString &text); // 信号:执行某个动作,包含昵称和消息文本 void action(const QString &nickname, const QString &text);private slots: // 私有槽:用于更改昵称,可以传入初始值参数 bool changeNickname(bool initial = false);};#endif // CHATMAINWINDOW_H>>>
#include <QApplication> // 引入 QApplication 类,用于管理应用程序的控制流和主要设置#include <QInputDialog> // 引入 QInputDialog 类,用于弹出输入对话框#include <QMessageBox> // 引入 QMessageBox 类,用于显示消息框#include "ChatMainWindow.h" // 引入自定义的聊天主窗口类头文件#include "chat_adaptor.h" // 引入 D-Bus 适配器类头文件#include "chat_interface.h" // 引入 D-Bus 接口类头文件// ChatMainWindow 构造函数ChatMainWindow::ChatMainWindow(){ setupUi(this); // 设置用户界面,通过 Qt Designer 生成的代码初始化 UI // 连接信号和槽,当文本框内容变化时,更新发送按钮的可用状态 connect(messageLineEdit, &QLineEdit::textChanged, this, [this](const QString &newText) { sendButton->setEnabled(!newText.isEmpty()); }); // 连接“发送”按钮的点击事件,发送消息,并清空输入框 connect(sendButton, &QPushButton::clicked, this, [this]() { emit message(m_nickname, messageLineEdit->text()); // 发出消息信号 messageLineEdit->clear(); // 清空输入框 }); // 连接“更改昵称”的触发事件,调用 changeNickname 方法 connect(actionChangeNickname, &QAction::triggered, this, &ChatMainWindow::changeNickname); // 连接“关于 Qt”的触发事件,显示有关 Qt 的信息框 connect(actionAboutQt, &QAction::triggered, this, [this]() { QMessageBox::aboutQt(this); }); // 连接应用程序最后一个窗口关闭的信号,发出用户退出聊天的动作信号 connect(qApp, &QApplication::lastWindowClosed, this, [this]() { emit action(m_nickname, tr("退出聊天")); }); // 添加 D-Bus 接口并连接到 D-Bus new ChatAdaptor(this); // 创建 D-Bus 适配器对象 auto connection = QDBusConnection::sessionBus(); // 获取会话总线连接 // "/": 在这里,"/" 是该对象在 D-Bus 上的路径。D-Bus 采用树形结构来组织对象,每个对象都有其唯一的路径。使用根路径 "/" 意味着该对象将注册为系统的顶层对象。 connection.registerObject("/", this); // 注册对象,使其可通过 D-Bus 访问 // using chat = ::OrgExampleChatInterface;: 这行代码通过 using 声明创建了一个别名。 // chat 现在可以作为 ::OrgExampleChatInterface 的别名。这意味着在后续代码中,可以用 org::example::chat 来引用 OrgExampleChatInterface 类, // 而不需要每次都写出完整的命名空间路径。 using org::example::chat; // 使用命名空间 // 创建并初始化 D-Bus 接口对象 // OrgExampleChatInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); auto *iface = new chat({}, {}, connection, this); // 连接 D-Bus 消息信号 connect(iface, &chat::message, this, [this](const QString &nickname, const QString &text) { displayMessage(tr("<%1> %2").arg(nickname, text)); // 显示消息 }); // 连接 D-Bus 动作信号 connect(iface, &chat::action, this, [this](const QString &nickname, const QString &text) { displayMessage(tr("* %1 %2").arg(nickname, text)); // 显示动作 }); // 尝试更改昵称,若失败则退出应用程序 if (!changeNickname(true)) QMetaObject::invokeMethod(qApp, &QApplication::quit, Qt::QueuedConnection); // 退出应用程序}// 显示消息的方法void ChatMainWindow::displayMessage(const QString &message){ m_messages.append(message); // 将新消息添加到消息列表 // 保持消息数量在 100 条以内,超过则删除最旧消息 if (m_messages.count() > 100) m_messages.removeFirst(); // 将消息列表合并为一个字符串,在聊天记录文本框中显示 auto history = m_messages.join(QLatin1String("\n")); chatHistory->setPlainText(history); // 更新聊天记录显示}// 更改昵称的方法bool ChatMainWindow::changeNickname(bool initial){ auto newNickname = QInputDialog::getText(this, tr("设置昵称"), tr("新昵称:")); // 弹出输入对话框 newNickname = newNickname.trimmed(); // 去除首尾空格 if (!newNickname.isEmpty()) { // 如果昵称不为空 auto old = m_nickname; // 保存旧昵称 m_nickname = newNickname; // 更新为新昵称 // 根据是否是初始昵称,发出相应的动作信号 if (initial) emit action(m_nickname, tr("加入聊天")); // 新用户加入聊天 else emit action(old, tr("现在被称为 %1").arg(m_nickname)); // 更新用户昵称 return true; // 返回成功 } return false; // 返回失败}// 主函数int main(int argc, char **argv){ QApplication app(argc, argv); // 创建应用程序对象 // 检查 D-Bus 会话总线连接 if (!QDBusConnection::sessionBus().isConnected()) { qWarning("无法连接到D-Bus会话总线。\n" "请检查您的系统设置,然后重试。\n"); // 输出警告信息 return 1; // 返回错误代码 } ChatMainWindow chat; // 创建聊天主窗口对象 chat.show(); // 显示该窗口 return app.exec(); // 进入应用程序主事件循环}>>>

>>>1,演示

2,运行

【源码】记得转存慢慢看 通过网盘分享的文件:chat 链接: https://pan.baidu.com/s/1pKsDTVsaQFswjy6FQlSrKw?pwd=qt93 提取码: qt93
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。