PyQT自定义小部件固定为正方形。

6
我正在开发一个自定义小部件(继承自QWidget)用作控件。如何将小部件的宽高比固定为正方形,但仍允许布局管理器在竖向和横向空间都足够时调整其大小?
我知道可以设置QPainter的视口,使其只在中心正方形区域内进行绘制,但这仍然允许用户在绘制区域的两侧单击。
2个回答

6
似乎没有一种通用的方法可以在所有情况下保持小部件是正方形。你必须选择以下其中一种:
  • 使其高度取决于其宽度:
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很好。


4
我建议采用BlaXpirit的方法,但这里也有一个我之前使用过的替代方案。
如果你子类化自定义小部件的resizeEvent()函数,你可以调整请求的大小使它变成一个正方形,然后手动设置小部件的尺寸。
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_())

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接