как перейти с pyqt4 на pyqt5 в python - PullRequest
2 голосов
/ 19 марта 2020

Я хочу обновить или преобразовать этот код из pyqt4 в pyqt5, так как этот код несовместим с последним pyqt5.

Так что кто-то может сказать мне, какие основные изменения я могу внести в этот код, чтобы запустить его в pyqt5 .

import sys
from PyQt4.QtCore import Qt
from PyQt4.QtCore import QRectF
from PyQt4.QtWidgets import QApplication
from PyQt4.QtGui import QColor
from PyQt4.QtGui import QFont
from PyQt4.QtGui import QPainter
from PyQt4.QtGui import QPixmap
from PyQt4.QtGui import QTextOption
from PyQt4.QtGui import QToolTip
from PyQt4.QtGui import QWidget

это все импортированные библиотеки для этого кода

class AreaSelector(QWidget):

    def __init__(self, parent=None):

        QWidget.__init__(self, None, Qt.FramelessWindowHint)
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.setWindowState(Qt.WindowFullScreen)
        self.setAutoFillBackground(False)

        self.parent = parent
        self.start_x = 0
        self.start_y = 0
        self.end_x = 0
        self.end_y = 0
        self.current_x = 0
        self.current_y = 0

    def showEvent(self, event):

        self.bg = QPixmap.grabWindow(QApplication.desktop().winId())
        self.screen_geometry = QApplication.desktop().screenGeometry(self)

    def mousePressEvent(self, event):

        self.start_x = event.globalX()
        self.start_y = event.globalY()

    def mouseReleaseEvent(self, event):

        self.end_x = event.globalX()
        self.end_y = event.globalY()

пожалуйста, посмотрите полный код здесь полный код

1 Ответ

1 голос
/ 19 марта 2020

Перевод кода PyQt4 в PyQt5 не является тривиальной задачей:

  • PyQt4 и PyQt5 являются оболочками Qt4 и Qt5, соответственно, поэтому на оба они влияют изменения этого перехода, и один из переходы заключаются в том, что подмодуль Qt Gui в Qt4 был разделен на подмодули Qt Gui и QtWidgets в Qt5.
  • Некоторые классы и методы устарели, поэтому вам придется найти эквивалент если он существует.

В этом случае происходят обе вещи, решение для первого случая простое: вы должны заглянуть в документацию Qt и проверить, к какому подмодулю он относится, например QToolTip, вверху есть таблица:

enter image description here

И часть QT += widgets, которая указывает, что она принадлежит наблюдается субмодуль QtWidgets.

Но второй случай несколько сложнее, так как он включает поиск эквивалента, который может или не может быть в одном классе, в этом случае это происходит с QPixmap.grabWindow() метод, который не рекомендуется ( см. здесь для получения дополнительной информации). После выполнения поиска вы можете заменить этот код на QApplication.primaryScreen().grabWindow(0).

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

import sys
from PyQt5.QtCore import QRectF, Qt
from PyQt5.QtGui import QColor, QFont, QPainter, QPixmap, QTextOption, QScreen
from PyQt5.QtWidgets import QApplication, QToolTip, QWidget


class AreaSelector(QWidget):
    def __init__(self, parent=None):

        QWidget.__init__(self, None, Qt.FramelessWindowHint)
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.setWindowState(Qt.WindowFullScreen)
        self.setAutoFillBackground(False)

        self.parent = parent
        self.start_x = 0
        self.start_y = 0
        self.end_x = 0
        self.end_y = 0
        self.current_x = 0
        self.current_y = 0

    def showEvent(self, event):
        self.bg = QApplication.primaryScreen().grabWindow(0)
        self.screen_geometry = QApplication.primaryScreen().geometry()

    def mousePressEvent(self, event):

        self.start_x = event.globalX()
        self.start_y = event.globalY()

    def mouseReleaseEvent(self, event):

        self.end_x = event.globalX()
        self.end_y = event.globalY()

    def mouseMoveEvent(self, event):

        self.current_x = event.globalX()
        self.current_y = event.globalY()
        self.repaint()

        text = "Start: %sx%s \nEnd: %sx%s" % (
            self.start_x,
            self.start_y,
            self.current_x,
            self.current_y,
        )
        QToolTip.showText(event.pos(), text)

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Return:
            self._acceptSelection()
        elif event.key() == Qt.Key_Escape:
            self.close()

    def _acceptSelection(self):

        if self.parent is not None:
            self.parent.areaSelectEvent(
                self.start_x, self.start_y, self.end_x, self.end_y
            )
        self.close()

    def paintEvent(self, event):

        painter = QPainter()
        painter.begin(self)

        painter.fillRect(self.screen_geometry, QColor(10, 10, 10, 125))

        self._paint_selection(painter)
        self._paint_usage_text(painter)
        painter.end()

    def _paint_usage_text(self, painter):

        font = QFont("Helvetica [Cronyx]", 26, QFont.Bold)
        painter.setFont(font)
        painter.setPen(QColor(255, 255, 255, 255))

        screen_width = self.screen_geometry.width()
        text_width = 800
        text_start_x = screen_width / 2 - text_width / 2

        screen_height = self.screen_geometry.height()
        text_height = 200
        text_start_y = screen_height / 2 - text_height / 2

        textoption = QTextOption(Qt.AlignCenter)
        textbox = QRectF(text_start_x, text_start_y, text_width, text_height)
        painter.drawText(
            textbox,
            "Click & Drag to select an area\n" "ENTER to confirm or ESC to cancel",
            textoption,
        )
        painter.drawRoundedRect(textbox, 20, 20)

    def _paint_selection(self, painter):
        """Draws the current user selection"""
        rectangle = QRectF()

        if self.start_x > self.current_x:
            rectangle.setLeft(self.current_x)
            rectangle.setRight(self.start_x)

        else:
            rectangle.setLeft(self.start_x)
            rectangle.setRight(self.current_x)

        if self.start_y > self.current_y:
            rectangle.setTop(self.current_y)
            rectangle.setBottom(self.start_y)

        else:
            rectangle.setTop(self.start_y)
            rectangle.setBottom(self.current_y)

        painter.drawPixmap(rectangle, self.bg, rectangle)
        painter.drawRect(rectangle)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    main = AreaSelector()
    main.show()
    sys.exit(app.exec_())
...