Reputation: 3235
I am trying to print to a specific tabbed panel in wxpython, but my below code just seems to print to the 3rd (Running Jobs) TAB panel window and I can't work out why. I want to print the 2nd (QueueList) TAB panel.
import wx
import sys
global queueList
queueList = []
class ScrolledWindow(wx.Frame):
def __init__(self, parent, id, title):
#global panel1
wx.Frame.__init__(self, parent, id, title, size=(800, 700))
self.tabbed = wx.Notebook(self, -1, style=(wx.NB_TOP))
self.panel1 = wx.Panel(self.tabbed, -1)
self.panel2 = wx.Panel(self.tabbed, -1)
self.panel3 = wx.Panel(self.tabbed, -1)
self.tabbed.AddPage(self.panel1, "Submit Job")
self.tabbed.AddPage(self.panel2, "Queue")
self.tabbed.AddPage(self.panel3, "Running Jobs")
self.CreateStatusBar()
menuBar = wx.MenuBar()
menu = wx.Menu()
self.SetMenuBar(menuBar)
self.Centre()
self.submit(self)
self.queue(self)
self.running(self)
def submit(self, event):
self.Show()
dt1 = MyFileDropTarget(self)
self.tc_files = wx.TextCtrl(self.panel1, wx.ID_ANY, pos=(42, 120), size=(500, 25))
self.tc_files.SetDropTarget(dt1)
self.buttonGo = wx.Button(self.panel1, -1, "Submit", pos=(90,530))
self.buttonGo.Bind(wx.EVT_BUTTON, self.submit1)
self.buttonClose = wx.Button(self.panel1, -1, "Quit", pos=(195,530))
self.buttonClose.Bind(wx.EVT_BUTTON, self.OnClose)
outputtxt3 = '''Drag & Drop Folder of Packages to Verify'''
wx.StaticText(self.panel1, -1, outputtxt3, (33, 64), style=wx.ALIGN_CENTRE)
def notify(self, indir):
"""Update file in testcontrol after drag and drop"""
self.tc_files.SetValue(indir[0])
global indirTemp
indirTemp = indir
def submit1(self, edit):
list1 = '\n'.join(indirTemp)
queueList.append(list1)
print queueList
wx.MessageBox('Job Submitted')
def queue(self, event):
self.Show()
self.buttonClose2 = wx.Button(self.panel2, -1, "Quit", pos=(195,170))
self.buttonClose2.Bind(wx.EVT_BUTTON, self.OnClose)
global log2
log2 = wx.TextCtrl(self.panel2, -1, pos=(35, 210), size=(720,400),
style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)
self.redir2=RedirectText(log2)
sys.stdout=self.redir2
def showQueue(self, edit):
global queueList
print queueList
def running(self, event):
self.Show()
self.buttonClose3 = wx.Button(self.panel3, -1, "Quit", pos=(195,170))
self.buttonClose3.Bind(wx.EVT_BUTTON, self.OnClose)
global log3
log3 = wx.TextCtrl(self.panel3, -1, pos=(35, 210), size=(720,400),
style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)
self.redir3=RedirectText(log3)
sys.stdout=self.redir3
def go3(self, edit):
print "do something"
def OnClose(self, e):
self.Close(True)
class MyFileDropTarget(wx.FileDropTarget):
""""""
def __init__(self, window):
wx.FileDropTarget.__init__(self)
self.window = window
def OnDropFiles(self, x, y, filenames):
self.window.notify(filenames)
class RedirectText:
def __init__(self,aWxTextCtrl):
self.out=aWxTextCtrl
def write(self,string):
self.out.WriteText(string)
app = wx.App()
ScrolledWindow(None, -1, 'Application')
app.MainLoop()
Upvotes: 1
Views: 698
Reputation: 14685
As I mentioned in my other answer, the superficial reason why it's not working is because there was a bug :) IE the logic written was not what was intended. The deeper reason is because the app needs some better design. Appended is an example of how that might be done.
The main feature of this design is that it separates the logic of each function (each of which is carried by the user on a separate tab of the notebook) into separate classes. The classes communicate by method calls, and the connections are static at construction (for example, a reference to the queue manager is passed to the submission controller on construction).
This is by no means supposed to be "the best" design, it's just an example of possible improvement - the improvements reduce the chance of the types of hard to find logic errors in the original.
import wx
class MainWindow(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(800, 700))
self.tabbed = wx.Notebook(self, -1, style=(wx.NB_TOP))
self.running = RunningPane(self.tabbed)
self.queue = QueuePane(self.tabbed, self.running)
self.submissions = SubmissionPane(self.tabbed, self.queue)
self.tabbed.AddPage(self.submissions, "Submit Job")
self.tabbed.AddPage(self.queue, "Queue")
self.tabbed.AddPage(self.running, "Running Jobs")
self.CreateStatusBar()
menuBar = wx.MenuBar()
menu = wx.Menu()
self.SetMenuBar(menuBar)
self.Centre()
self.Show()
#---
#
class SubmissionPane(wx.Panel):
def __init__(self, parent, queue_control):
wx.Panel.__init__(self, parent, -1)
self.parent = parent
self.queue_control = queue_control
self.selected_folder = None
self.drop_target = MyFileDropTarget(self)
self.tc_files = wx.TextCtrl(self, wx.ID_ANY, pos=(42, 120), size=(500, 25))
self.tc_files.SetDropTarget(self.drop_target)
self.buttonGo = wx.Button(self, -1, "Submit", pos=(90,530))
self.buttonGo.Bind(wx.EVT_BUTTON, self.OnSubmit)
self.buttonClose = wx.Button(self, -1, "Quit", pos=(195,530))
self.buttonClose.Bind(wx.EVT_BUTTON, self.OnClose)
outputtxt3 = '''Drag & Drop Folder of Packages to Verify'''
wx.StaticText(self, -1, outputtxt3, (33, 64), style=wx.ALIGN_CENTRE)
self.Show()
def SetSubmissionFolders(self, folder_list):
"""Called by the FileDropTarget when files are dropped"""
self.tc_files.SetValue(','.join(folder_list))
self.selected_folders = folder_list
def OnSubmit(self, event):
self.queue_control.QueueFolders(self.selected_folders)
wx.MessageBox('Job Submitted')
def OnClose(self, e):
self.Close(True)
class MyFileDropTarget(wx.FileDropTarget):
""""""
def __init__(self, window):
wx.FileDropTarget.__init__(self)
self.window = window
def OnDropFiles(self, x, y, filenames):
self.window.SetSubmissionFolders(filenames)
#---
#
class QueuePane(wx.Panel):
def __init__(self, parent, run_control):
wx.Panel.__init__(self, parent, -1)
self.parent = parent
self.run_control = run_control
self.queue = []
self.buttonClose2 = wx.Button(self, -1, "Quit", pos=(195,170))
self.buttonClose2.Bind(wx.EVT_BUTTON, self.OnClose)
self.log_text = wx.TextCtrl(self, -1, pos=(35, 210), size=(720,400),
style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)
self.Show()
def QueueFolders(self, folder_list):
"""Called by anyone with a list of folders to queue.
In this code, that is the submission pane."""
self.queue.extend(folder_list)
self.log_text.AppendText("\n".join(folder_list))
def OnClose(self, e):
self.Close(True)
#---
#
class RunningPane(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, -1)
self.parent = parent
self.buttonClose3 = wx.Button(self, -1, "Quit", pos=(195,170))
self.buttonClose3.Bind(wx.EVT_BUTTON, self.OnClose)
self.running_log = wx.TextCtrl(self, -1, pos=(35, 210), size=(720,400),
style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)
self.Show()
def OnClose(self, e):
self.Close(True)
#
#---
app = wx.App()
MainWindow(None, -1, 'Application')
app.MainLoop()
Upvotes: 1
Reputation: 14685
The reason is because you call running()
after you call queue()
in __init__()
, and this is the last thing that redirects stdout before you do some printing.
Here is a version of your code that makes this obvious when you run it, by outputting a trace of what it is doing as it does it...
import wx
import sys
global queueList
queueList = []
class ScrolledWindow(wx.Frame):
def __init__(self, parent, id, title):
#global panel1
wx.Frame.__init__(self, parent, id, title, size=(800, 700))
self.tabbed = wx.Notebook(self, -1, style=(wx.NB_TOP))
self.panel1 = wx.Panel(self.tabbed, -1)
self.panel2 = wx.Panel(self.tabbed, -1)
self.panel3 = wx.Panel(self.tabbed, -1)
self.tabbed.AddPage(self.panel1, "Submit Job")
self.tabbed.AddPage(self.panel2, "Queue")
self.tabbed.AddPage(self.panel3, "Running Jobs")
self.CreateStatusBar()
menuBar = wx.MenuBar()
menu = wx.Menu()
self.SetMenuBar(menuBar)
self.Centre()
self.submit(self)
self.queue(self)
self.running(self)
def submit(self, event):
self.Show()
dt1 = MyFileDropTarget(self)
self.tc_files = wx.TextCtrl(self.panel1, wx.ID_ANY, pos=(42, 120), size=(500, 25))
self.tc_files.SetDropTarget(dt1)
self.buttonGo = wx.Button(self.panel1, -1, "Submit", pos=(90,530))
self.buttonGo.Bind(wx.EVT_BUTTON, self.submit1)
self.buttonClose = wx.Button(self.panel1, -1, "Quit", pos=(195,530))
self.buttonClose.Bind(wx.EVT_BUTTON, self.OnClose)
outputtxt3 = '''Drag & Drop Folder of Packages to Verify'''
wx.StaticText(self.panel1, -1, outputtxt3, (33, 64), style=wx.ALIGN_CENTRE)
def notify(self, indir):
"""Update file in testcontrol after drag and drop"""
self.tc_files.SetValue(indir[0])
global indirTemp
indirTemp = indir
def submit1(self, edit):
list1 = '\n'.join(indirTemp)
queueList.append(list1)
sys.stderr.write("submit1 printing\n")
print queueList
wx.MessageBox('Job Submitted')
def queue(self, event):
self.Show()
self.buttonClose2 = wx.Button(self.panel2, -1, "Quit", pos=(195,170))
self.buttonClose2.Bind(wx.EVT_BUTTON, self.OnClose)
global log2
log2 = wx.TextCtrl(self.panel2, -1, pos=(35, 210), size=(720,400),
style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)
sys.stderr.write("redirecting stdout to log2\n")
self.redir2=RedirectText(log2)
sys.stdout=self.redir2
def showQueue(self, edit):
sys.stderr.write("showQueue printing\n")
global queueList
print queueList
def running(self, event):
self.Show()
self.buttonClose3 = wx.Button(self.panel3, -1, "Quit", pos=(195,170))
self.buttonClose3.Bind(wx.EVT_BUTTON, self.OnClose)
global log3
log3 = wx.TextCtrl(self.panel3, -1, pos=(35, 210), size=(720,400),
style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)
sys.stderr.write("redirecting stdout to log3\n")
self.redir3=RedirectText(log3)
sys.stdout=self.redir3
def go3(self, edit):
sys.stderr.write("go3 printing\n")
print "do something"
def OnClose(self, e):
self.Close(True)
class MyFileDropTarget(wx.FileDropTarget):
""""""
def __init__(self, window):
wx.FileDropTarget.__init__(self)
self.window = window
def OnDropFiles(self, x, y, filenames):
self.window.notify(filenames)
class RedirectText:
def __init__(self,aWxTextCtrl):
self.out=aWxTextCtrl
def write(self,string):
self.out.WriteText(string)
app = wx.App()
ScrolledWindow(None, -1, 'Application')
app.MainLoop()
Note the trouble that you have to go to to do some simple debugging, because you have hijacked stdout. I still strongly recommend you find a better way to do this, when you come to actually completing your application, once you have satisfied yourself with this experiment. It is not robust or maintainable doing it the way that you are doing it. Other evidence for this is the need for globals: a big warning sign that your code will become fragile and hard to maintain.
Upvotes: 1