Как сгенерировать щелчок мышью на QGraphicsWidget в QTest?
Я хочу проверить функциональность нажатия кнопки на моей панели. Проблема в том, что кнопка - это не элементы QPushButtons, а элементы QGraphicWidget.
Как сгенерировать эту кнопку щелчком мыши, чтобы проверить ее поведение?
Кнопки не являются простыми кнопками QPushButton, потому что они имеют особые поведения при наведении мыши, анимированы и т. Д. Эти кнопки добавляются в сцену, затем сцена добавляется в вид, а вид как виджет добавляется в макет. Я вижу, что есть возможность щелкнуть по представлению, используя:
QTest.mouseClick(self.panel_with_buttons.view.viewport(), Qt.LeftButton)
но это не нажимает на кнопку. Я также попытался указать положение кнопки:
rect = self.panel_with_buttons.button2.boundingRect()
QTest.mouseClick(self.panel_with_buttons.view.viewport(), Qt.LeftButton, pos = rect.center())
но это почему-то неподдерживаемый аргумент
Код для класса Button и класса PanelWithButtons (panel_with_buttons.py):
from PySide2 import QtWidgets, QtCore, QtGui
class Button(QtWidgets.QGraphicsWidget):
pressed = QtCore.Signal()
def __init__(self, image_path: str, parent=None):
super().__init__(parent)
self._pixmap = QtGui.QPixmap(image_path)
def paint(self, painter, option, widget=None):
painter.setPen(QtCore.Qt.NoPen)
painter.drawPixmap(0, 0, self._pixmap)
def mousePressEvent(self, event: QtWidgets.QGraphicsSceneMouseEvent):
self.pressed.emit()
class PanelWithButtons(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.button = QtWidgets.QPushButton('button1')
self.button.clicked.connect(self.button_clicked)
pix = 'home.png'
self.button2 = Button(pix)
self.button2.pressed.connect(self.button2_pressed)
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.button)
self.scene = QtWidgets.QGraphicsScene()
self.scene.addItem(self.button2)
self.view = QtWidgets.QGraphicsView(self.scene)
layout.addWidget(self.view)
self.setLayout(layout)
@QtCore.Slot()
def button_clicked(self):
print('button1 clicked')
@QtCore.Slot()
def button2_pressed(self):
print('button2 pressed')
test.py:
from unittest import TestCase
from PySide2 import QtWidgets
from PySide2.QtTest import QTest
from PySide2.QtCore import Qt, QPoint
from test.panel_with_buttons import PanelWithButtons
class TestPanel(TestCase):
def setUp(self) -> None:
app = QtWidgets.QApplication()
self.panel_with_buttons = PanelWithButtons()
def test_go_cargo(self):
QTest.mouseClick(self.panel_with_buttons.button, Qt.LeftButton)
rect = self.panel_with_buttons.button2.boundingRect()
QTest.mouseClick(self.panel_with_buttons.view.viewport(), Qt.LeftButton)
В качестве результата я получаю щелчок мышью по первой кнопке (я вижу "button1 clicked"), но я не знаю, как создать щелчок по второй кнопке.
1 ответ
Файл panel_with_buttons.py содержит следующие ошибки:
Вы должны создать абсолютный путь к ресурсам, в данном случае путь к изображению. Когда вы запускаете файл.py, если передается относительный путь, именно в этом месте запускается скрипт, который может вызвать проблемы, при условии, что изображение находится рядом с panel_with_buttons.py.
Вы должны установить размер кнопки равным размеру изображения, используя метод resize().
Учитывая, что файл должен быть следующим:
import os
from PySide2 import QtWidgets, QtCore, QtGui
current_dir = os.path.dirname(os.path.realpath(__file__))
class Button(QtWidgets.QGraphicsWidget):
pressed = QtCore.Signal()
def __init__(self, image_path: str, parent=None):
super().__init__(parent)
self._pixmap = QtGui.QPixmap(image_path)
self.resize(self._pixmap.size())
def paint(self, painter, option, widget=None):
painter.setPen(QtCore.Qt.NoPen)
painter.drawPixmap(0, 0, self._pixmap)
def mousePressEvent(self, event: QtWidgets.QGraphicsSceneMouseEvent):
self.pressed.emit()
super().mousePressEvent(event)
class PanelWithButtons(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.button = QtWidgets.QPushButton("button1")
self.button.clicked.connect(self.button_clicked)
print(os.getcwd())
pix = os.path.join(current_dir, "home.png")
self.button2 = Button(pix)
self.button2.pressed.connect(self.button2_pressed)
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.button)
self.scene = QtWidgets.QGraphicsScene()
self.scene.addItem(self.button2)
self.view = QtWidgets.QGraphicsView(self.scene)
layout.addWidget(self.view)
self.setLayout(layout)
@QtCore.Slot()
def button_clicked(self):
print("button1 clicked")
@QtCore.Slot()
def button2_pressed(self):
print("button2 pressed")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = PanelWithButtons()
w.show()
sys.exit(app.exec_())
С другой стороны, вы должны получить положение точки, принадлежащей Button, относительно области просмотра, используя методы mapToScene of Button и mapFromScene из QGraphicsView, в этом случае точка будет центром Button.
from unittest import TestCase
from PySide2 import QtCore, QtCore, QtWidgets, QtTest
from test.panel_with_buttons import PanelWithButtons
class TestPanel(TestCase):
def setUp(self) -> None:
app = QtWidgets.QApplication()
self.panel_with_buttons = PanelWithButtons()
self.panel_with_buttons.resize(640, 480)
def test_go_cargo(self):
QtTest.QTest.mouseClick(
self.panel_with_buttons.button, QtCore.Qt.LeftButton
)
it = self.panel_with_buttons.button2
sp = it.mapToScene(it.rect().center())
p = self.panel_with_buttons.view.mapFromScene(sp)
QtTest.QTest.mouseClick(
self.panel_with_buttons.view.viewport(), QtCore.Qt.LeftButton, pos=p
)