'PyQt5 threading isn't working display freeze
I have a python program that uses mysql.connector to login to a server and execute the query and saving the sql result in excel file. i use pyqt for my gui and when i press the button the gui is freezing. i have created the qthread and worker class but when i import the executor function and pressing the button the program is running and the gui is starting to freeze, what am i doing wrong? how can i implement the multithreading?
from cmath import inf
from multiprocessing import connection
from operator import index
import os
from sqlite3 import Cursor
from unittest.result import failfast
from datetime import datetime
import mysql.connector
from mysql.connector import errorcode
import pandas as pd
#importing Queries
from Queries import *
#Location Ip's
from locations import locs
from locations import usr,passwd,db
startDate='2022-04-01'
endDate='2022-04-15'
logfailedls = 'logfailed.txt'
logsuccessls = 'logsuccess.txt'
class bcolors:
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKCYAN = '\033[96m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
def executor(QUERY):
alldf = None
for type,info in locs.items():
if not os.path.isdir('%s/'%(type)):
os.makedirs('%s/'%(type))
ls = os.listdir('{}/'.format(type))
if logfailedls in ls:
os.remove('{}/{}'.format(type,logfailedls))
if logsuccessls in ls:
os.remove('{}/{}'.format(type,logsuccessls))
for ip,locName in info.items():
try:
cnx = mysql.connector.connect(user=usr, password=passwd,host=ip, database=db)
if cnx.is_connected():
print("Connection Succesfull to {}".format(locName))
logsuccess = open('{}/logsuccess.txt'.format(type),'a')
logsuccess.write('{} : {}-{}\n'.format(datetime.now().strftime("%Y-%m-%d %H:%M:%S"),ip,locName))
logsuccess.close()
location = cnx.cursor(buffered=True)
location.execute("SELECT loccod FROM docparameters d limit 1")
loc = location.fetchone()[0]
cursor = cnx.cursor()
cursor.execute(QUERY)
df = pd.DataFrame(cursor.fetchall())
if alldf is not None:
alldf = alldf.append(df)
else:
alldf = df
print(df)
field_names = [ i[0] for i in cursor.description]
print(field_names)
xlswriter = pd.ExcelWriter('{}/{}.xls'.format(type,loc),engine='openpyxl')
df.to_excel(xlswriter)
xlswriter.save()
cnx.close()
except mysql.connector.Error as err:
if err.errno == errorcode.ER_ACCESS_DENIED_ERROR:
print("Something wrong with your username or password")
elif err.errno == errorcode.ER_BAD_DB_ERROR:
print("DATABASE does not exist")
else:
print(err)
print("Connectin Failed to %s"%(loc))
logfailed = open("{}/logfailed.txt".format(type),'a')
logfailed.write('{} : {}-{}\n'.format(datetime.now().strftime("%Y-%m-%d %H:%M:%S"),ip,locName))
logfailed.close()
else:
cnx.close()
return [alldf,field_names]
def saveToExcel(query,filename):
xlswriter = pd.ExcelWriter("%s.xls"%(filename),engine='openpyxl')
queryDatas = executor(query)
export = queryDatas[0]
export.columns = queryDatas[1]
export.to_excel(xlswriter,index=False)
xlswriter.save()
#saveToExcel(union,'UNION 15%')
#saveToExcel(hnb,'HBC 25%')
#saveToExcel(SCB,'SCB')
this is my pyqt gui program
from concurrent.futures import Executor
import traceback
from unittest import result
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import sys
import time
import copy
from connector import *
class WorkerSignals(QObject):
finished = pyqtSignal()
error = pyqtSignal(tuple)
result = pyqtSignal(object)
class Worker(QThread):
def __init__(self,fn,*args,**kwargs):
super(Worker,self).__init__()
self.fn = fn
self.args = args
self.kwargs = kwargs
self.signals = WorkerSignals()
@pyqtSlot()
def run(self):
try:
result = self.fn(*self.args,**self.kwargs)
except:
traceback.print_exc()
exctype, value = sys,sys.exc_info()[:2]
self.signals.error.emit((exctype,value,traceback.format_exc()))
else:
self.signals.result.emit(result)
finally:
self.signals.finished.emit()
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.threadpool = QThreadPool()
print("multithreading with maximum %d threads" % self.threadpool.maxThreadCount())
self.counter = 0
layout = QVBoxLayout()
self.l = QLabel("Start")
b = QPushButton("DANGER!")
b.pressed.connect(self.oh_no)
c = QPushButton("?")
c.pressed.connect(self.change_message)
layout.addWidget(self.l)
layout.addWidget(b)
layout.addWidget(c)
w = QWidget()
w.setLayout(layout)
self.setCentralWidget(w)
self.show()
def change_message(self):
self.message = "OH NO"
def print_output(self,s):
print(s)
def thread_complete(self):
print("THREAD COMPLETE!")
def oh_no(self):
worker = Worker(executor(SCB))
worker.signals.result.connect(self.print_output)
worker.signals.finished.connect(self.thread_complete)
self.threadpool.start(worker)
app = QApplication([])
window = MainWindow()
app.exec_()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
