「Qt」- 杂记

认识

The toolkit was called Qt because the letter Q looked appealing in Haavard’s Emacs typeface, and “t” was inspired by Xt, the X toolkit.

组成

QApplication, QGuiApplication and QCoreApplication

differences between QApplication, QGuiAppication, QCoreApplication classes

本文简单整理 QApplication, QGuiAppication, QCoreApplication 这三个对象之间的区别。

QCoreApplication | 基类。在命令行应用程序中,应该使用它。

QGuiApplication | 基类 + GUI 功能。在 QML 应用程序中,应该使用它。「QML」是一种用户界面标记语言,是一种指令使的语言,与 CSS 有些相似。

QApplication | 基类 + GUI + 对 Widget 支持。在 QtWidgets 应用程序中,应该使用它。

Event loop | 字面上翻译就是「事件循环」,详细的解释需要阅读文档和一些 Qt 相关的书籍。但简而说:事件循环是一个无限循环,它在应用程序的后台运行,处理从操作系统传入的事件(鼠标移动,点击,绘制事件,硬件事件等)以及内部通信(信号和插槽)。调用app.exec()时,事件循环开始,这也是“在执行app.exec()后,后续代码不会再继续执行”的原因。

性质

应用调试

Debugging Techniques | Qt 6.7

环境变量:
QT_DEBUG_PLUGINS=1 | … make Qt print out diagnostic information about the each (C++) plugin it tries to load.
QML_IMPORT_TRACE=1 | … make QML print out diagnostic information from the import loading mechanism.

提供输入法支持

https://doc.qt.io/qt-6/qinputmethod.html

Fcitx 与 Qt 的协作方式主要有两种,代表了演进的历史:

传统方式:XIM (X Input Method)

工作原理:这是 X Window 系统最古老的输入法协议。Qt 程序通过 Xlib 与 X 服务器通信。当启用输入法时,程序会创建一个名为 XIC 的区域,所有按键事件会先通过 X 服务器发送给 Fcitx,Fcitx 处理完毕后再将结果文本发送回程序的 XIC 区域。

缺点:
  • 延迟高:需要经过 X 服务器中转,路径长。
  • 不稳定:容易因为程序或输入法的崩溃而导致另一方出现问题(焦点丢失、卡死等)。
  • 功能有限:难以实现复杂的预编辑文本显示(如带下划线的拼音)和候选词窗口精确定位。

现状:这是早期的 Qt4 及更老程序的主要方式,现在已不是首选,但作为后备方案存在。

现代方式:IBus 兼容接口 或 Fcitx 自有 Qt 模块

这是当前最主要、最推荐的方式。Fcitx 实现了一个与 IBus 输入法框架兼容的接口。而 Qt 从 4.4 版本开始,原生内置了对 IBus 协议的支持(通过 QtIMModule)。

工作原理:这是 客户端-服务器 (Client-Server) 模型 的 直接通信。

步骤 1:建立连接 (Qt 程序启动时)

当一个 Qt 程序(如 Kate, VLC, 甚至 Chrome/Linux 版)启动时,如果它检测到系统环境变量(如 GTK_IM_MODULE=fcitx 和 QT_IM_MODULE=fcitx),它会加载 Qt 内置的 IBus 输入法客户端模块。

这个 Qt 模块会通过 D-Bus(Linux 桌面最重要的进程间通信 IPC 机制)去寻找并连接到已经运行的 Fcitx 守护进程(fcitx5)。

连接成功后,Qt 程序就成为了 Fcitx 的一个“客户端”。它们之间建立了一条直接的 D-Bus 通信通道。

步骤 2:处理输入 (用户开始打字)

焦点进入:当你点击一个 Qt 程序的输入框时,该程序会通过 D-Bus 向 Fcitx 发送一个焦点进入事件,告诉 Fcitx:“嗨,我现在准备接收输入了”。

按键拦截:

