Python - вызов функции из другого класса для рисования линии с использованием ошибки PyQt: "sip.wrappertype" - PullRequest
0 голосов
/ 13 апреля 2020

Я пытаюсь создать два класса, используя PyQt для создания gui, например, так:

import sys
from PyQt5.QtGui import QPainter, QPen, QBrush
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtCore import Qt, QRect, QPoint

class line():
    def makeline():
        qp.drawLine(250,250,350,300)

test = line()

class ShapeDrawer(QWidget):
  def __init__(self):
    super().__init__()
    self.setGeometry(50, 50, 500, 500)
    self.show()
  def paintEvent(self, event):
    qp = QPainter()
    qp.begin(self)
    line.makeline()
    qp.end()

if __name__ == '__main__':
  app = QApplication(sys.argv)
  ex = ShapeDrawer()
  sys.exit(app.exec_())

Однако, когда я запускаю этот код, я получаю

Traceback (most recent call last):
  File ".\ShapeDrawer.py", line 25, in paintEvent
    line.makeline()
  File ".\ShapeDrawer.py", line 9, in makeline
    qp.drawLine(250,250,350,300)
NameError: name 'qp' is not defined

И когда Я пытаюсь определить QPainter внутри функции следующим образом:

class line():
    def makeline():
        qp = QPainter()
        qp.begin(ShapeDrawer)
        qp.drawLine(250,250,350,300)

Я получаю

Traceback (most recent call last):
  File ".\ShapeDrawer.py", line 27, in paintEvent
    line.makeline()
  File ".\ShapeDrawer.py", line 10, in makeline
    qp.begin(ShapeDrawer)
TypeError: begin(self, QPaintDevice): argument 1 has unexpected type 'sip.wrappertype'

Я не уверен, как поступить. Любая помощь очень ценится!

edit: Дополнительно я получил совет when you define the draw method, you could add an additional argument which is a QPainter object, and when you call this method in paintEvent, you could pass the qp defined in that method as an input. Однако я не уверен в том, как реализовать это сам, а также был бы признателен за помощь в этом!

1 Ответ

0 голосов
/ 13 апреля 2020

В вашем коде qp не существует в области действия makeline.

Создание нового, такого как вы, не поможет по двум причинам:

  • вы пытаетесь рисовать в классе, но QPainter может быть запущен только на экземпляре ;
  • рисование должно работать на экземпляре QPainter, созданном в paintEvent и на виджет и запуск рисователя на виджете может только произойти в рамках paintEvent;

Просто добавьте художник в качестве параметра к функции makeline, затем вызовите его с аргументом Painter.

class line():
    def makeline(<b>qp</b>):
        qp.drawLine(250,250,350,300)


class ShapeDrawer(QWidget):
    # ...
    def paintEvent(self, event):
      qp = QPainter()
      qp.begin(self)
      line.makeline(<b>qp</b>)
      qp.end()

Обратите внимание, что определение нового класса, который выполняет только то, что вы показываете, почти бесполезно, если только вы не хотите использовать общий объект, который сохраняет «набор» функций, так что вы можете просто поместить функцию в основной отступ.

Кроме того, даже в случае использования этого класса в качестве «коллекции», технически вы выполняете метод stati c (но вы не сделал так); если вы попытаетесь создать экземпляр, вы не сможете его вызвать. Давайте проверим это, используя makeline на экземпляре test:

test = line()
# ...
class ShapeDrawer(QWidget):
    # ...
    def paintEvent(self, event):
      qp = QPainter()
      qp.begin(self)
      <b>test</b>.makeline(qp)

Это приведет к следующей ошибке:

TypeError: makeline() takes exactly 1 argument (2 given)

И это потому, что метод экземпляра всегда имеет Экземпляр класса (обычно называемый «self») в качестве первого аргумента.
Итак, вы либо добавляете декоратор метода stati c:

class line():
    <b>@staticmethod</b>
    def makeline(qp):
        qp.drawLine(250,250,350,300)

, либо добавляете self к нему:

class line():
    def makeline(<b>self</b>, qp):
        qp.drawLine(250,250,350,300)

Также помните, что распространено (и настоятельно рекомендуется) соглашение использовать заглавные имена для классов и строчные буквы только для функций и переменных (подробнее об этом в Руководство по стилю для Python Код , он же PEP 8).

Наконец, обратите внимание, что вы можете создать экземпляр QPainter непосредственно с объектом, на котором рисование будет использоваться в качестве первого аргумента, и если вы используете рисовальщик в paintEvent завершение не требуется, так как это произойдет автоматически, как только будет возвращено paintEvent:

    def paintEvent(self, event):
      qp = QPainter(self)
      line.makeline(qp)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...