Масштабирование и панорамирование с помощью жестов Pinch и Swipe в QGraphicsView с помощью PyQt5 на Mac и WindowsPython

Программы на Python
Ответить
Anonymous
 Масштабирование и панорамирование с помощью жестов Pinch и Swipe в QGraphicsView с помощью PyQt5 на Mac и Windows

Сообщение Anonymous »

Мне нужно реализовать масштабирование для QGraphicsView с помощью жеста сведения (двумя пальцами) и панорамирование по сцене с помощью жеста смахивания (также двумя пальцами) в PyQt5.15.7 на Windows и Mac (и оптимально работает и для Linux). Я попытался добиться этого с помощью следующего кода:

Код: Выделить всё

import sys

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *

class View(QGraphicsView):
def __init__(self, parent=None):
super().__init__(parent)

self.zoom_in_factor = 1.25
self.zoom = 10
self.zoom_step = 1
self.zoom_clamp = True
self.zoom_range = [1, 10]
self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)

self.scene = QGraphicsScene()
self.scene.setSceneRect(-5000, -5000, 10000, 10000)
self.scene.addRect(0, 0, 100, 100, QPen(Qt.NoPen), QBrush(Qt.green))

self.setScene(self.scene)

def wheelEvent(self, event):
if event.modifiers() == Qt.ControlModifier:
# Check if mouse wheel up or down
if event.angleDelta().y() > 0:
zoom_factor = self.zoom_in_factor
self.zoom += self.zoom_step
else:
zoom_factor = 1 / self.zoom_in_factor
self.zoom -= self.zoom_step

# Clamping
clamped = False
if self.zoom < self.zoom_range[0]:
self.zoom = self.zoom_range[0]
clamped = True
if self.zoom > self.zoom_range[1]:
self.zoom = self.zoom_range[1]
clamped = True

if not clamped or self.zoom_clamp is False:
self.scale(zoom_factor, zoom_factor)

self.scene.update()

else:
return super().wheelEvent(event)

app = QApplication([sys.argv])

view = View()
view.show()

app.exec()
Этот код работает так, как я хочу, на моем ноутбуке с Windows (Asus ROG Flow X13). Когда я делаю жест смахивания, он вызывает супер-метод и обрабатывает его соответствующим образом, и (я не знаю почему) при щипковом жесте PyQt думает, что я держу управление, и поэтому выполняет часть кода, связанную с масштабированием.
Однако на MacBook (как и следовало ожидать) супер-метод вызывается всегда (кроме случаев, когда я удерживаю нажатой cmd). Поэтому масштабирование здесь не работает с помощью жеста сжатия, но панорамирование работает.
Я тестировал с помощью

Код: Выделить всё

QGestures
, чтобы реализовать масштабирование с помощью этого кода:

Код: Выделить всё

import sys

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *

class View(QGraphicsView):
def __init__(self, parent=None):
super().__init__(parent)

self.grabGesture(Qt.PinchGesture)
self.grabGesture(Qt.SwipeGesture)

self.scene = QGraphicsScene()
self.scene.setSceneRect(-5000, -5000, 10000, 10000)
self.scene.addRect(0, 0, 100, 100, QPen(Qt.NoPen), QBrush(Qt.green))

self.setScene(self.scene)

def event(self, event):
if event.type() == QEvent.Gesture:
return self.gestureEvent(QGestureEvent(event))
return super().event(event)

def gestureEvent(self, event):
print("Gesture event")

if event.gesture(Qt.PinchGesture):
print("Pinch gesture")
self.pinchTriggered(QPinchGesture(event.gesture(Qt.PinchGesture)))
if event.gesture(Qt.SwipeGesture):
print("Swipe gesture")
self.swipeTriggered(QSwipeGesture(event.gesture(Qt.SwipeGesture)))

print()
return True

def pinchTriggered(self, gesture):
changeFlags = gesture.changeFlags()

if changeFlags & QPinchGesture.ScaleFactorChanged:
print("Scale factor changed", gesture.scaleFactor(), gesture.totalScaleFactor(), gesture.lastScaleFactor())

def swipeTriggered(self, gesture):
pass

app = QApplication([sys.argv])

view = View()
view.show()

app.exec()
При тестировании этого кода на разных платформах произошли следующие вещи:
В Windows жесты не регистрируются.
На Mac был зарегистрирован только жест сжатия. Поэтому я попытался реализовать масштабирование на Mac с помощью жеста щипка, используя подход, аналогичный официальной документации PyQt. Похоже, это не сработало, поскольку ScaleFactor, totalScaleFactor и totalScaleFactor QPinchGesture не изменяются при выполнении жеста сжатия. Они всегда остаются на уровне 1.0.
Можно ли исправить эту ошибку или есть ли какой-либо другой подход, кроме QGesture, для решения этой проблемы?

Подробнее здесь: https://stackoverflow.com/questions/749 ... th-pyqt5-o
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»