我正在开发一个自定义窗口小部件(继承自QWidget)以用作控件。如何将窗口小部件的宽高比修正为方形,但是当垂直和水平空间都允许时,仍允许布局管理器调整其大小?
我知道我可以设置QPainter的视口,使其仅绘制在中心的方形区域,但仍允许用户单击绘制区域的任意一侧。
答案 0 :(得分:4)
显然,我old approach有很多瑕疵,其中的一些内容毫无意义:
QSizePolicy.setHeightForWidth
和QSizePolicy.setWidthForHeight
是独占的...... setWidthForHeight
在大多数情况下都不起作用...... QWidget.widthForHeight
这样的东西,所以定义它并不会真正覆盖任何东西。似乎没有通用的方法可以在所有情况下保持小部件正方形。 你必须选择一个:
class MyWidget(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
policy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
policy.setHeightForWidth(True)
self.setSizePolicy(policy)
...
def heightForWidth(self, width):
return width
...
class MyWidget(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
...
def resizeEvent(self, e):
setMinimumWidth(height())
...
只要存在这种可能性,这样的小部件就会保持正方形。
对于其他情况,您应该考虑更改视口,如您所述。鼠标事件应该不是那么大的问题,只需找到窗口小部件的中心(将维度除以2),找到min(width, height)
并从那里开始。您应该能够通过坐标验证鼠标事件。只有在事件通过验证并且您使用了事件时,才能调用QMouseEvent.accept
。
答案 1 :(得分:2)
我会选择BlaXpirit的方法,但这是我以前用过的替代方法。
如果您对自定义窗口小部件resiseEvent()
进行子类化,则可以调整请求的大小以使其成为正方形,然后手动设置窗口小部件的大小。
import sys
from PyQt4 import QtCore, QtGui
class CustomWidget(QtGui.QFrame):
def __init__(self, parent=None):
QtGui.QFrame.__init__(self, parent)
# Give the frame a border so that we can see it.
self.setFrameStyle(1)
layout = QtGui.QVBoxLayout()
self.label = QtGui.QLabel('Test')
layout.addWidget(self.label)
self.setLayout(layout)
def resizeEvent(self, event):
# Create a square base size of 10x10 and scale it to the new size
# maintaining aspect ratio.
new_size = QtCore.QSize(10, 10)
new_size.scale(event.size(), QtCore.Qt.KeepAspectRatio)
self.resize(new_size)
class MainWidget(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
layout = QtGui.QVBoxLayout()
self.custom_widget = CustomWidget()
layout.addWidget(self.custom_widget)
self.setLayout(layout)
app = QtGui.QApplication(sys.argv)
window = MainWidget()
window.show()
sys.exit(app.exec_())