Отображение другого класса Paint в одном Qwidget

На следующем изображении показано приложение с одним виджетом ввода и одним виджетом рисования.

и в коде есть два класса рисования. Идея состоит в том, что при нажатии кнопки вызывается первый класс рисования и отображается в Paintwidget, а когда вызывается другой класс рисования, он хочет отобразить в том же Paintwidget. На самом деле не перекрывают друг друга, а не отображаются в одном виджете.

Как это могло быть сделано?

При нажатии круглой кнопки эта строка кода меняется с

    self.mainSplitter.addWidget(self.paint1)

к

    self.mainSplitter.addWidget(self.paint2)

И наоборот

Визуализация:

Отображение другого класса Paint в одном Qwidget

Код:

from PyQt5 import QtCore, QtGui, QtWidgets

class Foo(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(Foo, self).__init__(parent)
        self.setGeometry(QtCore.QRect(200, 100, 800, 650))

        self.button = Button()
        self.paint1 = Paintwidget1()
        self.paint2 = Paintwidget2()
        self.button.valuesChanged.connect(self.paint1.set_size_squares)
        self.button.valueChanged.connect(self.paint2.set_size_round)

        self.mainSplitter = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
        self.mainSplitter.addWidget(self.button)
        self.mainSplitter.addWidget(self.paint1)

        self.setCentralWidget(self.mainSplitter)

class Paintwidget1(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.sizeHint()        
        self.setBackgroundRole(QtGui.QPalette.Base)     
        self.setAutoFillBackground(True)

        self._size = QtCore.QSizeF()
        self._path = QtGui.QPainterPath()
        self._rect = QtCore.QRectF()
        self._type = QtGui.QRegion.Rectangle
        self._factor = 1.0

        self._pos = QtCore.QPointF()
        self._initial_flag = False
        fnt = self.font() 
        fnt.setPointSize(20) 
        self.setFont(fnt) 

    def showEvent(self, event):
        if not self._initial_flag:
            self._pos = self.rect().center()
            self._initial_flag = True

    @QtCore.pyqtSlot(int, int)
    def set_size_squares(self, w, h):
        self._path = QtGui.QPainterPath()
        self._size = QtCore.QSizeF(w, h)
        self._type = QtGui.QRegion.Rectangle
        self.updatePath()

    def paintEvent(self, event):
        pen = QtGui.QPen()
        brush = QtGui.QBrush(QtCore.Qt.black)
        painter = QtGui.QPainter(self)
        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        painter.setPen(pen)
        painter.setBrush(brush)

        painter.translate(self.rect().center())
        painter.scale(self._factor, self._factor)
        painter.translate(-self.rect().center())

        painter.translate(self._pos)
        painter.drawPath(self._path)
        if self._type == QtGui.QRegion.Rectangle:
            painter.fillRect(self._rect, QtGui.QBrush(QtCore.Qt.gray, QtCore.Qt.Dense7Pattern))
            painter.setBrush(QtGui.QBrush(QtCore.Qt.NoBrush))
            painter.drawRect(self._rect)


    def mousePressEvent(self, event):
        QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
        self._initial_pos = event.pos()
        super().mousePressEvent(event)

    def mouseMoveEvent(self, event):
        delta = event.pos() - self._initial_pos
        self._path.translate(delta)
        self._rect.translate(delta)
        self.update()
        self._initial_pos = event.pos()
        super().mouseMoveEvent(event)

    def mouseReleaseEvent(self, event):
        QtWidgets.QApplication.restoreOverrideCursor()
        super().mouseReleaseEvent(event)

    def updatePath(self):
        r = QtCore.QRectF(QtCore.QPointF(), self._size)
        r.moveCenter(QtCore.QPointF())
        self._rect = QtCore.QRectF(r)
        self.update()

    def wheelEvent(self, event):
        self._factor *= 1.01**(event.angleDelta().y()/15.0)
        self.update()
        super().wheelEvent(event)

class Paintwidget2(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.sizeHint()        
        self.setBackgroundRole(QtGui.QPalette.Base)     
        self.setAutoFillBackground(True)

        self._size = QtCore.QSizeF()
        self._path = QtGui.QPainterPath()
        self._rect = QtCore.QRectF()
        self._type = QtGui.QRegion.Rectangle
        self._factor = 1.0

        self._pos = QtCore.QPointF()
        self._initial_flag = False
        fnt = self.font() 
        fnt.setPointSize(20) 
        self.setFont(fnt) 

    def showEvent(self, event):
        if not self._initial_flag:
            self._pos = self.rect().center()
            self._initial_flag = True

    @QtCore.pyqtSlot(int)
    def set_size_round(self, v):
        self._path = QtGui.QPainterPath()
        self._size = QtCore.QSizeF(v, 0.8*v)
        self._type = QtGui.QRegion.Ellipse
        self.updatePath()

    def paintEvent(self, event):
        pen = QtGui.QPen()
        brush = QtGui.QBrush(QtCore.Qt.black)
        painter = QtGui.QPainter(self)
        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        painter.setPen(pen)
        painter.setBrush(brush)

        painter.translate(self.rect().center())
        painter.scale(self._factor, self._factor)
        painter.translate(-self.rect().center())

        painter.translate(self._pos)
        painter.drawPath(self._path)
        if self._type == QtGui.QRegion.Ellipse:
            painter.setBrush(QtGui.QBrush(QtCore.Qt.gray, QtCore.Qt.Dense7Pattern))
            painter.drawEllipse(self._rect)

    def mousePressEvent(self, event):
        QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
        self._initial_pos = event.pos()
        super().mousePressEvent(event)

    def mouseMoveEvent(self, event):
        delta = event.pos() - self._initial_pos
        self._path.translate(delta)
        self._rect.translate(delta)
        self.update()
        self._initial_pos = event.pos()
        super().mouseMoveEvent(event)

    def mouseReleaseEvent(self, event):
        QtWidgets.QApplication.restoreOverrideCursor()
        super().mouseReleaseEvent(event)

    def updatePath(self):
        r = QtCore.QRectF(QtCore.QPointF(), self._size)
        r.moveCenter(QtCore.QPointF())
        self._rect = QtCore.QRectF(r)
        self.update()

    def wheelEvent(self, event):
        self._factor *= 1.01**(event.angleDelta().y()/15.0)
        self.update()
        super().wheelEvent(event)

class Button(QtWidgets.QWidget):
    valueChanged = QtCore.pyqtSignal(int)
    valuesChanged = QtCore.pyqtSignal(int,int)
    def __init__(self, parent=None):
        super(Button, self).__init__(parent)
        roundbutton = QtWidgets.QPushButton('Round')
        squarebutton = QtWidgets.QPushButton('Square')
        Alay = QtWidgets.QVBoxLayout(self)
        Alay.addWidget(roundbutton)
        Alay.addWidget(squarebutton)
        self.value = QtWidgets.QLabel()
        roundbutton.clicked.connect(self.getbuttonfunc)
        squarebutton.clicked.connect(self.sqaurebuttonfunc)

    @QtCore.pyqtSlot()
    def getbuttonfunc(self):
        number, ok = QtWidgets.QInputDialog.getInt(self, self.tr("Set Number"),
                                         self.tr("Input:"), 1, 1)
        if ok:
            self.valueChanged.emit(number)

    @QtCore.pyqtSlot()
    def sqaurebuttonfunc(self):
        number, ok = QtWidgets.QInputDialog.getInt(self, self.tr("Set Number"),
                                         self.tr("Input:"), 1, 1)
        if ok:
            self.valuesChanged.emit(number, number)


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = Foo()
    w.show()
    sys.exit(app.exec_())

Ваше объяснение непонятно, на какой кнопке вы говорите? Что вы имеете в виду под вызов первого класса рисования? а что такое показать это в Paintwidget?, лучше объясните себя и приведите реальный пример.

eyllanesc 17.12.2018 09:59

Ладно, обновлю и приведу реальный пример :)

Pavel.D 17.12.2018 10:00

Смотрите мое обновление.!

Pavel.D 17.12.2018 12:17

смотри мой ответ ..

eyllanesc 17.12.2018 12:27
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
4
103
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы должны использовать QStackedWidget для обмена виджетами, также установите sizeHint() для Paintwidget1 и Paintwidget2:

class Foo(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(Foo, self).__init__(parent)
        self.setGeometry(QtCore.QRect(200, 100, 800, 650))
        self.button = Button()
        self.paint1 = Paintwidget1()
        self.paint2 = Paintwidget2()
        self.button.valuesChanged.connect(self.on_paint1)
        self.button.valueChanged.connect(self.on_paint2)
        self.mainSplitter = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
        self._stacked_widget = QtWidgets.QStackedWidget()
        self.mainSplitter.addWidget(self.button)
        self.mainSplitter.addWidget(self._stacked_widget)
        self.setCentralWidget(self.mainSplitter)
        self._stacked_widget.addWidget(self.paint1)
        self._stacked_widget.addWidget(self.paint2)

    @QtCore.pyqtSlot(int, int)
    def on_paint1(self, w, h):
        self._stacked_widget.setCurrentIndex(0)
        self.paint1.set_size_squares(w, h)

    @QtCore.pyqtSlot(int)
    def on_paint2(self, v):
        self._stacked_widget.setCurrentIndex(1)
        self.paint2.set_size_round(v)

class Paintwidget1(QtWidgets.QWidget):
    # ...
    def sizeHint(self):
        return QtCore.QSize(640, 480)

class Paintwidget2(QtWidgets.QWidget):
    # ...
    def sizeHint(self):
        return QtCore.QSize(640, 480)

Спасибо, именно то, что я хочу!

Pavel.D 17.12.2018 12:43

Я не хочу вносить какие-либо изменения, прежде чем спрошу ?. Я хочу добавить еще один def on_paint3():, но он работает не так, как ожидалось ...

Pavel.D 17.12.2018 14:14

Другие вопросы по теме