У меня есть QMdiSubWindow, который содержит QTabWidget, который содержит QGraphicsView внутри виджета с QHBoxLayout. Подокно находится в области mdi в моем главном окне. Моя цель - иметь фиксированный размер для QGraphicScene, в зависимости от размера бумаги, которую я использую. В этом случае представление должно либо соответствовать тому же размеру, что и сцена, не показывая полос прокрутки, если эта область может вписаться в общую доступную область mdi, также изменяя размер подокна, или должно изменять размер, чтобы заполнить доступную область, изменяя размер подокна, и должны показывать полосы прокрутки для перехода к оставшемуся пространству.
Мой текущий подход вращается вокруг изменения размера сначала подокна mdi, а затем вызова для изменения размера текущего активного виджета в QTabWidget окна. Это все сделано согласно реализации musicamante. Текущий виджет выбирает минимальное значение между родительским (QStackedWidget) родительским (QTabWidget) родительским (QMdiSubWindow) прямоугольником (с изменением размера в первую очередь) и размерами QGraphicsScene, который обновляется, когда я устанавливаю размеры.
-> Установить размеры QGraphicsScene из пользовательского ввода
-> Изменить размер подокна
-> Изменить размер QGraphicsView
Я использую ту же логику c, в моей программе, которая вообще не отображает полосы прокрутки, и представление расширяется, чтобы соответствовать QGraphicsScene, несмотря на то, что вместо этого указывается размер подокна (подокно имеет правильный размер), и в следующем примере, где они показывают при необходимости, но частично обрезается.
from PyQt5 import QtWidgets, QtCore, QtGui
paperSizes = {
"A0": {
"72": [2384, 3370],
"96": [3179, 4494],
"150": [4967, 7022],
"300": [9933, 14043]
},
"A1": {
"72": [1684, 2384],
"96": [2245, 3179],
"150": [3508, 4967],
"300": [7016, 9933]
},
"A2": {
"72": [1191, 1684],
"96": [1587, 2245],
"150": [2480, 3508],
"300": [4960, 7016]
},
"A3": {
"72": [842, 1191],
"96": [1123, 1587],
"150": [1754, 2480],
"300": [3508, 4960]
},
"A4": {
"72": [595, 842],
"96": [794, 1123],
"150": [1240, 1754],
"300": [2480, 3508]
}
}
class canvas(QtWidgets.QWidget):
def __init__(self, parent=None, size= 'A4', ppi= '72'):
super(canvas, self).__init__(parent)
self._ppi = ppi
self._canvasSize = size
self.painter = QtWidgets.QGraphicsScene()
self.painter.setBackgroundBrush(QtGui.QBrush(QtCore.Qt.white))
self.view = QtWidgets.QGraphicsView(self.painter)
# self.view.setMinimumSize(595, 842)
self.layout = QtWidgets.QHBoxLayout(self)
self.layout.addWidget(self.view, stretch = 1, alignment= QtCore.Qt.AlignCenter)
self.setLayout(self.layout)
self.painter.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi])
def resizeView(self, w, h):
self.painter.setSceneRect(0, 0, w, h)
self.adjustView()
def adjustView(self):
self.view.setSceneRect(0, 0, self.painter.sceneRect().width() - self.view.frameWidth() * 2,
self.painter.sceneRect().height())
# give the view some time to adjust itself
QtWidgets.QApplication.processEvents()
width = self.painter.sceneRect().width() + self.view.frameWidth()*2
if self.view.verticalScrollBar().isVisible():
width += self.style().pixelMetric(QtWidgets.QStyle.PM_ScrollBarExtent)
height = self.painter.sceneRect().height() + self.view.frameWidth()*2
if self.view.verticalScrollBar().isVisible():
height += self.style().pixelMetric(QtWidgets.QStyle.PM_ScrollBarExtent)
self.view.setFixedWidth(min(self.parent().rect().width() - self.view.frameWidth()*2, width))
self.view.setFixedHeight(min(self.parent().rect().height()- self.view.frameWidth()*2, height))
def resizeEvent(self, event):
self.adjustView()
def setCanvasSize(self, size):
self.canvasSize = size
def setCanvasPPI(self, ppi):
self.ppi = ppi
@property
def canvasSize(self):
return self._canvasSize
@property
def ppi(self):
return self._ppi
@canvasSize.setter
def canvasSize(self, size):
self._canvasSize = size
if self.painter:
self.resizeView(*paperSizes[self.canvasSize][self.ppi])
@ppi.setter
def ppi(self, ppi):
self._ppi = ppi
if self.painter:
self.resizeView(*paperSizes[self.canvasSize][self.ppi])
@property
def dimensions(self):
#returns the dimension of the current scene
return self.painter.sceneRect().width(), self.painter.sceneRect().height()
class AppDemo(QtWidgets.QMainWindow):
def __init__(self):
super(AppDemo, self).__init__()
self.centralwidget = canvas(self)
width, height = paperSizes['A4']['72']
wsetter = min(1800, width - self.centralwidget.view.frameWidth()*2)
hsetter = min(900, height - self.centralwidget.view.frameWidth()*2)
self.setFixedSize(wsetter, hsetter)
self.centralwidget.resizeView(width, height)
self.setCentralWidget(self.centralwidget)
self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.customContextMenuRequested.connect(self.resizer)
self.show()
def resizer(self, point):
width, height = paperSizes['A0']['300']
wsetter = min(1800, width - self.centralwidget.view.frameWidth()*2)
hsetter = min(900, height - self.centralwidget.view.frameWidth()*2)
self.setFixedSize(wsetter, hsetter)
self.centralWidget().resizeView(width, height)
def main():
import sys
app = QtWidgets.QApplication(sys.argv)
w = AppDemo()
w.setWindowTitle('AppDemo')
w.centralwidget.resizeView(*paperSizes['A0']['72'])
w.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()