pyqt5 - 调整 QWindow 的大小以适应内容
问题描述
我的 PyQt5 应用程序的主窗口在自定义画布小部件上方设置了一个文本标签,该小部件显示图像:
from PyQt5 import QtCore, QtGui, QtWidgets
class Canvas(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.image = None
def paintEvent(self, event):
qp = QtGui.QPainter(self)
if self.image:
qp.drawImage(0, 0, self.image)
class Window(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.canvas = Canvas()
self.label = QtWidgets.QLabel()
self.label.setText('foobar')
self.label.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
QtWidgets.QSizePolicy.Fixed)
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.label)
layout.addWidget(self.canvas)
layout.setSpacing(0)
layout.setContentsMargins(0, 0, 0, 0)
content = QtWidgets.QWidget()
content.setLayout(layout)
self.setCentralWidget(content)
self.load_image('a.jpg')
def load_image(self, filename):
image = QtGui.QImage(filename)
self.canvas.image = image
self.canvas.setFixedSize(image.width(), image.height())
self.update()
def keyPressEvent(self, event):
self.load_image('b.jpg')
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
这看起来像这样,这就是我想要的:
当画布更改为显示较小的图像时,我想相应地缩小窗口以适应。但是,它看起来像这样:
如果我手动拖动来调整它的大小,我可以给窗口的最小大小似乎是适合内容的大小,但为什么它不自动调整大小呢?
解决方案
当设置了固定大小时,它被用作 sizeHint,后者被布局用来设置小部件的大小。所以画布的大小取决于小部件的大小,但你想要相反。您必须将图像大小缩放到窗口大小:
from PyQt5 import QtCore, QtGui, QtWidgets
class Canvas(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setSizePolicy(
QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding
)
self.image = QtGui.QImage()
@property
def image(self):
return self._image
@image.setter
def image(self, image):
self._image = image
self.update()
def paintEvent(self, event):
qp = QtGui.QPainter(self)
if not self.image.isNull():
image = self.image.scaled(
self.size(), QtCore.Qt.IgnoreAspectRatio, QtCore.Qt.SmoothTransformation
)
qp.drawImage(0, 0, image)
class Window(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.canvas = Canvas()
self.label = QtWidgets.QLabel("foobar")
self.label.setSizePolicy(
QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed
)
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.label)
layout.addWidget(self.canvas)
layout.setSpacing(0)
layout.setContentsMargins(0, 0, 0, 0)
content = QtWidgets.QWidget()
content.setLayout(layout)
self.setCentralWidget(content)
self.load_image("a.jpg")
def load_image(self, filename):
image = QtGui.QImage(filename)
self.canvas.image = image
def keyPressEvent(self, event):
self.load_image('b.jpg')
super().keyPressEvent(event)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
推荐阅读
- forms - Flask:如何存储用户的表单输入,以便以后可以在两个请求中检索它
- python - 如何显示烧瓶选择的视频显示
- javascript - 每次刷新页面时,最后提交的表单数据都会不断添加到数组中
- c# - 通过注册表将子项添加到 Windows ContextMenu(无外壳)
- javascript - 带有ajax数据加载的Highcharts Windbarb
- java - 将数组传递给构造函数并出现“无法将 double [] 转换为 int”错误
- python - 如何让硒一个接一个地执行两个不同的按钮
- java - How do you make the application get to read the 1st letter of the 2nd word
- python - 如何从 3d 数组中删除周围的空数据
- docker - 是否有将 ansible-playbook 转换为 Dockerfile 的工具?