You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PyQt5中获取QMenu与QAction之间的像素间距?

获取QAction与所属QMenu的间距值

我希望通过编程方式获取QAction与其所属QMenu之间的像素间距(如图中标记的左侧和顶部间距):

菜单示例

当前代码运行后输出如下:

QMenu '' geometry: (0, 0, 100, 30) self.contentsRect()=PyQt5.QtCore.QRect(0, 0, 100, 30)
-> QMenu '' marginsVals=(0, 0, 0, 0) menuhmargin=0 menuvmargin=0
...
QAction 'Choices:' geometry: (3, 3, 116, 22) self.contentsRect()=PyQt5.QtCore.QRect(0, 0, 123, 50)
-> QAction 'Choices:' marginsVals=None
QMenu 'Choices:' geometry: (0, 0, 100, 30) self.contentsRect()=PyQt5.QtCore.QRect(0, 0, 100, 30)
-> QMenu 'Choices:' marginsVals=(0, 0, 0, 0) menuhmargin=0 menuvmargin=0
...
QAction '(Dummy)' geometry: (3, 25, 116, 22) self.contentsRect()=PyQt5.QtCore.QRect(0, 0, 123, 50)
-> QAction '(Dummy)' marginsVals=None
QMenu '(Dummy)' geometry: (0, 0, 100, 30) self.contentsRect()=PyQt5.QtCore.QRect(0, 0, 100, 30)
-> QMenu '(Dummy)' marginsVals=(0, 0, 0, 0) menuhmargin=0 menuvmargin=0
...

从输出能看到,QAction 'Choices:'的几何位置是(3, 3, 116, 22),对应菜单的contentsRect是(0, 0, 123, 50),推测左右上间距都是3像素,但我想直接通过API读取这些值,而非手动计算。

尝试过PM_MenuHMargin、PM_MenuVMargin以及.contentsMargins(),但这些方法始终返回0,无法得到正确的间距值。

解决方案

你需要使用QStyle.PM_MenuItemHMargin和QStyle.PM_MenuItemVMargin这两个像素度量常量,它们对应QAction在QMenu内的水平和垂直边距。修改HoverableMenu的menu_about_to_show方法,添加这两个值的获取:

def menu_about_to_show(self):
    print(f"QMenu '{self.title()}' geometry: {self.geometry().getRect()} {self.contentsRect()=}")
    margins = self.contentsMargins()
    marginsVals = None
    if margins:
        marginsVals = (margins.left(), margins.top(), margins.right(), margins.bottom())
    opt = QStyleOption()
    opt.initFrom(self)
    # 获取菜单本身的边距(你之前使用的)
    menuhmargin = self.style().pixelMetric(QStyle.PM_MenuHMargin, opt, self)
    menuvmargin = self.style().pixelMetric(QStyle.PM_MenuVMargin, opt, self)
    # 获取菜单项(QAction)的边距
    item_hmargin = self.style().pixelMetric(QStyle.PM_MenuItemHMargin, opt, self)
    item_vmargin = self.style().pixelMetric(QStyle.PM_MenuItemVMargin, opt, self)
    print(f"-> QMenu '{self.title()}' {marginsVals=} {menuhmargin=} {menuvmargin=}")
    print(f"-> 菜单项边距:水平={item_hmargin},垂直={item_vmargin}")

运行修改后的代码,就能直接得到QAction与QMenu之间的间距值,这就是你看到的3像素偏移的来源。

补充说明

  • PM_MenuHMargin/VMargin是控制QMenu整体与外部容器的边距,而PM_MenuItemHMargin/VMargin才是控制QAction在QMenu内部的边距。
  • 这些值由当前使用的Qt样式(比如Windows风格、Fusion风格)决定,不同样式下可能有不同的数值。

内容的提问来源于stack exchange,提问作者sdbbs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 16:22:01