I'm developing a custom widget (inheriting from QWidget) to use as a control. How can I fix the aspect-ratio of the widget to be square, but still allow it to be resized by the layout manager when both vertical and horizontal space allows?
I know that I can set the viewport of the QPainter so that it only draws in a central square area, but that still allows the user to click either side of the drawn area.
It seems like there is no universal way to keep a widget square under all circumstances. You must choose one:
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())
...
Such a widget will be kept square as long as there is such a possibility.
For other cases you should indeed consider changing the viewport, as you mentioned. Mouse events shouldn't be that much of a problem, just find the center of the widget (divide dimensions by 2), find min(width, height)
and go from there. You should be able to validate the mouse events by coordinate. It is nice to call QMouseEvent.accept
, only if the event passed the validation and you used the event.