Home > database >  Queue not filling
Queue not filling

Time:07-11

I'm trying to figure out how to use the Queue system in python. In the code below I'm trying to use two threads, one that begins an update function feeds data into a put() and one that takes data from the put() with get() and updates the chart with that data.

However, using print statements show that it is putting "None" into put() and the get() seems to get some data somehow but only twice, and only the same data. However, the rest of the thread() function is certainly adding more and more data to the data list

import pyqtgraph as pg
import numpy as np
from PyQt5 import QtWidgets, QtCore, QtGui
from pyqtgraph import PlotWidget, plot, QtCore, QtGui
import sys 
import os
from random import randint
import time
import threading
import os
import queue
import random
from apscheduler.schedulers.background import BackgroundScheduler


class CandlestickItem(pg.GraphicsObject):
    def __init__(self):
        pg.GraphicsObject.__init__(self)
        self.flagHasData = False

    def set_data(self, data):
        self.data = data 
        self.flagHasData = True
        self.generatePicture()
        self.informViewBoundsChanged()
        


    def generatePicture(self):
        self.picture = QtGui.QPicture()
        p = QtGui.QPainter(self.picture)
        p.setPen(pg.mkPen('w'))
        w = (self.data[1][0] - self.data[0][0]) / 3.
        for (t, open, close, min, max) in self.data:
            p.drawLine(QtCore.QPointF(t, min), QtCore.QPointF(t, max))
            if open > close:
                p.setBrush(pg.mkBrush('r'))
            else:
                p.setBrush(pg.mkBrush('g'))
            p.drawRect(QtCore.QRectF(t-w, open, w*2, close-open))
        p.end()

    def paint(self, p, *args):
        if self.flagHasData:
            p.drawPicture(0, 0, self.picture)

    def boundingRect(self):
        return QtCore.QRectF(self.picture.boundingRect())

app = QtWidgets.QApplication([])

data = [  
    [1., 10, 13, 5, 15],
    [2., 13, 17, 9, 20],
    [3., 17, 14, 11, 23],
    [4., 14, 15, 5, 19],
    [5., 15, 9, 8, 22],
    [6., 9, 15, 8, 16],
]
item = CandlestickItem()
item.set_data(data)

plt = pg.plot()
plt.addItem(item)
plt.setWindowTitle('pyqtgraph example: customGraphicsItem')
q = queue.Queue()

def update():
    global item, data
    while True:
        data_len = len(data)
        rand = random.randint(0, len(data)-1)
        new_bar = data[rand][:]
        new_bar[0] = data_len
        data.append(new_bar)
        q.put(data)
        print("putting data "   str(q.put(data)))
        
        # print(data)
        time.sleep(1)

    # app.processEvents() 

def startTheThread():

    t = threading.Thread(target = update, args = ())
    t.start()
    
def startTheThread_2():
    t2 = threading.Thread(target = thread, args = ())
    t2.start()
    
    
def thread():
    while not q.empty():
        i = q.get()
        print("getting data "   str(i))
        print(i)
        item.set_data(i)
        # CandlestickItem(i) 
        q.task_done() 
        
        
startTheThread()
startTheThread_2()



if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtWidgets.QApplication.instance().exec_()

This is the output of this code until I stop it's execution.

putting data Nonegetting data [[1.0, 10, 13, 5, 15], [2.0, 13, 17, 9, 

20], [3.0, 17, 14, 11, 23], [4.0, 14, 15, 5, 19], [5.0, 15, 9, 8, 22], [6.0, 9, 15, 8, 16], [6, 17, 14, 11, 23]]
[[1.0, 10, 13, 5, 15], [2.0, 13, 17, 9, 20], [3.0, 17, 14, 11, 23], [4.0, 14, 15, 5, 19], [5.0, 15, 9, 8, 22], [6.0, 9, 15, 8, 16], [6, 17, 14, 11, 23]]
getting data [[1.0, 10, 13, 5, 15], [2.0, 13, 17, 9, 20], [3.0, 17, 14, 11, 23], [4.0, 14, 15, 5, 19], [5.0, 15, 9, 8, 22], [6.0, 9, 15, 8, 16], [6, 17, 14, 11, 23]]
[[1.0, 10, 13, 5, 15], [2.0, 13, 17, 9, 20], [3.0, 17, 14, 11, 23], [4.0, 14, 15, 5, 19], [5.0, 15, 9, 8, 22], [6.0, 9, 15, 8, 16], [6, 17, 14, 11, 23]]

putting data None
putting data None
putting data None
putting data None
putting data None
putting data None
putting data None
putting data None
putting data None
putting data None
putting data None
putting data None
putting data None

CodePudding user response:

There are a variety of issues in your code. But the main issue is very simple, your thread function that gets data from the queue exits as soon as the queue is empty. It loops with while not q.empty():, which will only last until it's consumed all the currently available data. Then it quits and never checks again.

Likely you want to to loop indefinitely. Just a simple while True will do that for you, as q.get will block for as long as necessary, if there's no data currently available.

Among the other issues in your code:

  • Every time you do q.put(data), you're putting a reference to the same list of lists, data. This is problematic if you want the unchanged data to be processed first, before the updated data gets processed in a later step. If the queue is actually holding several updates at once, you'd then see the most recent version of the data processed several times. Copying data before putting it into the queue should fix this.

  • The print call you have in update causes you to put to the queue twice. And since put doesn't return anything, you always get None in your output. Probably you want to be printing data instead of the return value from put (and certainly not calling it twice).

  • Related