你按下键盘,比如字母 a。

按键事件首先被 Qt 应用程序的窗口系统捕获。

Qt 的输入法模块会拦截这个事件,判断“我现在连接着 Fcitx,这个键应该先交给输入法处理”。

Qt 程序通过 D-Bus 将按键事件 a 发送给 Fcitx 服务端。

步骤 3:输入法引擎处理

Fcitx 收到 a 这个按键事件。

Fcitx 根据当前激活的输入法引擎(如拼音)进行处理。

引擎将 a 添加到自己的内部组合串中,并开始转换:

它查询词库,生成候选列表(如 “啊”、“阿”、“吖”…)。

它生成“预编辑文本”,也就是带下划线的 a。

步骤 4:渲染与显示 (双向通信)

这是最关键的一步,展示了它们如何协同更新界面:

Fcitx → Qt (发送预编辑文本):

Fcitx 通过 D-Bus 向 Qt 程序发送一条消息,内容包含:“请在你的光标位置显示预编辑文本 a”,并附带样式信息(如下划线)。

Qt 程序的责任:

Qt 程序收到指令后,并不立即将 a 永久插入文档。而是在光标处临时、高亮地显示这个 a(通常带下划线或阴影)。这就是你看到的灰色拼音。

Fcitx → Qt (发送候选词列表):

Fcitx 同时将候选词列表(“啊”、“阿”、“吖”…)也发送给 Qt 程序。

Qt 程序的责任:

Qt 程序会创建一个候选词窗口(通常位于光标下方),并显示这些词语。这个窗口是由 Qt 程序自己绘制的,但内容和位置由 Fcitx 控制。

步骤 5:确认与提交

你继续输入,或者按空格键选择第一个候选词。

当 Fcitx 引擎决定提交最终结果时(比如你选择了“啊”),它会:

清空自己的内部组合串。

通过 D-Bus 向 Qt 程序发送一条“提交”消息,内容是最终的汉字“啊”。

Qt 程序收到“提交”消息后:

清除之前临时显示的预编辑文本(下划线的拼音)。

将最终的汉字“啊” 作为一个普通的文本字符,永久地插入到输入框的光标位置。

构建

Qt Creator, Qt Designer, Qt Quick Designer

-「Wikipedia/Qt Creator#Editors
-「Qt Designer vs Qt Quick Designer vs Qt Creator?

Qt Creator 是 Qt 的 IDE,它大大简化了 Qt 的开发;

Qt Designer 是一个图形工具,可以让您构建 QWidget GUI;

Qt Quick Designer 与 Qt Designer 类似,但用于构建基于 QML 的 GUI;

Qt Quick Designer 与 Qt Designer 两者都内置于 Qt Creator;

安装 Qt Creator 工具

#!/bin/sh

################################################################################
# Kali GNU/Linux Rolling
#
# # Ubuntu 14.04 QtCreator Qt5 examples missing
# # https://askubuntu.com/questions/450983/ubuntu-14-04-qtcreator-qt5-examples-missing
# # Getting Started With Qt and Qt Creator on Linux
# # https://www.ics.com/blog/getting-started-qt-and-qt-creator-linux
#
################################################################################
# 安装基础
apt-get install qtcreator

# 安装示例(不同的示例可能在不同的包中),该命令并未安装说有的示例包;
apt-get install qtbase5-examples qtbase5-doc-html qtwebengine5-examples

应用

使 TabWidget 按钮居中

-「QTabwidget’s tab text alignment not working

# 创建按钮
QLabel * button = new QLabel("text");
button->setAlignment(Qt::AlignLeft);

# 将原有的文本置空
ui->tabWidget->tabBar()->setTabText(index, "");

# 将按钮添加到组件上
ui->tabWidget->tabBar()->setTabButton(index, QTabBar::LeftSide, button);

参考

DeepSeek / Fcitx 输入法 与 其他 Qt 程序是如何协同工作的?