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

时间:2012-06-13 04:15:11

标签: python qt widget pyqt pyqt4

我正在开发一个自定义窗口小部件(继承自QWidget)以用作控件。如何将窗口小部件的宽高比修正为方形,但是当垂直和水平空间都允许时,仍允许布局管理器调整其大小?

我知道我可以设置QPainter的视口,使其仅绘制在中心的方形区域,但仍允许用户单击绘制区域的任意一侧。

2 个答案:

答案 0 :(得分:4)

显然,我old approach有很多瑕疵,其中的一些内容毫无意义:

  • QSizePolicy.setHeightForWidthQSizePolicy.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_())