水平居中单选按钮标签
Horizontally center radio button label
我正在使用单选按钮创建垂直制表符效果。我完成了所有工作,但我仍然坚持做一些我认为很容易的事情。
在这部分代码中,我遍历选项卡名称列表并为每个选项卡生成单选按钮:
def _init_vertical_tabs(self, layout, row):
"""Initialize vertical tabs"""
tabs_widget = QtWidgets.QWidget()
tabs_widget.setObjectName("tabs")
vertical_tabs_layout = QtWidgets.QVBoxLayout()
vertical_tabs_layout.setSpacing(0)
vertical_tabs_layout.setContentsMargins(0, 0, 0, 0)
vertical_tabs_layout.setAlignment(QtCore.Qt.AlignCenter)
tabs_widget.setLayout(vertical_tabs_layout)
layout.addWidget(tabs_widget, row, 0, len(self.tabs), 1)
tabs_widget.setMinimumHeight(self.parent_height)
tabs_widget.setMinimumWidth(self.parent_width*0.15)
tabs_widget.setMaximumHeight(self.parent_height)
tabs_widget.setMaximumWidth(self.parent_width*0.15)
tab_to_widget = dict()
for tab in self.tabs:
tab_button = self._create_tab(tab, vertical_tabs_layout, self.parent_width*0.15, self.parent_height/len(self.tabs),)
tab_to_widget[tab] = tab_button
def _create_tab(self, tab, layout, width, height):
"""Basic method to create a fake tab"""
button = QtWidgets.QRadioButton(tab)
button.setContentsMargins(0, 0, 0, 0)
l = lambda tab_name = tab: self.toggle_visibility_tabs(tab_name)
button.clicked.connect(l)
button.setMinimumHeight(height)
button.setMinimumWidth(width)
button.setMaximumHeight(height)
button.setMaximumWidth(width)
layout.addWidget(button)
然后我应用了一些 css:
QWidget#tabs{
color: #ffffff;
background-color: #005073;
border: 0px solid #e54d42;
text-align: center;
}
QWidget#tabs QRadioButton{
color: #ffffff;
font-weight: 400;
font-size: 20pt;
border-radius: 0px;
background-color: #003850; /*QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:0 #003850, stop:0.5 #005073, stop:1 #003850);*/
margin: 0px;
font-family: Arial, Helvetica, sans-serif;
text-align: center;
}
QWidget#tabs QRadioButton#Validator{
border-bottom-left-radius: 60px;
border-left: none;
}
QWidget#tabs QRadioButton::indicator{
width: 0px;
height: 0px;
border-radius: 0px;
border: 1px solid #e54d42;
border-top: none;
border-right: none;
border-left: none;
font-family: Arial, Helvetica, sans-serif;
text-align: center;
}
QWidget#tabs QRadioButton:hover, QWidget#tabs QRadioButton:selected, QWidget#tabs QRadioButton:checked{
border-left: 30px solid #e54d42;
color: #e54d42;
}
结果是:
我想将文字放在中间,我尝试使用尺寸政策,结果是这样的:
但这不是我想要的,首先,单选按钮标签仍然是左对齐的,而且由于单选按钮更短,所选按钮的红色边框显然不再位于左侧。有人可以告诉我在 css 或 python 代码中是否有实现此目的的简单方法?我也尝试了 text-align
,但也没有用。
谢谢!
为此单独使用样式表几乎是不可能的。我建议您混合使用样式表 和 自定义绘画。
首先,编辑样式表,确保将单选按钮的所有颜色设置为transparent
。
然后,创建一个 QRadioButton 的子class,它都通过调用基础 class 实现来绘制按钮 和 绘制带有指定文本的文本颜色和字体。
class CustomRadio(QtWidgets.QRadioButton):
def paintEvent(self, event):
# draw the widget as paintEvent normally does
super().paintEvent(event)
# create a new painter on the widget
qp = QtGui.QPainter(self)
# create a styleoption and init it with the button
opt = QtWidgets.QStyleOptionButton()
self.initStyleOption(opt)
# now we can know if the widget is hovered and/or checked
if opt.state & (QtWidgets.QStyle.State_MouseOver | QtWidgets.QStyle.State_On):
# if it is, set the color accordingly
qp.setPen(QtGui.QColor('#e54d42'))
else:
qp.setPen(QtCore.Qt.white)
# finally, draw the text
qp.drawText(self.rect(),
QtCore.Qt.AlignCenter | QtCore.Qt.TextShowMnemonic, self.text())
如果您使用的是 Designer,则需要升级旋转框:
- select 所有单选按钮,右键单击它们中的任何一个,然后从上下文菜单中 select
Promote to...
;
- 确保 "Base class name" 组合框设置为 "QRadioButton";
- 在"Promoted class name"中,写上"CustomRadio"(上面子class的名字);
- 在 "Header file" 字段中写入您保存子 class 的文件的名称,不带扩展名(例如,如果您使用
main.py
,写入 "main");请记住,该路径是相对于 ui 文件(或 py 文件,如果您使用的是 pyuic)的路径,因此如果 ui/py 在您的主文件夹中程序,subclass 文件在 "subclasses" 目录中并命名为 "myradios.py",你必须在那里写 "subclasses.myradios";
- 单击 "Add" 创建新的推广 class,然后 "Promote" 实际推广 selected 收音机;
- 如果您之前没有 select 所有收音机,现在您可以使用上下文菜单的
Promote to
子菜单中的新 "Custom Radio" 项来推广它们;
保存ui文件,如果使用pyuic生成新的python文件,大功告成。
我正在使用单选按钮创建垂直制表符效果。我完成了所有工作,但我仍然坚持做一些我认为很容易的事情。
在这部分代码中,我遍历选项卡名称列表并为每个选项卡生成单选按钮:
def _init_vertical_tabs(self, layout, row):
"""Initialize vertical tabs"""
tabs_widget = QtWidgets.QWidget()
tabs_widget.setObjectName("tabs")
vertical_tabs_layout = QtWidgets.QVBoxLayout()
vertical_tabs_layout.setSpacing(0)
vertical_tabs_layout.setContentsMargins(0, 0, 0, 0)
vertical_tabs_layout.setAlignment(QtCore.Qt.AlignCenter)
tabs_widget.setLayout(vertical_tabs_layout)
layout.addWidget(tabs_widget, row, 0, len(self.tabs), 1)
tabs_widget.setMinimumHeight(self.parent_height)
tabs_widget.setMinimumWidth(self.parent_width*0.15)
tabs_widget.setMaximumHeight(self.parent_height)
tabs_widget.setMaximumWidth(self.parent_width*0.15)
tab_to_widget = dict()
for tab in self.tabs:
tab_button = self._create_tab(tab, vertical_tabs_layout, self.parent_width*0.15, self.parent_height/len(self.tabs),)
tab_to_widget[tab] = tab_button
def _create_tab(self, tab, layout, width, height):
"""Basic method to create a fake tab"""
button = QtWidgets.QRadioButton(tab)
button.setContentsMargins(0, 0, 0, 0)
l = lambda tab_name = tab: self.toggle_visibility_tabs(tab_name)
button.clicked.connect(l)
button.setMinimumHeight(height)
button.setMinimumWidth(width)
button.setMaximumHeight(height)
button.setMaximumWidth(width)
layout.addWidget(button)
然后我应用了一些 css:
QWidget#tabs{
color: #ffffff;
background-color: #005073;
border: 0px solid #e54d42;
text-align: center;
}
QWidget#tabs QRadioButton{
color: #ffffff;
font-weight: 400;
font-size: 20pt;
border-radius: 0px;
background-color: #003850; /*QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:0 #003850, stop:0.5 #005073, stop:1 #003850);*/
margin: 0px;
font-family: Arial, Helvetica, sans-serif;
text-align: center;
}
QWidget#tabs QRadioButton#Validator{
border-bottom-left-radius: 60px;
border-left: none;
}
QWidget#tabs QRadioButton::indicator{
width: 0px;
height: 0px;
border-radius: 0px;
border: 1px solid #e54d42;
border-top: none;
border-right: none;
border-left: none;
font-family: Arial, Helvetica, sans-serif;
text-align: center;
}
QWidget#tabs QRadioButton:hover, QWidget#tabs QRadioButton:selected, QWidget#tabs QRadioButton:checked{
border-left: 30px solid #e54d42;
color: #e54d42;
}
结果是:
我想将文字放在中间,我尝试使用尺寸政策,结果是这样的:
但这不是我想要的,首先,单选按钮标签仍然是左对齐的,而且由于单选按钮更短,所选按钮的红色边框显然不再位于左侧。有人可以告诉我在 css 或 python 代码中是否有实现此目的的简单方法?我也尝试了 text-align
,但也没有用。
谢谢!
为此单独使用样式表几乎是不可能的。我建议您混合使用样式表 和 自定义绘画。
首先,编辑样式表,确保将单选按钮的所有颜色设置为transparent
。
然后,创建一个 QRadioButton 的子class,它都通过调用基础 class 实现来绘制按钮 和 绘制带有指定文本的文本颜色和字体。
class CustomRadio(QtWidgets.QRadioButton):
def paintEvent(self, event):
# draw the widget as paintEvent normally does
super().paintEvent(event)
# create a new painter on the widget
qp = QtGui.QPainter(self)
# create a styleoption and init it with the button
opt = QtWidgets.QStyleOptionButton()
self.initStyleOption(opt)
# now we can know if the widget is hovered and/or checked
if opt.state & (QtWidgets.QStyle.State_MouseOver | QtWidgets.QStyle.State_On):
# if it is, set the color accordingly
qp.setPen(QtGui.QColor('#e54d42'))
else:
qp.setPen(QtCore.Qt.white)
# finally, draw the text
qp.drawText(self.rect(),
QtCore.Qt.AlignCenter | QtCore.Qt.TextShowMnemonic, self.text())
如果您使用的是 Designer,则需要升级旋转框:
- select 所有单选按钮,右键单击它们中的任何一个,然后从上下文菜单中 select
Promote to...
; - 确保 "Base class name" 组合框设置为 "QRadioButton";
- 在"Promoted class name"中,写上"CustomRadio"(上面子class的名字);
- 在 "Header file" 字段中写入您保存子 class 的文件的名称,不带扩展名(例如,如果您使用
main.py
,写入 "main");请记住,该路径是相对于 ui 文件(或 py 文件,如果您使用的是 pyuic)的路径,因此如果 ui/py 在您的主文件夹中程序,subclass 文件在 "subclasses" 目录中并命名为 "myradios.py",你必须在那里写 "subclasses.myradios"; - 单击 "Add" 创建新的推广 class,然后 "Promote" 实际推广 selected 收音机;
- 如果您之前没有 select 所有收音机,现在您可以使用上下文菜单的
Promote to
子菜单中的新 "Custom Radio" 项来推广它们;
保存ui文件,如果使用pyuic生成新的python文件,大功告成。