Domanda

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()
È stato utile?

Soluzione

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()

Altri suggerimenti

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top