Рисунок Canvas виджет не отображается - PullRequest
0 голосов
/ 08 апреля 2020

Я пытаюсь встроить анимацию matplotlib в мой PyQt5- GUI. Вот мой класс анимации:

class AnimationCanvas(FigureCanvas):
    def __init__(self, parent=None, width=5, height=4, dpi=100):
        self.fig = Figure(figsize=(width, height), dpi=dpi)
        self.fig.set_facecolor('#1a1a1a')

        self.ax = self.fig.add_subplot(111,polar=True)
        self.ax.set_facecolor('#333333')
        self.ax.set_ylim(0,1)
        self.ax.tick_params(axis='x', labelsize=8,colors='#ffffff')
        self.ax.set_yticks([])  # Shows no r values
        self.ax.set_xticks(np.pi/180. * np.linspace(0,  360, 18, endpoint=False)) # A line every 20 degrees
        self.ax.grid(color='#595959', linestyle='-.', linewidth=0.7)
        self.ax.set_title("Position of the speakers", pad = 8,
                          fontdict= dict(
                              color = '#ffffff',
                              fontsize = 15,
                              fontweight = 0.9))
        self.line, = self.ax.plot([], [], marker = 'X', color= '#ffffe6',markersize=15)

        super(AnimationCanvas, self).__init__(self.fig)

Когда я использую следующий код в классе MainWindow (который обрабатывает анимацию), чтобы установить его как центральный виджет, который он показывает, проблем нет. Но я хочу встроить его в мой существующий GUI, чтобы он не был центральным виджетом. Когда я пытаюсь дать ему абсолютную позицию, используя setGeometry() или move(), он просто больше не появляется. Я также попытался использовать QVBoxLayout и добавить self.canvas к макету, который тоже работает, но я не знаю, как правильно его стилизовать, чтобы он не выглядел как большой беспорядок с этими нежелательными пробелами.

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self,xdata, *args, **kwargs,):
        super(MainWindow, self).__init__(*args, **kwargs)
        widget = QWidget()
        vbox = QVBoxLayout(widget)

        self.canvas = AnimationCanvas(self, width=5, height=4, dpi=100)
        self.setCentralWidget(self.canvas)
        vbox.addWidget(self.canvas)

        self.angles = xdata*(3.14/180)
        self.ydata = np.ones(len(self.angles))*0.96
        self.index = 0
        self.line = self.canvas.line

        self.plot_button = QtWidgets.QPushButton(self.canvas)
        self.plot_button.setGeometry(QtCore.QRect(5, 5, 50, 25))
        self.plot_button.setText("plot")
        self.plot_button.setObjectName("plot")
        self.plot_button.clicked.connect(self.plot_animation)
        vbox.addWidget(self.plot_button)
        self.setCentralWidget(widget)

        self.setGeometry(300, 300, 800, 600)

Вопросы:

  1. Почему setGeometry() не работает в этом случае и как это исправить.
  2. Если мне нужно использовать QVBoxLayout, что лучше способ добиться приятного взгляда? addSpacing() и addStretch() везде кажутся мне немного излишним.

Заранее спасибо!

1 Ответ

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

Если вы хотите разместить AnimationCanvas непосредственно в центральном виджете, тогда вызовите setParent в конструкторе.

class AnimationCanvas(FigureCanvas):
    def __init__(self, parent=None, width=5, height=4, dpi=100):
        ...
        super(AnimationCanvas, self).__init__(self.fig)
        self.setParent(parent)

И создайте AnimationCanvas с родительским widget, центральным виджетом QMainWindow. Вызов setGeometry в QPushButton теперь будет работать, он будет помещен в AnimationCanvas в позиции (5, 5) с размером (50, 25).

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self,xdata=None, *args, **kwargs,):
        super(MainWindow, self).__init__(*args, **kwargs)
        widget = QWidget()
        self.setCentralWidget(widget)

        self.canvas = AnimationCanvas(parent=widget, width=5, height=4, dpi=100)

        self.plot_button = QtWidgets.QPushButton(self.canvas)
        self.plot_button.setGeometry(QtCore.QRect(5, 5, 50, 25))

        self.setGeometry(300, 300, 800, 600)

Если вы используете макет, то setGeometry обычно игнорируется, поскольку макет управляет положением и размером всех его виджетов. Однако вы можете добавить в макет только AnimationCanvas, но не QPushButton, что позволит ему оставаться в AnimationCanvas с точной указанной вами геометрией.

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self,xdata=None, *args, **kwargs,):
        super(MainWindow, self).__init__(*args, **kwargs)
        widget = QWidget()
        self.setCentralWidget(widget)
        vbox = QVBoxLayout(widget)

        self.canvas = AnimationCanvas(width=5, height=4, dpi=100)
        vbox.addWidget(self.canvas)

        self.plot_button = QtWidgets.QPushButton(self.canvas)
        self.plot_button.setGeometry(QtCore.QRect(5, 5, 50, 25))

        self.setGeometry(300, 300, 800, 600)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...