python - 如何将 QTabBar 中的图标居中?
问题描述
我正在尝试更改 QTabWidget 的样式。我想缩小每个选项卡中图标和文本之间的差距,并将两者居中。
这就是我现在所拥有的:
这就是我要的:
我当前的样式表是:
stylesheet = """
QTabBar {
background: %s;
}
QTabBar::tab {
background: %s;
height: 60px;
width: 200px;
font-family: Ubuntu;
font-weight: bold;
font-size: 14px;
color: %s;
}
QTabBar::tab:selected {
background: white;
}
QTabWidget {
background: white;
}
QTabWidget::pane {
background: white;
border: none;
}
""" % (colors.light_gray, # tabbar bg where there are no tabs
colors.light_gray, # tab bg
colors.dark_gray,) # text color
图标在代码中设置:
class ImageProcessingPage(qt.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setStyleSheet(stylesheet)
layout = qt.QHBoxLayout()
self.setLayout(layout)
self.tabWidget = qt.QTabWidget()
layout.addWidget(self.tabWidget)
self.tabWidget.addTab(qt.QLabel("Placeholder for edition"),
icons.getQIcon("pic-edit-gray"),
"Edition")
self.tabWidget.addTab(qt.QLabel("Placeholder for edition"),
icons.getQIcon("roi-gray"),
"ROI")
self.tabWidget.addTab(qt.QLabel("Placeholder for edition"),
"Segmentation")
我尝试在 中添加一些填充QTabBar::tab
,这有助于在图标的左侧添加一些空间,但并没有减少图标和文本之间的空间量。
解决方案
一种可能的解决方案是使用 QProxyStyle 在您想要的位置绘制图标:
from PyQt5 import QtCore, QtGui, QtWidgets
class TabBarStyle(QtWidgets.QProxyStyle):
def drawControl(self, element, option, painter, widget=None):
icon = QtGui.QIcon()
if element == QtWidgets.QStyle.CE_TabBarTabLabel:
icon = QtGui.QIcon(option.icon)
# draw without icon
option.icon = QtGui.QIcon()
super(TabBarStyle, self).drawControl(element, option, painter, widget)
if icon.isNull():
return
verticalTabs = option.shape in (
QtWidgets.QTabBar.RoundedEast,
QtWidgets.QTabBar.RoundedWest,
QtWidgets.QTabBar.TriangularEast,
QtWidgets.QTabBar.TriangularWest,
)
alignment = QtCore.Qt.AlignCenter | QtCore.Qt.TextShowMnemonic
if not self.proxy().styleHint(
QtWidgets.QStyle.SH_UnderlineShortcut, option, widget
):
alignment |= QtCore.Qt.TextHideMnemonic
if verticalTabs:
painter.save()
if option.shape in (
QtWidgets.QTabBar.RoundedEast,
QtWidgets.QTabBar.TriangularEast,
):
newX = tr.width() + tr.x()
newY = tr.y()
newRot = 90
else:
newX = tr.x()
newY = tr.y() + tr.height()
newRot = -90
m = QtCore.QTransform.fromTranslate(newX, newY)
m.rotate(newRot)
p.setTransform(m, True)
tr = self.proxy().subElementRect(
QtWidgets.QStyle.SE_TabBarTabText, option, widget
)
fm = QtGui.QFontMetrics(painter.font())
iconRect = fm.boundingRect(option.text)
iconSize = QtCore.QSize(option.iconSize)
if not iconSize.isValid():
iconExtent = self.proxy().pixelMetric(
QtWidgets.QStyle.PM_SmallIconSize
)
iconSize = QtCore.QSize(iconExtent, iconExtent)
tabIconSize = icon.actualSize(
iconSize,
QtGui.QIcon.Normal
if (option.state & QtWidgets.QStyle.State_Enabled)
else QtGui.QIcon.Disabled,
QtGui.QIcon.On
if (option.state & QtWidgets.QStyle.State_Selected)
else QtGui.QIcon.Off,
)
# High-dpi icons do not need adjustment; make sure tabIconSize is not larger than iconSize
iconSize = QtCore.QSize(
min(tabIconSize.width(), iconSize.width()),
min(tabIconSize.height(), iconSize.height()),
)
offset = 10
iconRect.moveCenter(
tr.center() - QtCore.QPoint(iconSize.width() + offset, 0)
)
tabIcon = icon.pixmap(
widget.window().windowHandle() if widget else None,
option.iconSize,
QtGui.QIcon.Normal
if (option.state & QtWidgets.QStyle.State_Enabled)
else QtGui.QIcon.Disabled,
QtGui.QIcon.On
if (option.state & QtWidgets.QStyle.State_Selected)
else QtGui.QIcon.Off,
)
painter.drawPixmap(iconRect.x(), iconRect.y(), tabIcon)
if verticalTabs:
painter.restore()
然后在 QTabBar 中设置它:
self.tabbar_style = TabBarStyle(self.tabWidget.tabBar().style())
self.tabWidget.tabBar().setStyle(self.tabbar_style)
推荐阅读
- c# - GameProgramming,原型模式:如何将泛型类从 C++ 转换为 C#?
- javascript - 从我的网站播放存储在 Google Cloud Storage 上的大型 .mp4 视频
- raspberry-pi - 树莓派升级失败
- sql - 简单的数据库表设计结构
- javascript - JS 以百分比而不是数字运行数据计数
- javascript - Grid.js 响应式大尺寸表
- javascript - 如何在两个异步操作之间暂停?
- django - 无法访问远程 vps 上的 django 开发服务器
- java - 在输出前留下特定的间隙
- computer-vision - Pytorch 张量维数乘法