Рассмотрим этот маленький фрагмент:
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_())
Если мы запустим его, мы увидим, что числовой блок сеток в порядке, как указано 8x10:
Теперь скажем, что я устанавливаю NUM_BLOCKS_X=3
и NUM_BLOCKS_Y=2
, выход будет следующим:
Это неправильно! Я определенно не хочу этого, я бы хотел, чтобы QGraphicsView был правильно сжат до заданных параметров сетки.
1-й вопрос: Как я могу это достичь?
Еще одна вещь, которую я хотел бы знать: рассмотрим опубликованный фрагмент, в котором сетка 10x8, а затем измените размер QGraphicsWidget на 800x600, выход будет:
Но я хотел бы знать, как я могу рисовать только область QGraphicsScene. Прямо сейчас я использую rect
в drawBackground.
Итак, мой второй вопрос: как рисовать сетку только внутри области QGraphicsScene?
Одна из основных проблем появляется, когда я уменьшаю масштаб, в этом случае я хотел бы видеть только размер QGraphicsScene, потому что я буду добавлять элементы только в этом регионе, позвольте назвать его "доступным" регионом. Как вы можете видеть, прямо сейчас он рисует линии сетки на "непритязательной" области и что действительно запутывает