QTimer.singleshot is causing the GUI to hangout

  pyqt, pyqt5, python

I am creating a table that shows the running processes, with a decorator to update these information. Using the decorator as in the code below, causes the GUI to hangs out every time the singleshot is called (every second).

Why the singleshot is causing the GUI to hangs, and how can I get better logic ?

# First create table
data = getProcesses()
tableWidget = QTableWidget()
Layout.addWidget(tableWidget)
fillTable(data, len(data['pid']), len(data), tableWidget)

# get the processes
    def getProcesses():
        allprocesses = {}
        for p in psutil.process_iter():
            try:
                if p.name().lower() in ["python.exe", "pythonw.exe"]: # console, window
                    with p.oneshot():
                        allprocesses.setdefault('pid', []).append(p.pid)
                        allprocesses.setdefault('memory(MB)', []).append(p.memory_full_info().uss/(1024**2))
                        allprocesses.setdefault('memory(%)', []).append(p.memory_percent(memtype="rss"))
                        allprocesses.setdefault('cpu_times(s)', []).append(sum(p.cpu_times()[:2]))
                        allprocesses.setdefault('create_time', []).append(datetime.datetime.fromtimestamp(p.create_time()).strftime("%Y-%m-%d %H:%M:%S"))
                        allprocesses.setdefault('cpu(%)', []).append(p.cpu_percent()/psutil.cpu_count())
            except:
                continue
        del p
        return allprocesses

def updateInfo(data, table):
    try:
        table.clear()
        for p in psutil.process_iter():
            if p.pid in data['pid']:
                try:
                    with p.oneshot():
                        data['memory(MB)'][data['pid'].index(p.pid)]    = p.memory_full_info().uss/(1024**2)
                        data['memory(%)'][data['pid'].index(p.pid)]     = p.memory_percent(memtype="rss")
                        data['cpu_times(s)'][data['pid'].index(p.pid)]  = sum(p.cpu_times()[:2])
                        data['cpu(%)'][data['pid'].index(p.pid)]        = p.cpu_percent()/psutil.cpu_count()
                        self.fillTable(data, len(data['pid']), len(data), table) 
                except:
                    continue
    except:
        pass                      

def tabledecorator(func):
    @functools.wraps(func)
    def wrapper(data, r, c, table):
        func(data, r, c, table)
        QTimer.singleShot(1000, lambda: self.updateInfo(data, table))            
    return wrapper

@tabledecorator
def fillTable(data, r, c, table):
    table.setRowCount(r) 
    table.setColumnCount(c)
    horHeaders = []
    for n, key in enumerate(reversed(sorted(data.keys()))):
        horHeaders.append(key)
        for m, item in enumerate(data[key]):
            newitem = QTableWidgetItem()
            newitem.setData(Qt.DisplayRole, item)
            table.setItem(m, n, newitem)
    table.setHorizontalHeaderLabels(horHeaders)
    table.resizeColumnsToContents()
    table.resizeRowsToContents()
    del horHeaders, n, key, m, item, newitem

Source: Python Questions

LEAVE A COMMENT