Printing wxpython打印到选项卡式面板
我试图打印到wxpython中的特定选项卡面板,但我下面的代码似乎打印到第三个(正在运行的作业)选项卡面板窗口,我不知道为什么。我想打印第二个(队列列表)选项卡面板Printing wxpython打印到选项卡式面板,printing,wxpython,tabbed,Printing,Wxpython,Tabbed,我试图打印到wxpython中的特定选项卡面板,但我下面的代码似乎打印到第三个(正在运行的作业)选项卡面板窗口,我不知道为什么。我想打印第二个(队列列表)选项卡面板 import wx import sys global queueList queueList = [] class ScrolledWindow(wx.Frame): def __init__(self, parent, id, title): #global panel1 wx.Fram
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()
原因是在
\uuu init\uuuu()
中调用queue()
后调用running()
,这是在执行某些打印之前重定向stdout的最后一件事
下面是一个版本的代码,当您运行它时,通过输出它正在执行的操作的跟踪,可以使这一点变得明显
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()
请注意,由于您劫持了stdout,因此您必须进行一些简单的调试。我仍然强烈建议,一旦你对这个实验感到满意,当你真正完成你的应用程序时,找到一个更好的方法来做这件事。它不是健壮的或可维护的,以您现在的方式进行操作。这方面的其他证据是对globals的需要:这是一个巨大的警告信号,表明您的代码将变得脆弱且难以维护。正如我在另一个答案中提到的,它不起作用的表面原因是因为存在一个bug:)即编写的逻辑不是预期的。更深层次的原因是该应用程序需要更好的设计。这是一个如何实现的示例 这种设计的主要特点是,它将每个功能的逻辑(每个功能都由用户在笔记本的单独选项卡上携带)划分为不同的类。类通过方法调用进行通信,并且连接在构造时是静态的(例如,对队列管理器的引用在构造时传递给提交控制器) 这绝不是“最好”的设计,它只是一个可能改进的例子——改进减少了在原始设计中难以发现的逻辑错误类型的机会
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()
出于好奇,你为什么要声明TextCtrls是全局的呢?我把一个文件夹拖到放置目标,然后点击“提交”。我没有将任何内容打印到tab3,我收到一条关于队列列表未定义的错误消息。。。。而且(很抱歉被批评)我会努力寻找不同的方法来做这件事,而不是重定向stdout。我认为将stdout作为代码两部分之间的一条路径,将是一件非常脆弱、难以维护、容易出错的事情。。。。。。pubsub可能是一个很好的选择。抱歉,我已经修改了原始问题以显示示例,该示例现在按所述运行,但仍然打印到错误的窗口。感谢GreenAsJade,这是有道理的,但我不确定在这种情况下如何使用pubsub。你能给我指出正确的方向吗?好的,pubsub是一种在不同实体之间匿名通信的好方法(即发送者不需要知道它要去哪里,接收者也不需要知道它来自哪里)。这就是您通过打印实现的目标。但是在你的情况下,这可能不是正确的答案。只有当你的整个应用程序结构更好时,你才会知道,这是第一件要解决的事情。理想情况下,你可以将你的应用程序重组为“模型/视图/控制器”架构或类似的架构。随着你的应用程序的发展,你会从中受益。我会考虑如何在你当前的结构中做到这一点,而你在谷歌MVC:)我很感激你花了这么多时间在这个绿色翡翠上,我将不得不坐下来一点一点地解译它。再次感谢。在应用程序的其余部分,我使用了很多全局的,你提到过这是一种不好的做法吗?这确实是,有很好的理由——不仅仅是“教条”。在上面的例子中,我向您展示了如何在没有全局变量的情况下在代码的各个部分之间进行通信。队列和运行列表之间的通信应该相同。如果还有其他需要沟通的事情,他们应该再次通过方法调用(如上)或通知(pubsub)进行沟通。。。。。现在,我需要将一些其他变量传递到正在运行的类/函数中。开始时,我需要将self.queue值传递给正在运行的类/函数,但我不确定如何进行传递,请您为我指出正确的方向好吗?我想我们正在突破我们在问题/答案/评论中应该讨论的范围。所以我做了一个房间。再见。