Let's consider this little snippet:
import sys
from PyQt5 import QtWidgets
from PyQt5 import QtCore
from PyQt5 import QtGui
from PyQt5.QtWidgets import QMenu
from PyQt5.QtGui import QKeySequence
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QCursor
def create_action(parent, text, slot=None,
shortcut=None, shortcuts=None, shortcut_context=None,
icon=None, tooltip=None,
checkable=False, checked=False):
action = QtWidgets.QAction(text, parent)
if icon is not None:
action.setIcon(QIcon(':/%s.png' % icon))
if shortcut is not None:
action.setShortcut(shortcut)
if shortcuts is not None:
action.setShortcuts(shortcuts)
if shortcut_context is not None:
action.setShortcutContext(shortcut_context)
if tooltip is not None:
action.setToolTip(tooltip)
action.setStatusTip(tooltip)
if checkable:
action.setCheckable(True)
if checked:
action.setChecked(True)
if slot is not None:
action.triggered.connect(slot)
return action
class Settings():
WIDTH = 20
HEIGHT = 15
NUM_BLOCKS_X = 10
NUM_BLOCKS_Y = 14
class QS(QtWidgets.QGraphicsScene):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
width = Settings.NUM_BLOCKS_X * Settings.WIDTH
height = Settings.NUM_BLOCKS_Y * Settings.HEIGHT
self.setSceneRect(0, 0, width, height)
self.setItemIndexMethod(QtWidgets.QGraphicsScene.NoIndex)
class QV(QtWidgets.QGraphicsView):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.view_menu = QMenu(self)
self.create_actions()
def create_actions(self):
act = create_action(self.view_menu, "Zoom in",
slot=self.on_zoom_in,
shortcut=QKeySequence("+"), shortcut_context=Qt.WidgetShortcut)
self.view_menu.addAction(act)
act = create_action(self.view_menu, "Zoom out",
slot=self.on_zoom_out,
shortcut=QKeySequence("-"), shortcut_context=Qt.WidgetShortcut)
self.view_menu.addAction(act)
self.addActions(self.view_menu.actions())
def on_zoom_in(self):
if not self.scene():
return
self.scale(1.5, 1.5)
def on_zoom_out(self):
if not self.scene():
return
self.scale(1.0 / 1.5, 1.0 / 1.5)
def drawBackground(self, painter, rect):
gr = rect.toRect()
start_x = gr.left() + Settings.WIDTH - (gr.left() % Settings.WIDTH)
start_y = gr.top() + Settings.HEIGHT - (gr.top() % Settings.HEIGHT)
painter.save()
painter.setPen(QtGui.QColor(60, 70, 80).lighter(90))
painter.setOpacity(0.7)
for x in range(start_x, gr.right(), Settings.WIDTH):
painter.drawLine(x, gr.top(), x, gr.bottom())
for y in range(start_y, gr.bottom(), Settings.HEIGHT):
painter.drawLine(gr.left(), y, gr.right(), y)
painter.restore()
super().drawBackground(painter, rect)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
a = QS()
b = QV()
b.setScene(a)
# b.resize(800,600)
b.show()
sys.exit(app.exec_())
If we run it we can see the number block of grids is ok, as specified it's 8x10:
Now, let's say i set NUM_BLOCKS_X=3
and NUM_BLOCKS_Y=2
, the output will be this one:
That's wrong! I definitely don't want that, I'd like the QGraphicsView to be shrinked properly to the grid's settings I've specified.
1st Question: How can i achieve that?
Another thing I'd like to know is, let's consider the posted snippet where the grid is 10x8 and then let's resize the QGraphicsWidget to 800x600, the output will be:
But I'd like to know how i can draw only the QGraphicsScene region. Right now I'm using rect
in drawBackground.
So my 2nd question is: How can I draw the grid only inside QGraphicsScene's region?
One of the main problems appears when I zoom out, in that case I'd like to see only the size of the QGraphicsScene, because I'll be adding items only on that region, let's call it "drawable" region. As you can see, right now it's drawing grid lines on "non-drawable" region and that's really confusing