PyQt5 根据输入值自动绘图

PyQt5 Automatic drawing from input value

我最近用 Qpaint 创建了一个小部件,我想将值传递给它,同时强制 Qpaint 小部件从输入值中提取。这个想法是从 Qdialog 定义一个数据值并将其传递给主小部件,然后将该值传递给 Qpaint Widget class。我希望,当用户单击按钮 'Getting values' 时,会出现一个对话框小部件并插入一些 int 值,然后将其传递给主小部件。从那里传递值以更正 class Paint。这将绘制并显示结果。我尝试使用 Qlabel,首先将值分配给 Qlabel or QlineEdit

class Button(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Button, self).__init__(parent)
          ---------

        self.value = QtWidgets.QLabel()

           --------

然后在paint class里面调用那些值或者文本。然后将其分配给 Qpaint event。但是好像不行。'

class Paint(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Paint, self).__init__(parent)

        self.button = Button()
        self.Value = self.button.value

          ---------

        painter.drawRect(100,100,250,250)     <----- instead of value 250 having self.Value

代码Main.py

import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from datainput import *


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

        self.button = Button()
        self.paint = Paint()

        self.lay = QtWidgets.QVBoxLayout()
        self.lay.addWidget(self.paint)
        self.lay.addWidget(self.button)
        self.setLayout(self.lay)

class Paint(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Paint, self).__init__(parent)

        self.button = Button()
        self.Value = self.button.value

        self.setBackgroundRole(QtGui.QPalette.Base)       
        self.setAutoFillBackground(True)

    def paintEvent(self, event):

        self.pen = QtGui.QPen()
        self.brush = QtGui.QBrush( QtCore.Qt.gray, QtCore.Qt.Dense7Pattern)
        painter = QtGui.QPainter(self)
        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        painter.setPen(self.pen)
        painter.setBrush(self.brush)
        painter.drawRect(100,100,250,250)
        painter.setBrush(QtGui.QBrush())

class Button(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Button, self).__init__(parent)

        getbutton = QtWidgets.QPushButton('Getting values')
        Alay = QtWidgets.QVBoxLayout(self)
        Alay.addWidget(getbutton)

        self.value = QtWidgets.QLabel()

        getbutton.clicked.connect(self.getbuttonfunc)


    def getbuttonfunc(self):
        subwindow=Dinput()
        subwindow.setWindowModality(QtCore.Qt.ApplicationModal)
        if subwindow.exec_() == QtWidgets.QDialog.Accepted:
            self._output = subwindow.valueEdit.text()
            return self.value.setText(self._output)


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

输入Qdialog代码,datainput.py

import sys
from PyQt5 import QtCore, QtGui, QtWidgets

class Dinput(QtWidgets.QDialog):
    def __init__(self, parent=None):
        super(Dinput, self).__init__(parent)

        valuelabel = QtWidgets.QLabel('Input: ')
        self.valueEdit = QtWidgets.QLineEdit()

        buttonBox = QtWidgets.QDialogButtonBox()
        buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
        buttonBox.accepted.connect(self.accept) 
        buttonBox.rejected.connect(self.close)

        self.Alay = QtWidgets.QHBoxLayout()
        self.Alay.addWidget(valuelabel)
        self.Alay.addWidget(self.valueEdit)

        self.Blay = QtWidgets.QVBoxLayout()
        self.Blay.addLayout(self.Alay)
        self.Blay.addWidget(buttonBox)
        self.setLayout(self.Blay)

    def closeEvent(self, event):
        super(Dinput, self).closeEvent(event)

    def accept(self):          
        super(Dinput, self).accept()

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

可视化

感谢任何帮助。谢谢

datainput 是无关紧要的,你的任务只是获取一个数字,所以对于 space 问题我不会使用它,而是使用 QInputDialog::getInt()。转到问题上,在这些可以随时获取值的情况下的策略是通过信号通知另一个视图的更改,在接收值的插槽中更新存储值的变量并调用更新以便它在必要时调用 paintEvent,并在 paintEvent 中使用存储值的变量。

import sys
from PyQt5 import QtCore, QtGui, QtWidgets


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

        self.button = Button()
        self.paint = Paint()
        self.button.valueChanged.connect(self.paint.set_size_square)

        self.lay = QtWidgets.QVBoxLayout(self)
        self.lay.addWidget(self.paint)
        self.lay.addWidget(self.button)

class Paint(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Paint, self).__init__(parent)
        self.setBackgroundRole(QtGui.QPalette.Base)     
        self.setAutoFillBackground(True)
        self._size_square = 250

    @QtCore.pyqtSlot(int)
    def set_size_square(self, v):
        self._size_square = v
        self.update()

    def paintEvent(self, event):
        pen = QtGui.QPen()
        brush = QtGui.QBrush( QtCore.Qt.gray, QtCore.Qt.Dense7Pattern)
        painter = QtGui.QPainter(self)
        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        painter.setPen(pen)
        painter.setBrush(brush)
        r = QtCore.QRect(QtCore.QPoint(100, 100), self._size_square*QtCore.QSize(1, 1))
        painter.drawRect(r)

class Button(QtWidgets.QWidget):
    valueChanged = QtCore.pyqtSignal(int)

    def __init__(self, parent=None):
        super(Button, self).__init__(parent)
        getbutton = QtWidgets.QPushButton('Getting values')
        Alay = QtWidgets.QVBoxLayout(self)
        Alay.addWidget(getbutton)
        self.value = QtWidgets.QLabel()
        getbutton.clicked.connect(self.getbuttonfunc)

    @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)

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