获取实际的 Qt window 标题
Get the actual Qt window title
我需要获得Qt顶层window(或MDI子window)的visible标题,因为我想列出window 不同位置的标题就像它们对用户可见一样。
考虑一个支持多个顶级编辑器 windows(或具有类似用途的 MDI 区域)的程序,该程序应列出那些 windows 的标题,例如菜单或内部“window 经理".
如果我想列出那些 windows 并且还支持 windowModified
属性 的 [*]
占位符,他们的 windowTitle()
将 return 这个烦人的占位符,不管他们的状态如何。
不幸的是,windowTitle
功能有点抽象,原因如下:
- 由于
windowModified
功能,如果已设置,它总是 return 占位符;
[*]
占位符可以“转义”多次,甚至 次出现,以便在 window 中实际显示 [*]
标题;
- 如果“实际”
windowTitle
属性 是一个空字符串(默认值),它会退回到 windowFilePath
属性,这不仅 always 有 [*]
占位符,但在 属性 包含 [*]
占位符的罕见情况下也可能表现得很奇怪;虽然我意识到这是一种非常奇怪的情况(并且在某种程度上是不负责任的,假设系统实际上支持它),但我仍然想要一种可靠的方法来获得当前生成的 window 标题,即使在那些罕见的(虽然“错误”) ) 情况;
考虑到上述情况,有没有办法获得 Qt 为 window 设置的 真实 标题?
OS 将 最终 显示在顶级 window 的标题栏中的标题没有绝对和确定的方法。
如 windowTitle
documentation, some systems might support displaying the applicationDisplayName
中所述。一些高度可定制的 (Linux) OS 可能会显示所提供标题的更改版本。几乎没有办法获得“最终”显示的标题,除非您想深入研究与 Window 管理器交互的特定 OS 模块(而且这可能还不够,因为在 *nix 系统上可以进行高水平的定制。
考虑到与 OP 相关的是“内部”window 标题(Qt 最终“中继”到系统的内容),解决方案是实现 Qt 实际上在内部使用 qt_setWindowTitle_helperHelper()
.
请注意,Qt 实现并不完美。当使用占位符字符串的特定组合时,会出现一些奇怪的情况。例如:
- 使用
[*] [*] [*]
作为 window 标题会导致“[*]
”显示为未修改的 window,否则显示“* [*] *
”;
- 和
[*] [*][*] [*]
,未修改的window标题是“ [*] [*]
”(注意前导space),另一个是“* [*]* [*]
”。 =47=]
虽然,如上所述,Qt 实现远非完美,但我们感兴趣的是 实际 window 标题转发给 OS,所以我们必须坚持,因为视觉结果是重要的方面,无论它是否“正确”。
最后,请记住,如果 Qt 开发人员决定更改此行为(我相信他们应该更改),此实现将来可能会失效。
以下代码是一个简单的函数,它将 return 实际 window 标题转发给给定小部件的 OS,可用于必须显示 visible 标题的任何情况:
def realWindowTitle(widget):
title = widget.windowTitle()
placeHolder = '[*]'
if not placeHolder in title:
return title
phSize = len(placeHolder)
style = widget.style()
if (widget.isWindowModified()
and style.styleHint(
style.SH_TitleBar_ModifyNotification, None, widget)
# for PyQt6 or full Enum support use
# style.StyleHint.SH_TitleBar_ModifyNotification
):
replaceHolder = '*'
else:
replaceHolder = ''
index = title.find(placeHolder)
while index != -1:
index += phSize
count = 1
while title.find(placeHolder, index) == index:
count += 1
index += phSize
if count % 2: # odd number of [*] -> replace last one
lastIndex = title.rfind(placeHolder, 0, index)
title = (title[:lastIndex]
+ replaceHolder
+ title[lastIndex + phSize:])
index = title.find(placeHolder, index)
# return "escaped" sequences of the remaining double placeholders
return title.replace('[*][*]', placeHolder)
我需要获得Qt顶层window(或MDI子window)的visible标题,因为我想列出window 不同位置的标题就像它们对用户可见一样。
考虑一个支持多个顶级编辑器 windows(或具有类似用途的 MDI 区域)的程序,该程序应列出那些 windows 的标题,例如菜单或内部“window 经理".
如果我想列出那些 windows 并且还支持 windowModified
属性 的 [*]
占位符,他们的 windowTitle()
将 return 这个烦人的占位符,不管他们的状态如何。
不幸的是,windowTitle
功能有点抽象,原因如下:
- 由于
windowModified
功能,如果已设置,它总是 return 占位符; [*]
占位符可以“转义”多次,甚至 次出现,以便在 window 中实际显示[*]
标题;- 如果“实际”
windowTitle
属性 是一个空字符串(默认值),它会退回到windowFilePath
属性,这不仅 always 有[*]
占位符,但在 属性 包含[*]
占位符的罕见情况下也可能表现得很奇怪;虽然我意识到这是一种非常奇怪的情况(并且在某种程度上是不负责任的,假设系统实际上支持它),但我仍然想要一种可靠的方法来获得当前生成的 window 标题,即使在那些罕见的(虽然“错误”) ) 情况;
考虑到上述情况,有没有办法获得 Qt 为 window 设置的 真实 标题?
OS 将 最终 显示在顶级 window 的标题栏中的标题没有绝对和确定的方法。
如 windowTitle
documentation, some systems might support displaying the applicationDisplayName
中所述。一些高度可定制的 (Linux) OS 可能会显示所提供标题的更改版本。几乎没有办法获得“最终”显示的标题,除非您想深入研究与 Window 管理器交互的特定 OS 模块(而且这可能还不够,因为在 *nix 系统上可以进行高水平的定制。
考虑到与 OP 相关的是“内部”window 标题(Qt 最终“中继”到系统的内容),解决方案是实现 Qt 实际上在内部使用 qt_setWindowTitle_helperHelper()
.
请注意,Qt 实现并不完美。当使用占位符字符串的特定组合时,会出现一些奇怪的情况。例如:
- 使用
[*] [*] [*]
作为 window 标题会导致“[*]
”显示为未修改的 window,否则显示“* [*] *
”; - 和
[*] [*][*] [*]
,未修改的window标题是“[*] [*]
”(注意前导space),另一个是“* [*]* [*]
”。 =47=]
虽然,如上所述,Qt 实现远非完美,但我们感兴趣的是 实际 window 标题转发给 OS,所以我们必须坚持,因为视觉结果是重要的方面,无论它是否“正确”。
最后,请记住,如果 Qt 开发人员决定更改此行为(我相信他们应该更改),此实现将来可能会失效。
以下代码是一个简单的函数,它将 return 实际 window 标题转发给给定小部件的 OS,可用于必须显示 visible 标题的任何情况:
def realWindowTitle(widget):
title = widget.windowTitle()
placeHolder = '[*]'
if not placeHolder in title:
return title
phSize = len(placeHolder)
style = widget.style()
if (widget.isWindowModified()
and style.styleHint(
style.SH_TitleBar_ModifyNotification, None, widget)
# for PyQt6 or full Enum support use
# style.StyleHint.SH_TitleBar_ModifyNotification
):
replaceHolder = '*'
else:
replaceHolder = ''
index = title.find(placeHolder)
while index != -1:
index += phSize
count = 1
while title.find(placeHolder, index) == index:
count += 1
index += phSize
if count % 2: # odd number of [*] -> replace last one
lastIndex = title.rfind(placeHolder, 0, index)
title = (title[:lastIndex]
+ replaceHolder
+ title[lastIndex + phSize:])
index = title.find(placeHolder, index)
# return "escaped" sequences of the remaining double placeholders
return title.replace('[*][*]', placeHolder)