python - Why is my code running twice, crashing, and not printing stderr? Multiprocessing with output redirected to GUI -
i have code printing sys.stdout
gui tkinter text widget. getting strange behavior program , can't figure out why; need troubleshooting.
the biggest problem sys.stderr
not printing gui or ide results. may result of how got sys.stdout
go gui not knowledgeable enough diagnose whether that's case. followed code: python multiprocessing redirect stdout of child process tkinter text. may have why code apparently running twice.
i have main program running gui , use multiprocessing
run separate script imported module made. 1 of first things script check errors in inputs. if there's error, have give custom exception end process without closing python. exception uses tkmessagebox
generate window alert user program needs attention. used print traceback gui no longer redirecting sys.stdout
.
anyway, when run script , gets exception, brings 2 windows. 1 looks windows-generated os message box message inside programmed. other empty white window title "tk" disappears when hit "ok" on other message box. python crashes after hitting "ok". gui doesn't crash must subprocess crashes. edit: second window problem solved , code below has been updated reflect that. however, subprocess still crashing when hit "ok" on message box , still loading module twice (apparently).
i have print statement @ beginning of imported module. module imported before gui created , shows in ide. when initiate function in module using multiprocessing
, print statement shows in ide again. statement isn't part of function running.
i have no background in computer science totally obvious i'm not seeing.
please take , see going on. i've simplified code , should run you. i'm running windows 8.1 , python 2.7.9.
gui/main loop:
#### _______________import modules_________________### import tkinter multiprocessing.queues import queue multiprocessing import process import sys, traceback threading import thread import qbmpchugger ###_____create text catcher ______### def text_catcher(text_widget, queue): while true: text_widget.insert("end", queue.get()) app.update_idletasks() class stdoutqueue(queue): def __init__(self, *args, **kwargs): queue.__init__(self, *args, **kwargs) def write(self, msg): self.put(msg) def flush(self): sys.__stdout__.flush() def errorgrab(type, value, traceback): exception_string = "".join(traceback.format_exception(type, value, traceback)) # whatever want here print exception_string print "testing excepthook" ###____________widget__________________### class inputbox(tkinter.tk): def __init__(self,parent): tkinter.tk.__init__(self, parent) self.parent = parent self.initialize() def initialize(self): # build frame self.ok = tkinter.frame(self, padx=3, pady=3) self.ok.grid(column=0, row=2, columnspan=3, sticky="ew") self.printframe = tkinter.labelframe(self, borderwidth=3, relief="ridge", padx=3, pady=3, text="results") self.printframe.grid(column=0, row=3, columnspan=4, sticky="ew") # build "run" button self.okbutton = tkinter.button(self.ok, text=u"ok", command=self.okgo, anchor="e") self.okbutton.pack(side="right") # build output viewer self.view = tkinter.text(self.printframe) self.view.grid(column=0, row=0, columnspan=3, sticky="ew") self.scroll = tkinter.scrollbar(self.printframe, orient=tkinter.vertical) self.scroll.config(command=self.view.yview) self.view.config(yscrollcommand=self.scroll.set) self.scroll.grid(column=4, row=0, sticky="sn") def okgo(self): sys.stdout = q sys.excepthook = errorgrab monitor = thread(target=text_catcher, args=(self.view, q)) monitor.daemon = true monitor.start() self.view.delete(1.0, "end") self.update_idletasks() print("loading user-specified inputs...") wtin = "d:/python/inputs/wtdepth1.aux" print("loadingmodule") self.update_idletasks() import qbmpchugger self.update_idletasks() # starts child process, qbmpchugger.bmpcode inarg = (q, wtin) p = process(target=qbmpchugger.bmpcode, args=inarg) p.start() p.join() print("ended") if __name__ == "__main__": app = inputbox(none) app.title("file inputs , program settings") # start text monitor q = stdoutqueue() monitor = thread(target=text_catcher, args=(app.view, q)) monitor.daemon = true monitor.start() app.mainloop()
module "qbmpchugger":
#### _______________initialize_________________### print("creating program environment , importing modules...") import os import sys import tkmessagebox import tkinter # create user-defined exceptions class badinput(exception): pass def bmpcode(q, wtin): ### _________________verify inputs________________### boxroot = tkinter.tk() boxroot.withdraw() sys.stdout = q sys.stderr = q print("checking out spatial analyst extension gis...") # check out extension , overwrite outputs print("checking validity of specified inputs...") # check provided file paths valid inputs = [wtin] in inputs: if os.path.exists(i): pass else: message = "\ninvalid file path: {}\ncorrect path name , try again." tkmessagebox.showerror("invalid path", message.format(i)) raise badinput(message.format(i)) print("success!")
edit: removed section module used arcpy; shouldn't source of error.
update 1: tried moving import qbmpchugger
statement beginning of gui code function okgo
. result print("creating program environment , importing modules...")
prints once in gui when first loads , prints again in ide when starts second process. if run okgo
again without closing gui, prints in ide.
i closed gui , reran program check print statement printed first , got error; printed in ide. don't think changed code between runs that's interesting. i'll investigating traceback guess. updated code reflect changed location of import qbmpchugger
.
exception in thread thread-1: traceback (most recent call last): file "d:\python\python27\lib\threading.py", line 810, in __bootstrap_inner self.run() file "d:\python\python27\lib\threading.py", line 763, in run self.__target(*self.__args, **self.__kwargs) file "d:/python/pycharm/projects/bmp_tool/gui-thread.py", line 13, in text_catcher app.update_idletasks() file "d:\python\python27\lib\lib-tk\tkinter.py", line 1020, in update_idletasks self.tk.call('update', 'idletasks') tclerror: bad option ".242660736.242702216,relief": must idletasks
update 2: have been messing around sys.stdout
, sys.stderr
. deleted redirection of stderr , stdout in main program , did sys.stderr = q
in child process. received exception looks half of exception programmed; missing message , name of exception. ran function again without exiting gui , gave same exception said "process 2", , again "process 3". closing gui , running again gave me full exception, running again gave me shortened version.
process process-1: traceback (most recent call last): file "d:\python\python27\lib\multiprocessing\process.py", line 258, in _bootstrap self.run() file "d:\python\python27\lib\multiprocessing\process.py", line 114, in run self._target(*self._args, **self._kwargs) file "d:\python\pycharm\projects\bmp_tool\qbmpchugger.py", line 44, in bmpcode
update 3: appears if child can print either stdout or stderr in gui, not both, , has preference stdout.
Comments
Post a Comment