是否可以设置
raise_()
'd 小部件相对于父框架右边缘的位置?move()
'd 按钮相同的行为,但相对于右边框(默认情况下,小部件与左边框相关,并在调整窗口大小时随之移动)。
这是基本示例。
import sys
from PySide6.QtWidgets import QApplication, QWidget, QCheckBox, QVBoxLayout
from PySide6.QtCore import QMargins
from PySide6.QtCharts import QChart, QChartView, QLineSeries
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setMinimumSize(600, 400)
self.resize(600, 400)
self.setWindowTitle('QRadioButton in QChartView')
self.setContentsMargins(0, 0, 0, 0)
chart_view = QChartView(self)
chart = QChart()
series = QLineSeries()
chart.legend().setVisible(False)
series.append(0, 6)
series.append(2, 4)
series.append(3, 8)
series.append(7, 4)
series.append(10, 5)
chart.addSeries(series)
chart.createDefaultAxes()
chart_view.setChart(chart)
chart_view.setContentsMargins(0, 0, 0, 0)
chart.setMargins(QMargins(10, 10, 20, 10))
chart.layout().setContentsMargins(0, 0, 0, 0)
# Left button behaviour (aligns left top)
radio_button_left = QCheckBox('', self)
radio_button_left.setMinimumSize(13, 13)
radio_button_left.setMaximumSize(13, 13)
radio_button_left.move(33, 23)
# Right button behaviour (aligns left top, but I want to make it align right top)
radio_button_right = QCheckBox('', self)
radio_button_right.setMinimumSize(13, 13)
radio_button_right.setMaximumSize(13, 13)
radio_button_right.move(self.width()-33, 23)
layout = QVBoxLayout()
layout.addWidget(chart_view)
self.setLayout(layout)
chart_view.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())
我想这样做的原因是因为我在图表的右边框上有太多的空白空间(X轴上的数字可以超出图表的边界并移动图表。我不想裁剪他们。)。
只要我需要右上角的按钮,我决定将按钮放置在 QChartView 的顶部,以有效地利用这个空白空间。
那么,我该如何解决这个问题呢?
重要:我真的不想编写与窗口宽度相关的位置重新计算函数,因为这会定价过高。
几何图形总是根据其原点来考虑位置,在 UI 开发中,原点通常是上下文(父级、屏幕等)的左上角。如果您设置固定位置,则小部件将始终保持在其位置,除非另有说明。
写一个“位置重新计算”确实没什么大不了的,避免它只是懒惰。此外,这正是布局管理器所做的,对于这样一个简单的情况,只需覆盖
resizeEvent()
并执行与 __init__
中相同的操作即可:
def resizeEvent(self, event):
super().resizeEvent(event)
radio_button_right.move(self.width() - 33, 23)
不过,您也可以通过适当的布局管理来做到这一点:一种可能性是使用 QGridLayout 作为主布局:这种布局的一个特殊功能是小部件(和子布局)可以添加到已经被其他布局占用的网格单元中项目。
技巧是将图表添加到网格布局的第一个单元格,并将 QHBoxLayout 添加到 same 单元格,并指定垂直(顶部)对齐方式;然后按钮将被添加到水平布局(中间有一个拉伸项目),并且该布局的适当内容边距将用于设置它们与边框的距离。
请注意,您应该避免使用任意值为小部件设置固定几何形状:您为按钮使用的 13x13 尺寸是错误的,因为它仅基于假设的尺寸,而不是考虑当前的样式。在我的计算机中,我只能看到其中的一小部分,因为我使用的默认样式具有更大的复选框指示符。
此类小部件的正确最小尺寸应使用其
minimumSizeHint()
;然后,如果您想避免单选按钮和复选框的指示器与其文本之间使用常见的间距(即使未设置文本,该间距也始终存在),您可以使用样式表指定 0 间距。
radio_button_left = QCheckBox(styleSheet='spacing: 0px')
radio_button_right = QCheckBox(styleSheet='spacing: 0px')
size = radio_button_left.minimumSizeHint()
radio_button_left.setFixedSize(size)
radio_button_right.setFixedSize(size)
layout = QGridLayout(self)
layout.addWidget(chart_view)
overlay = QHBoxLayout()
layout.addLayout(overlay, 0, 0, alignment=Qt.AlignTop)
overlay.setContentsMargins(33, 23, 33, 0)
overlay.addWidget(radio_button_left)
overlay.addStretch()
overlay.addWidget(radio_button_right)
不相关的注释:1. 虽然概念相似,但单选按钮和复选框在目的和行为上有重要差异,它们的显示反映了这一点(意味着用户期望根据他们所看到的内容实现特定行为):始终选择它们正确的理由,不要混淆他们的名字; 2. 如果要添加到布局中,则创建指定父级的小部件是没有意义的; 3. 调用
show()
这样的小部件也是毫无意义的:记住只在有意识的情况下调用可见性函数。