Is there anyway I can run this program like this.
At the start of the program GUI shows and background process starts running. And the the GUI can be closed and opened anytime the user wants. But the background process keeps running uninterrupted.
Here is my current code. 4 classes.
- FileHandler
- Scanner <- Inherits from QThread
- UserInterface <- Takes QMainWindow as an argument
- Main <- Inherits from UserInterface
import math
import sys
import time
import psutil
import win32gui
import win32process
import threading
import atexit
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtChart import QChart, QChartView, QPieSeries
from PyQt5.QtCore import QThread, pyqtSignal
RECORDED_PROGRAMS = {}
class FileHandler():
def __init__ (self):
print("[+] Driver File Initiated...")
self.logFile = open("log.txt", "a+")
self.dataFile = open("data.txt", "a+")
def readFile(self):
pass
def writeFile(self):
print("[+] {} : Writing Data to the File...".format(time.strftime("%H:%M:%S".format(time.localtime()))))
self.dataFile.write("\nOn Write : {} : ".format(time.strftime("%H:%M:%S".format(time.localtime()))) + str(RECORDED_PROGRAMS))
def closeFile(self):
print("[+] File Handler Exiting...")
print("[+] Closing File...")
self.dataFile.write("\nOn Exit : {} : ".format(time.strftime("%H:%M:%S".format(time.localtime()))) + str(RECORDED_PROGRAMS))
self.dataFile.write("\n=================================================================================")
self.dataFile.write("\n[!] Program Exited. TimeStamp: {}".format(time.strftime("%H:%M:%S", time.localtime())))
self.dataFile.write("\n=================================================================================")
self.dataFile.close()
self.logFile.close()
#==============================================================================================================
class Scanner(QThread):
signal = pyqtSignal(bool)
def run(self):
print("[+] Scanner Initialized...")
count = 0
while True:
count += 1
try:
activeWindowId = win32gui.GetForegroundWindow()
threadList = win32process.GetWindowThreadProcessId(activeWindowId)
mainThreadName = psutil.Process(threadList[-1]).name()
if(mainThreadName in RECORDED_PROGRAMS.keys()):
RECORDED_PROGRAMS[mainThreadName] += 1
else:
RECORDED_PROGRAMS[mainThreadName] = 1
except Exception as E:
print("[-] Error in Scanner...")
print("======================================================")
print(E)
print("======================================================")
if count == 60:
self.signal.emit(True)
count = 0
time.sleep(1)
#==============================================================================================================
class UserInterface():
def __init__(self, MainWindow):
self.setupUi(MainWindow)
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(640, 480)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth())
MainWindow.setSizePolicy(sizePolicy)
MainWindow.setMinimumSize(QtCore.QSize(640, 480))
MainWindow.setMaximumSize(QtCore.QSize(640, 480))
font = QtGui.QFont()
font.setFamily("Bahnschrift")
font.setPointSize(14)
MainWindow.setFont(font)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.centralWidgetHLayout = QtWidgets.QHBoxLayout(self.centralwidget)
self.centralWidgetHLayout.setObjectName("centralWidgetHLayout")
self.leftGroupBox = QtWidgets.QGroupBox(self.centralwidget)
self.leftGroupBox.setMinimumSize(QtCore.QSize(300, 462))
self.leftGroupBox.setMaximumSize(QtCore.QSize(300, 462))
self.leftGroupBox.setObjectName("leftGroupBox")
self.leftGroupVLayout = QtWidgets.QVBoxLayout(self.leftGroupBox)
self.leftGroupVLayout.setContentsMargins(5, 5, 5, 5)
self.leftGroupVLayout.setSpacing(5)
self.leftGroupVLayout.setObjectName("leftGroupVLayout")
self.widget = QtWidgets.QWidget(self.leftGroupBox)
self.widget.setMinimumSize(QtCore.QSize(288, 427))
self.widget.setMaximumSize(QtCore.QSize(288, 427))
self.widget.setObjectName("widget")
self.widgetLayout = QtWidgets.QVBoxLayout(self.widget)
self.widgetLayout.setContentsMargins(0, 0, 0, 0)
self.widgetLayout.setSpacing(0)
self.widgetLayout.setObjectName("widgetLayout")
self.series = QPieSeries()
self.chart = QChart()
self.chart.addSeries(self.series)
self.chartView = QChartView(self.chart)
self.chart.setAnimationOptions(QChart.SeriesAnimations)
self.chart.legend().hide()
self.widgetLayout.addWidget(self.chartView)
self.leftGroupVLayout.addWidget(self.widget)
self.centralWidgetHLayout.addWidget(self.leftGroupBox)
self.rightGroupBox = QtWidgets.QGroupBox(self.centralwidget)
self.rightGroupBox.setMinimumSize(QtCore.QSize(316, 462))
self.rightGroupBox.setMaximumSize(QtCore.QSize(316, 462))
self.rightGroupBox.setObjectName("rightGroupBox")
self.rightGroupVLayout = QtWidgets.QVBoxLayout(self.rightGroupBox)
self.rightGroupVLayout.setContentsMargins(5, 5, 5, 5)
self.rightGroupVLayout.setSpacing(5)
self.rightGroupVLayout.setObjectName("rightGroupVLayout")
self.tableView = QtWidgets.QTableWidget(self.rightGroupBox)
self.tableView.setMinimumSize(QtCore.QSize(304, 427))
self.tableView.setMaximumSize(QtCore.QSize(304, 427))
self.tableView.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.tableView.setFrameShadow(QtWidgets.QFrame.Plain)
self.tableView.setLineWidth(1)
self.tableView.setMidLineWidth(0)
self.tableView.setObjectName("tableView")
self.tableView.setColumnCount(2)
self.tableView.setRowCount(0)
item = QtWidgets.QTableWidgetItem()
self.tableView.setHorizontalHeaderItem(0, item)
item = QtWidgets.QTableWidgetItem()
self.tableView.setHorizontalHeaderItem(1, item)
self.tableView.horizontalHeader().setVisible(True)
self.tableView.horizontalHeader().setDefaultSectionSize(150)
self.tableView.horizontalHeader().setHighlightSections(False)
self.tableView.horizontalHeader().setMinimumSectionSize(150)
self.tableView.verticalHeader().setVisible(True)
self.tableView.verticalHeader().setDefaultSectionSize(31)
self.rightGroupVLayout.addWidget(self.tableView)
self.centralWidgetHLayout.addWidget(self.rightGroupBox)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.leftGroupBox.setTitle(_translate("MainWindow", "Top 10 Overview"))
self.rightGroupBox.setTitle(_translate("MainWindow", "Recorded Programs"))
self.tableView.setSortingEnabled(True)
item = self.tableView.horizontalHeaderItem(0)
item.setText(_translate("MainWindow", "Program Name"))
item = self.tableView.horizontalHeaderItem(1)
item.setText(_translate("MainWindow", "Time (mins)"))
MainWindow.show()
#===========================================================================================================================
class Main(UserInterface):
def __init__(self, MainWindow):
self.scanner = Scanner()
self.fileHandler = FileHandler()
self.runScanner()
super().__init__(MainWindow)
def runScanner(self):
self.scanner.signal.connect(self.update)
self.scanner.start()
def update(self):
self.updateChart()
self.updateTable()
self.updateLog()
def updateChart(self):
print("[+] Updating Chart...")
self.chart.removeSeries(self.series)
self.series.clear()
for key, val in RECORDED_PROGRAMS.items():
self.series.append(key, math.ceil(val/60))
self.chart.addSeries(self.series)
def updateTable(self):
print("[+] Updating Table...")
rowCount = len(RECORDED_PROGRAMS)
self.tableView.setRowCount(rowCount)
programNames = list(RECORDED_PROGRAMS.keys())
timeRec = list(RECORDED_PROGRAMS.values())
for row in range(rowCount):
for column in range(2):
if column == 0:
self.tableView.setItem(row, column, QtWidgets.QTableWidgetItem(str(programNames[row])))
if column == 1:
self.tableView.setItem(row, column, QtWidgets.QTableWidgetItem(str(math.ceil(timeRec[row]/60))))
def updateLog(self):
print("[+] Updating Log...")
self.fileHandler.writeFile()
def quit(self):
print("[+] Quitting Program...")
self.scanner.terminate()
self.fileHandler.closeFile()
#===========================================================================================================================
def _exit():
print("[+] At Exit Func Triggered...")
main.quit()
if __name__ == "__main__":
guiApplication = QtWidgets.QApplication(sys.argv)
window = QtWidgets.QMainWindow()
main = Main(window)
atexit.register(_exit)
stop = False
while not stop:
answer = input("Stop [Y/N]? ")
if answer == "Y":
stop = True
time.sleep(0.5)
print("[+] Main Loop Exit hit...")