基本上,我通过添加带有快捷方式的操作来使用Qt菜单。当菜单出现时,它们看起来很好。
但是我想在操作项文本和它的快捷方式之间添加更多的间距。这个是可能的吗?我找不到任何功能来做这个。
setMinimumWidth可以工作,但我需要在Qt计算的动态宽度的基础上添加。
发布于 2022-01-24 15:04:49
由于QMenu计算其大小的方式很复杂,使用setMinimumWidth()并不是一个可靠的选项:一旦设置了该大小,就无法取消它,而且sizeHint()将始终使用该最小值。
不过,有两种可能的解决办法。
强制菜单布局
这是有点烦琐和肮脏,可能不是所有的情况下都能很好地工作。诀窍是通过添加一个“假”动作来强制重新布局,这个动作将被立即移除。
可以通过将特定函数连接到aboutToShow和aboutToHide信号来做到这一点:
def resizeMenu(menu):
for action in menu.actions():
if action.shortcut():
menu.setMinimumWidth(menu.sizeHint().width() + 50)
menu.removeAction(menu.addAction(''))
break
def restoreMenu(menu):
menu.setMinimumWidth(0)
menu.removeAction(menu.addAction(''))
menu.aboutToShow.connect(lambda: resizeMenu(menu))
menu.aboutToHide.connect(lambda: restoreMenu(menu))您还可以在应用程序上安装一个事件筛选器,以便它可以用于所有菜单:
class MenuWatcher(QtCore.QObject):
def eventFilter(self, obj, event):
if isinstance(obj, QtWidgets.QMenu):
if event.type() == event.Show:
for action in obj.actions():
if action.shortcut():
menu.setMinimumWidth(menu.sizeHint().width() + 50)
menu.removeAction(menu.addAction(''))
break
elif event.type() == event.Hide:
if menu.minimumWidth():
menu.setMinimumWidth(0)
menu.removeAction(menu.addAction(''))
return super().eventFilter(obj, event)
# ...
watcher = MenuWatcher()
app.installEventFilter(watcher)使用QProxyStyle
通过重写一个sizeFromContents()的QProxyStyle,我们可以检查该选项是否是一个CT_MenuItem,如果它在其text中有一个tabWidth (指示至少一个先前的操作有一个快捷方式)或一个\t (意味着它可能有一个快捷方式),那么我们可以在返回默认实现提供的大小之前添加一个特定的宽度:
class ProxyStyle(QtWidgets.QProxyStyle):
def sizeFromContents(self, ct, opt, size, widget=None):
size = super().sizeFromContents(ct, opt, size, widget)
if ct == self.CT_MenuItem and (opt.tabWidth or '\t' in opt.text):
size.setWidth(size.width() + 50)
return size
# ...
app.setStyle(ProxyStyle())https://stackoverflow.com/questions/70834567
复制相似问题