Почему мои данные не отображаются в Canvas в qt4 с python? Я приложил код - PullRequest
0 голосов
/ 10 апреля 2019

Я настраиваю систему управления с прямой графикой DAQ. У меня есть графический интерфейс, который я написал в pyqt4 с 3 кнопками управления, кнопкой выхода и встроенным графиком matplotlib, который я должен был отображать в реальном времени. Данные печатаются на экране терминала, но никогда не отображаются в графическом интерфейсе. Если я закрою пользовательский интерфейс, появится фигура, но ничего не отображается. Функция сюжета также работает в одиночку, просто нужно использовать plt.ion () .draw ()

Я пробовал использовать разные методы, используя pyqt4 и pyqt5. Я думаю, что это путается на том, что отображать Я настроил главное окно для графического интерфейса, и три кнопки работают в одиночку, но не могут взаимодействовать с ними, если включен сюжет

'''
import sys
from PyQt4 import QtGui, QtCore
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as 
FigureCanvas
import time
import numpy as np
from matplotlib.figure import Figure
import explorerhat
'''
class Window(QtGui.QMainWindow):

    def __init__(self):
        super(Window, self).__init__()
        self.setGeometry(400, 400, 700, 500)
        self.setWindowTitle("PiDAQ")

        ## Define Canvas size and location to be embedded into Main Window
        canvas = Canvas(self, width = 4, height = 4)
        canvas.move(200,20)

        self.show()

 ''' END CLASS'''

class Canvas(FigureCanvas):
    def __init__(self, parent = None, width =5 , height = 5, dpi =100):
        fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = fig.add_subplot

        FigureCanvas.__init__(self, fig)
        self.setParent(parent)

        self.plot()
'''
     def plot(self):

        t0 = time.time()

        i=0
        print('t0=', t0)
        ax = self.figure.add_subplot(111)

        N=50

        x = np.arange(N)*20/N
        y1 = np.arange(N)*5/N
        y2 = np.arange(N)*5/N

        line1, = self.ax.plot(x, y1, 'b-')
        line2, = self.ax.plot(x, y2, 'r-')

        while True:
            i =+ 1
            V2 = self.explorerhat.analog.one.read()
            V3 = self.explorerhat.analog.two.read()
            V4 = self.explorerhat.analog.three.read()
            V5 = self.explorerhat.analog.four.read()
            if V2 > 2.5:
                output = ' POW!!! '
            else:
                output = ''
            t = time.time()-t0

            if i % N == 0:

                print(i, t, V2, V3, V4, V5, output)
            x[i%N-1] = t

            if i % N == 0:
                y1[-1] = V2
                y2[-1] = V3
                line1.set_xdata(x-x[0])
                line1.set_ydata(y1)
                line2.set_xdata(x-x[0])
                line2.set_ydata(y2)
                self.draw()
            else:
                y1[i%N-1] = V2
                y2[i%N-1] = V3
            time.sleep(0.00001)
 '''

1 Ответ

0 голосов
/ 12 апреля 2019

Проблема в том, что функция plot никогда не возвращается и поэтому блокирует цикл обработки событий.

Qt работает, когда бесконечный цикл (цикл обработки событий) прослушивает события, а затем отправляет их четным обработчикам.Событиями могут быть нажатия клавиш, щелчки мыши, запросы на перерисовку, уведомления TCP и т. Д. Обработчики событий - это функции, которые что-то делают с этим событием.Они должны возвращаться быстро, потому что, пока они работают, Qt не может обрабатывать другие события (у Qt есть только один поток, который может обрабатывать события GUI).Обработчики событий, которые не возвращают, заставляют приложение зависать.См. this artcicle для более подробного объяснения.

Все ваши методы вызываются прямо или косвенно из-за какого-либо события (например, обработчик события нажатия кнопки генерирует сигнал clicked, который связан сваш слот).Поэтому все методы, которые вы пишете, должны возвращаться быстро (например, с точностью до секунды).Ваша функция plot не возвращается, и поэтому программа зависает.

Решение состоит в том, чтобы удалить цикл while из вашей функции plot и поместить содержимое в отдельный метод, который периодически вызывается QTimer.Примерно так.

import sys
from PyQt4 import QtGui, QtCore
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as 
FigureCanvas
import time
import numpy as np
from matplotlib.figure import Figure
import explorerhat

class Window(QtGui.QMainWindow):

    def __init__(self):
        super(Window, self).__init__()
        self.setGeometry(400, 400, 700, 500)
        self.setWindowTitle("PiDAQ")

        ## Define Canvas size and location to be embedded into Main Window
        canvas = Canvas(self, width = 4, height = 4)
        canvas.move(200,20)

        self.show()
        self.timer = QtCore.QTimer(100) # 100 msec
        selt.timer.timeout.connect(canvas.updatePlot)



class Canvas(FigureCanvas):
    def __init__(self, parent = None, width =5 , height = 5, dpi =100):
        fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = fig.add_subplot

        FigureCanvas.__init__(self, fig)
        self.setParent(parent)

        self.t0 = time.time()

        self.i=0
        print('t0=', t0)
        ax = self.figure.add_subplot(111)

        N=50

        self.x = np.arange(N)*20/N
        self.self.y1 = np.arange(N)*5/N
        self.y2 = np.arange(N)*5/N

        self.line1, = self.ax.plot(x, y1, 'b-')
        self.line2, = self.ax.plot(x, y2, 'r-')


    def updatePlot(self):
        self.i =+ 1
        V2 = self.explorerhat.analog.one.read()
        V3 = self.explorerhat.analog.two.read()
        V4 = self.explorerhat.analog.three.read()
        V5 = self.explorerhat.analog.four.read()
        if V2 > 2.5:
            output = ' POW!!! '
        else:
            output = ''
        t = time.time()-self.t0

        if self.i % N == 0:
            print(i, t, V2, V3, V4, V5, output)

        x = self.x
        x[i%N-1] = t

        if self.i % N == 0:
            self.y1[-1] = V2
            self.y2[-1] = V3
            self.line1.set_xdata(x-x[0])
            self.line1.set_ydata(y1)
            self.line2.set_xdata(x-x[0])
            self.line2.set_ydata(y2)
            self.draw()
        else:
            self.y1[i%N-1] = V2
            self.y2[i%N-1] = V3

Отказ от ответственности, я не запускал код выше.Может содержать небольшие ошибки.

...