I have maybe simple problem with Qt5. I am beginner in Qt5 so it is lack of knowledge. I searched more then 10 answers, code examples and I did not find solution. Problem is with padding added by QGraphicsView (not sure but I set background to red to show it).
I tried many commands to remove padding but without result always red lines/background color is visible. I can not cover full background with content of scene.
Here is image - red is background of `class BoardView(QGraphicsView)'
Here is part of code which cause problem (in my opinion) - full code is bellow - you can run it since reference only to Qt5. Requires Python 3.7 or similar.
I have hypothesis that mayb fitInView() adds some margin but I am not sure or I am not clean all margins (lack of knowledge in Qt5) - so maybe I should use other methods to achieve pure board without padding/margin.
class BoardView(QGraphicsView):
def __init__(self):
super().__init__()
logging.debug('size is %s for %s.', self.size(), self.__class__.__name__)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setViewportMargins(0, 0, 0, 0)
self.setContentsMargins(0, 0, 0, 0)
self.setFrameShape(QFrame.NoFrame)
# self.setFrameStyle(QFrame.NoFrame)
# transparent background
# self.setStyleSheet('QGraphicsView {background: transparent;}')
self.setStyleSheet('QGraphicsView { background: red; }')
logging.debug(self.styleSheet())
scene = BoardScene()
self.setScene(scene)
# no frame
logging.debug('Here is problem with frames!')
logging.debug('rect is %s for %s.', self.rect(), self.__class__.__name__)
logging.debug('sceneRect is %s for %s.', self.sceneRect(), self.__class__.__name__)
logging.debug('frameShape is %s for %s.', self.frameShape(), self.__class__.__name__)
logging.debug('frameStyle is %s for %s.', self.frameStyle(), self.__class__.__name__)
logging.debug('Why children rect is too small?')
logging.debug('How to change children rect?')
logging.debug('childrenRect is %s for %s.', self.childrenRect(), self.__class__.__name__)
logging.debug('contentsRect is %s for %s.', self.contentsRect(), self.__class__.__name__)
logging.debug('frameRect is %s for %s.', self.frameRect(), self.__class__.__name__)
logging.debug('frameSize is %s for %s.', self.frameSize(), self.__class__.__name__)
logging.debug('frameWidth is %s for %s.', self.frameWidth(), self.__class__.__name__)
logging.debug('frameGeometry is %s for %s.', self.frameGeometry(), self.__class__.__name__)
logging.debug('geometry is %s for %s.', self.geometry(), self.__class__.__name__)
def resizeEvent(self, event: QtGui.QResizeEvent) -> None:
super().resizeEvent(event)
self.fitInView(self.scene().board_container, Qt.KeepAspectRatio)
Fully working code (apart problem with padding)
import logging
import sys
import typing
from PyQt5 import QtCore, QtGui
from PyQt5.QtCore import QSize, QPoint, Qt, QRect, QMargins
from PyQt5.QtGui import QFont, QPaintEvent, QPainter, QBrush, QColor, QPen
from PyQt5.QtWidgets import QApplication, QWidget, QGridLayout, QSizePolicy, QVBoxLayout, QHBoxLayout, QGraphicsWidget, \
QGraphicsScene, QGraphicsView, QGraphicsGridLayout, QStyleOptionGraphicsItem, QGraphicsSceneMouseEvent, QFrame
class Application(QApplication):
pass
class SquareWidget(QGraphicsWidget):
def __init__(self, color):
super().__init__()
if color:
self.color = QtCore.Qt.white
else:
self.color = QtCore.Qt.black
# set some size
self.setMinimumSize(2.0, 2.0)
def paint(self, painter: QtGui.QPainter, option: QStyleOptionGraphicsItem, widget: typing.Optional[QWidget] = ...) -> None:
painter.fillRect(option.rect, self.color)
class BoardContainer(QGraphicsWidget):
def __init__(self):
super().__init__()
# require initialization
self.resize(16.0, 16.0)
logging.debug('size is %s for %s.', self.size(), self.__class__.__name__)
logging.debug('geometry is %s for %s.', self.geometry(), self.__class__.__name__)
grid = QGraphicsGridLayout()
logging.debug('spacing %s %s', (grid.verticalSpacing(), grid.horizontalSpacing()),
self.__class__.__name__)
grid.setSpacing(0)
logging.debug('spacing %s %s', (grid.verticalSpacing(), grid.horizontalSpacing()),
self.__class__.__name__)
grid.setContentsMargins(0.0, 0.0, 0.0, 0.0)
self.setLayout(grid)
for row in range(8):
for column in range(8):
square_widget = SquareWidget((row + column) % 2)
grid.addItem(square_widget, row, column)
grid.activate()
logging.debug('size is %s for %s.', self.size(), self.__class__.__name__)
class BoardScene(QGraphicsScene):
def __init__(self):
super().__init__()
self.board_container = board_container = BoardContainer()
self.addItem(board_container)
class BoardView(QGraphicsView):
def __init__(self):
super().__init__()
logging.debug('size is %s for %s.', self.size(), self.__class__.__name__)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setViewportMargins(0, 0, 0, 0)
self.setContentsMargins(0, 0, 0, 0)
self.setFrameShape(QFrame.NoFrame)
# self.setFrameStyle(QFrame.NoFrame)
# transparent background
# self.setStyleSheet('QGraphicsView {background: transparent;}')
self.setStyleSheet('QGraphicsView { background: red; }')
logging.debug(self.styleSheet())
scene = BoardScene()
self.setScene(scene)
# no frame
logging.debug('Here is problem with frames!')
logging.debug('rect is %s for %s.', self.rect(), self.__class__.__name__)
logging.debug('sceneRect is %s for %s.', self.sceneRect(), self.__class__.__name__)
logging.debug('frameShape is %s for %s.', self.frameShape(), self.__class__.__name__)
logging.debug('frameStyle is %s for %s.', self.frameStyle(), self.__class__.__name__)
logging.debug('Why children rect is too small?')
logging.debug('How to change children rect?')
logging.debug('childrenRect is %s for %s.', self.childrenRect(), self.__class__.__name__)
logging.debug('contentsRect is %s for %s.', self.contentsRect(), self.__class__.__name__)
logging.debug('frameRect is %s for %s.', self.frameRect(), self.__class__.__name__)
logging.debug('frameSize is %s for %s.', self.frameSize(), self.__class__.__name__)
logging.debug('frameWidth is %s for %s.', self.frameWidth(), self.__class__.__name__)
logging.debug('frameGeometry is %s for %s.', self.frameGeometry(), self.__class__.__name__)
logging.debug('geometry is %s for %s.', self.geometry(), self.__class__.__name__)
def resizeEvent(self, event: QtGui.QResizeEvent) -> None:
super().resizeEvent(event)
self.fitInView(self.scene().board_container, Qt.KeepAspectRatio)
class BoardWidget(QWidget):
def __init__(self):
super().__init__()
logging.debug('size is %s for %s.', self.size(), self.__class__.__name__)
grid = QGridLayout()
board_view = BoardView()
grid.addWidget(board_view, 0, 0)
self.setLayout(grid)
def main():
# show exceptions
def excepthook(cls, exception, traceback):
sys.__excepthook__(cls, exception, traceback)
sys.excepthook = excepthook
logging.basicConfig(level=logging.DEBUG)
app = Application(sys.argv)
app.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True)
default_font = QFont()
default_font.setPointSize(12)
app.setFont(default_font)
board_widget = BoardWidget()
board_widget.setMinimumSize(640, 640)
board_widget.show()
sys.exit(app.exec())
if __name__ == '__main__':
main()