pub.sendMessage 在我的代码中不起作用

pub.sendMessage is not working in my code

我在 运行 代码后出现错误 class。不知所措,求助

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."""

一个答案,仅供记录。 (记住,我不是 Thread 巫师。)
如果 Thread 没有停止并且您没有取消订阅消息,则有可能从静止的 运行 Thread 接收消息,它将尝试更新一个小部件不复存在。

我已经修改了您的代码以包含 ThreadStop 方法。
在销毁 GUI 之前,我还 join 线程以确保它已终止。
显然,这个 Thread 只是在自旋,您需要确保工作的 Thread 能够检查 running 变量。

线程代码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

主程序:

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 文件

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