python-3.xwxpythonpypubsub

pub.sendMessage is not working in my code


I am getting error after running code with below class. Clueless right now, please help

from __future__ import division
from threading import Thread
from pubsub import pub
import os
import glob

########################################################################
class process_csv_thread(Thread):
    """Test Worker Thread Class."""

Solution

  • An answer, just for the record. (Bare in mind, I'm no Thread wizard.)
    If the Thread is not stopped and you don't unsubscribe from the messages, there is the possibility of messages being received from a still running Thread, which will attempt to update a widget that no longer exists.

    I've adapted your code to include a Stop method for the Thread.
    I also join the thread to ensure that it has terminated, before destroying the GUI.
    Obviously, this Thread is simply spinning, you would need to ensure that a working Thread has a means of checking the running variable.

    Thread code process_csv_class.py

    from __future__ import division
    from threading import Thread
    from pubsub import pub
    import os
    import glob
    import time
    
    ########################################################################
    class process_csv_thread(Thread):
        """Test Worker Thread Class."""
    
        #----------------------------------------------------------------------
        def __init__(self,csv_path,rnti_value):
            """Init Worker Thread Class."""
            self.csv_path = csv_path
            self.rnti_value = rnti_value
    
            Thread.__init__(self)
            self.running = True
            self.start()    # start the thread i.e. run()
    
        #----------------------------------------------------------------------
        def run(self):
            all_files_list = glob.glob(self.csv_path+'/*.csv')
            output_excel_file='Parsed_output.xlsx'
            os.chdir(self.csv_path)
            pub.sendMessage("update", msg="Currently loading")
            while self.running == True:
                time.sleep(1)
                pub.sendMessage("update", msg="Processing files")
            pub.sendMessage("finish", msg="Thread Stopped")
            pub.sendMessage("finish", msg="Processing Terminated")
    
        def stop(self):
            self.running = False
    

    Main program:

    import time
    import wx
    import os
    import configparser
    
    from pubsub import pub
    
    #from extract_class import TestThread
    from process_csv_class import process_csv_thread
    
    ########################################################################
    class MyForm(wx.Frame):
    
        #----------------------------------------------------------------------
        def __init__(self):
            wx.Frame.__init__(self, None, wx.ID_ANY, "Nokia 5G TTI Parser",size=(560,460))
    
            # Add a panel so it looks the correct on all platforms
    
            self.config = configparser.ConfigParser()
            self.config.read("config_setup.ini")
    
            panel = wx.Panel(self, wx.ID_ANY)
    
            self.load_csv_btn=load_csv_btn= wx.Button(panel, label="Load 5G TTI CSV")
            load_csv_btn.Bind(wx.EVT_BUTTON, self.selectLogsFolder)
    
            self.def_opening_text = wx.TextCtrl ( panel, size = (122, 17),value = "Default Load Location:",style = wx.TE_READONLY | wx.NO_BORDER | wx.TE_CENTRE )
            self.def_opening_location = wx.TextCtrl ( panel, size = (300, -1),value = self.config.get('PrevConfig','defaultLoad') )
    
            self.process_btn=process_btn= wx.Button(panel, label="Process CSV Files")
            process_btn.Bind(wx.EVT_BUTTON, self.processCSVs)
    
            self.chart_btn=chart_btn= wx.Button(panel, label="Generate Chart Slides")
            chart_btn.Bind(wx.EVT_BUTTON, self.generateSlides)
    
            self.rnti_value = wx.TextCtrl ( panel, size = (45, -1),value = "RNTI:",style = wx.TE_READONLY | wx.NO_BORDER | wx.TE_LEFT )
            self.rnti_value_var = wx.TextCtrl(panel,value=self.config.get('PrevConfig','rnti_value_default'))
    
            self.outputMessages = wx.TextCtrl(parent = panel, id = -1, size = (530, 200), style = wx.TE_MULTILINE)
    
            self.load_fold_btn=load_fold_btn= wx.Button(panel, label="Results Folder")
            load_fold_btn.Bind(wx.EVT_BUTTON, self.LoadFold)
    
            self.exit_btn=exit_btn= wx.Button(panel, label="Exit")
            exit_btn.Bind(wx.EVT_BUTTON, self.onExit)
    
            self.about_btn=about_btn= wx.Button(panel, label="About")
            about_btn.Bind(wx.EVT_BUTTON, self.onAbout)
    
            topSizer = wx.BoxSizer(wx.VERTICAL)
    
            load_sizer = wx.BoxSizer(wx.HORIZONTAL)
            load_sizer.Add(load_csv_btn, 0, wx.ALL, 5)
            load_sizer.Add(self.def_opening_text, 0, wx.ALL, 8)
            load_sizer.Add(self.def_opening_location, 0, wx.ALL, 5)
    
            process_csv_sizer = wx.BoxSizer(wx.HORIZONTAL)
            process_csv_sizer.Add(process_btn, 0, wx.ALL|wx.EXPAND, 5)
            process_csv_sizer.Add(chart_btn, 0, wx.ALL|wx.EXPAND, 5)
    
            rnti_val_sizer = wx.BoxSizer(wx.HORIZONTAL)
            rnti_val_sizer.Add(self.rnti_value, 0, wx.ALL|wx.EXPAND, 5)
            rnti_val_sizer.Add(self.rnti_value_var, 0, wx.ALL|wx.EXPAND, 5)
    
            display_msg_sizer = wx.BoxSizer(wx.HORIZONTAL)
            display_msg_sizer.Add(self.outputMessages, 0, wx.ALL, 5)
    
            exit_row_sizer = wx.BoxSizer(wx.HORIZONTAL)
            exit_row_sizer.Add(self.load_fold_btn, 0, wx.ALL, 5)
            exit_row_sizer.Add(self.exit_btn, 0, wx.ALL, 5)
            exit_row_sizer.Add(self.about_btn, 0, wx.ALL, 5)
    
            topSizer.Add(load_sizer, 0, wx.LEFT)
            #topSizer.Add(extract_sizer, 0, wx.RIGHT)
            topSizer.Add(process_csv_sizer, 0, wx.RIGHT)
            topSizer.Add(rnti_val_sizer, 0, wx.RIGHT)
            topSizer.Add(display_msg_sizer, 0, wx.CENTER)
            topSizer.Add(exit_row_sizer, 0, wx.RIGHT)
    
    
            panel.SetSizer(topSizer)
    
            # create a pubsub receiver
            pub.subscribe(self.updateDisplay, "update")
            pub.subscribe(self.ThreadStopped, "finish")
    
            self.updateDisplay("Please load csv file")
    
        #----------------------------------------------------------------------
        def updateDisplay(self, msg):
            """
            Receives data from thread and updates the display
            """
            self.outputMessages.write("\n>>>%s" % str(msg))
            print("\n>>>%s" % str(msg))
    
        #----------------------------------------------------------------------
        def ThreadStopped(self, msg):
            """
            Receives finish from thread and updates the display
            """
            self.outputMessages.write("\n>>>%s" % str(msg))
            print("\n>>>%s" % str(msg))
    
        def selectLogsFolder(self, event):
            openDirDialog = wx.DirDialog(self,"Choose a directory:",size=(300,400),style=wx.DD_DEFAULT_STYLE)
            openDirDialog.SetPath(self.def_opening_location.GetValue())
            openDirDialog.ShowModal()
            self.csv_folder = openDirDialog.GetPath()
            self.updateDisplay("File Location: "+self.csv_folder)
    
            self.def_opening_location.SetValue(self.csv_folder)
            openDirDialog.Destroy()
    
    
        def processCSVs(self, event):
            try:
    
                self.pst = process_csv_thread(self.csv_folder,self.rnti_value_var.GetValue())
    
            except:
                self.updateDisplay("Error: Please check if CSV File is loaded")
    
        def generateSlides(self, event):
    
            try:
                cqi_sinr_thread(self.csv_folder,self.cells_list_input.GetValue(),self.rnti_value_var.GetValue())
            except:
                self.updateDisplay("Error: Please check if CSV File is loaded")
    
    
        def LoadFold(self, event):
            try:
                os.startfile(os.path.dirname(self.csv_folder))
            except:
                self.updateDisplay("Error: First Load File ")
    
    
        def onExit(self, event):
    
            try:
                self.pst.stop()
                self.pst.join()
            except:
                pass
            pub.unsubscribe(self.updateDisplay, "update")
            pub.unsubscribe(self.ThreadStopped, "finish")
            wx.GetApp().Yield()
            time.sleep(4)
    
            #self.config.set('PrevConfig', 'CellsList', self.cells_list_input.GetValue())
            self.config.set('PrevConfig', 'rnti_value_default', self.rnti_value_var.GetValue())
            self.config.set('PrevConfig', 'defaultLoad', self.def_opening_location.GetValue())
            with open('config_setup.ini', 'w') as configfile:
                self.config.write(configfile)
            configfile.close()
            self.Close()
    
        def onAbout(self, event):
            info = wx.AboutDialogInfo()
            info.Name = "KPI Parser"
            info.Version = "v13.0"
            info.AddDeveloper("***an \n**nan.**sir@*****.com")
            wx.AboutBox(info)
    
    #----------------------------------------------------------------------
    # Run the program
    if __name__ == "__main__":
        app = wx.App(False)
        frame = MyForm()
        frame.Show()
        app.MainLoop()
    

    config_setup.ini file

    [PrevConfig]
    defaultload = /home/rolf
    rnti_value_default = abc