Как сгенерировать щелчок мышью на 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
        )
Другие вопросы по тегам