无法退出wxpython

时间:2016-03-08 20:02:52

标签: python python-2.7 user-interface wxpython

所以我想我知道我的问题是什么,但我似乎无法弄清楚如何解决它。我对wxPython比较陌生。我正在将终端脚本中的一些功能移动到GUI,似乎无法正确使用它。我使用anaconda进行python发布,并为GUI添加了wxPython。我希望用户能够将文件拖放到文本控件中,然后将文件内容导入到数据框中以便使用pandas进行分析。到目前为止一切都很开心。除了程序不会退出的事实。我认为这与我如何定义窗口和框架有关。我已从脚本中删除了大量功能,以帮助简化操作。请让我知道我错过了什么。

由于 泰勒

import wx
import os
#import pandas as pd
#import numpy as np
#import matplotlib.pyplot as ply
#from scipy.stats import linregress

class MyFileDropTarget(wx.FileDropTarget):

    #----------------------------------------------------------------------
    def __init__(self, window):
        wx.FileDropTarget.__init__(self)
        self.window = window

    #----------------------------------------------------------------------
    def OnDropFiles(self, x, y, filenames):
        self.window.SetInsertionPointEnd(y)
        #self.window.updateText("\n%d file(s) dropped at %d,%d:\n" %
        #                   (len(filenames), x, y), y)
        for filepath in filenames:
            self.window.updateText(filepath + '\n', y)  

class MainWindow(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title=title, size=(200,100))
        file_drop_target = MyFileDropTarget(self)
        self.CreateStatusBar() # A Statusbar in the bottom of the window

        # Creating the menubar.
        menubar = wx.MenuBar()
        fileMenu = wx.Menu()
        helpMenu = wx.Menu()

        menubar.Append(fileMenu, '&File')
        menuOpen = fileMenu.Append(wx.ID_OPEN, "&Open"," Open a file to edit")
        #self.Bind(wx.EVT_MENU, self.OnOpen, menuOpen)
        fileMenu.AppendSeparator()
        menuExit = fileMenu.Append(wx.ID_EXIT,"E&xit"," Terminate the program")
        self.Bind(wx.EVT_MENU, self.OnExit, menuExit)

        menubar.Append(helpMenu, '&Help')
        menuAbout= helpMenu.Append(wx.ID_ABOUT, "&About"," Information about this program")
        self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout)

        self.SetMenuBar(menubar)

        #Create some sizers
        mainSizer = wx.BoxSizer(wx.VERTICAL)
        grid = wx.GridBagSizer(hgap=5, vgap=5)
        hSizer = wx.BoxSizer(wx.HORIZONTAL)

        #Create a button
        self.button = wx.Button(self, label="Test")
        #self.Bind(wx.EVT_BUTTON, self.OnClick,self.button)

        # Radio Boxes
        sysList = ['QEXL','QEX10','QEX7']
        wlList = ['1100', '1400', '1800']
        sys = wx.RadioBox(self, label="What system are you calibrating ?", pos=(20, 40), choices=sysList,  majorDimension=3,
                        style=wx.RA_SPECIFY_COLS)
        grid.Add(sys, pos=(1,0), span=(1,3))

        WL = wx.RadioBox(self, label="Maximum WL you currently Calibrating ?", pos=(20, 100), choices=wlList,  majorDimension=0,
                        style=wx.RA_SPECIFY_COLS)
        grid.Add(WL, pos=(2,0), span=(1,3))


        self.lblname = wx.StaticText(self, label="Cal File 1 :")
        grid.Add(self.lblname, pos=(3,0))
        self.Cal_1 = wx.TextCtrl(self, name="Cal_1", value="", size=(240,-1))
        self.Cal_1.SetDropTarget(file_drop_target)
        grid.Add(self.Cal_1, pos=(3,1))

        self.lblname = wx.StaticText(self, label="Cal File 2 :")
        grid.Add(self.lblname, pos=(4,0))
        self.Cal_2 = wx.TextCtrl(self, value="", name="Cal_2", size=(240,-1))
        self.Cal_2.SetDropTarget(file_drop_target)
        grid.Add(self.Cal_2, pos=(4,1))

        self.lblname = wx.StaticText(self, label="Cal File 3 :")
        grid.Add(self.lblname, pos=(5,0))
        self.Cal_3 = wx.TextCtrl(self, value="", name="Cal_3", size=(240,-1))
        self.Cal_3.SetDropTarget(file_drop_target)
        grid.Add(self.Cal_3, pos=(5,1))

        hSizer.Add(grid, 0, wx.ALL, 5)

        mainSizer.Add(hSizer, 0, wx.ALL, 5)
        mainSizer.Add(self.button, 0, wx.CENTER)
        self.SetSizerAndFit(mainSizer)


        self.Show(True)

    def OnAbout(self,e):
        # A message dialog box with an OK button. wx.OK is a standard ID in wxWidgets.
        dlg = wx.MessageDialog( self, "A quick test to see if your scans pass repeatability", "DOMA-64 Tester", wx.OK)
        dlg.ShowModal() # Show it
        dlg.Destroy() # finally destroy it when finished.

    def OnExit(self,e):
        # Close the frame.
        self.Close(True)

    def SetInsertionPointEnd(self, y):
        if y <= -31:
            self.Cal_1.SetInsertionPointEnd()
        elif y >= -1:
            self.Cal_3.SetInsertionPointEnd()
        else:
            self.Cal_2.SetInsertionPointEnd()

    def updateText(self, text, y):
        if y <= -31:
            self.Cal_1.WriteText(text)
        elif y >= -1:
            self.Cal_3.WriteText(text)
        else:
            self.Cal_2.WriteText(text)  

app = wx.App(False)
frame = MainWindow(None, "Sample editor")
app.MainLoop()

2 个答案:

答案 0 :(得分:0)

问题是您只创建一个MyFileDropTarget类的实例,然后将该同一个对象分配给多个小部件。看起来您需要为每个小部件创建一个放置目标实例。我稍微重构了你的代码,但这是一种方法:

import wx
import os
#import pandas as pd
#import numpy as np
#import matplotlib.pyplot as ply
#from scipy.stats import linregress

class MyFileDropTarget(wx.FileDropTarget):

    #----------------------------------------------------------------------
    def __init__(self, window):
        wx.FileDropTarget.__init__(self)
        self.window = window

    #----------------------------------------------------------------------
    def OnDropFiles(self, x, y, filenames):
        self.window.SetInsertionPointEnd(y)
        #self.window.updateText("\n%d file(s) dropped at %d,%d:\n" %
        #                   (len(filenames), x, y), y)
        for filepath in filenames:
            self.window.updateText(filepath + '\n', y)


class MyPanel(wx.Panel):

    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        file_drop_target = MyFileDropTarget(self)
        file_drop_target2 = MyFileDropTarget(self)
        file_drop_target3 = MyFileDropTarget(self)

        #Create some sizers
        mainSizer = wx.BoxSizer(wx.VERTICAL)
        grid = wx.GridBagSizer(hgap=5, vgap=5)
        hSizer = wx.BoxSizer(wx.HORIZONTAL)

        #Create a button
        self.button = wx.Button(self, label="Test")
        #self.Bind(wx.EVT_BUTTON, self.OnClick,self.button)

        # Radio Boxes
        sysList = ['QEXL','QEX10','QEX7']
        wlList = ['1100', '1400', '1800']
        sys = wx.RadioBox(self, label="What system are you calibrating ?", 
                          pos=(20, 40), choices=sysList,  majorDimension=3,
                          style=wx.RA_SPECIFY_COLS)
        grid.Add(sys, pos=(1,0), span=(1,3))

        WL = wx.RadioBox(self, label="Maximum WL you currently Calibrating ?",
                         pos=(20, 100), choices=wlList,  majorDimension=0,
                         style=wx.RA_SPECIFY_COLS)
        grid.Add(WL, pos=(2,0), span=(1,3))


        self.lblname = wx.StaticText(self, label="Cal File 1 :")
        grid.Add(self.lblname, pos=(3,0))
        self.Cal_1 = wx.TextCtrl(self, name="Cal_1", value="", size=(240,-1))
        self.Cal_1.SetDropTarget(file_drop_target)
        grid.Add(self.Cal_1, pos=(3,1))

        self.lblname = wx.StaticText(self, label="Cal File 2 :")
        grid.Add(self.lblname, pos=(4,0))
        self.Cal_2 = wx.TextCtrl(self, value="", name="Cal_2", size=(240,-1))
        self.Cal_2.SetDropTarget(file_drop_target2)
        grid.Add(self.Cal_2, pos=(4,1))

        self.lblname = wx.StaticText(self, label="Cal File 3 :")
        grid.Add(self.lblname, pos=(5,0))
        self.Cal_3 = wx.TextCtrl(self, value="", name="Cal_3", size=(240,-1))
        self.Cal_3.SetDropTarget(file_drop_target3)
        grid.Add(self.Cal_3, pos=(5,1))

        hSizer.Add(grid, 0, wx.ALL, 5)

        mainSizer.Add(hSizer, 0, wx.ALL, 5)
        mainSizer.Add(self.button, 0, wx.CENTER)
        self.SetSizer(mainSizer)



class MainWindow(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title=title, size=(400,400))
        panel = MyPanel(self)

        self.CreateStatusBar() # A Statusbar in the bottom of the window

        # Creating the menubar.
        menubar = wx.MenuBar()
        fileMenu = wx.Menu()
        helpMenu = wx.Menu()

        menubar.Append(fileMenu, '&File')
        menuOpen = fileMenu.Append(wx.ID_OPEN, "&Open"," Open a file to edit")
        #self.Bind(wx.EVT_MENU, self.OnOpen, menuOpen)
        fileMenu.AppendSeparator()
        menuExit = fileMenu.Append(wx.ID_EXIT,"E&xit"," Terminate the program")
        self.Bind(wx.EVT_MENU, self.OnExit, menuExit)

        menubar.Append(helpMenu, '&Help')
        menuAbout= helpMenu.Append(wx.ID_ABOUT, "&About",
                                   " Information about this program")
        self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout)

        self.SetMenuBar(menubar)

        self.Show(True)

    def OnAbout(self,e):
        # A message dialog box with an OK button. wx.OK is a standard ID in wxWidgets.
        dlg = wx.MessageDialog( self, "A quick test to see if your scans pass repeatability", "DOMA-64 Tester", wx.OK)
        dlg.ShowModal() # Show it
        dlg.Destroy() # finally destroy it when finished.

    def OnExit(self,e):
        # Close the frame.
        #del self.fdt
        self.Close(True)





app = wx.App(False)
frame = MainWindow(None, "Sample editor")
app.MainLoop()

更新2016.03.09 - 我决定发布OP解决方案的重构版本:

import wx
import os
#import pandas as pd
#import numpy as np
#import matplotlib.pyplot as ply
#from scipy.stats import linregress

class MyFileDropTarget(wx.FileDropTarget):

    #----------------------------------------------------------------------
    def __init__(self, obj):
        wx.FileDropTarget.__init__(self)
        self.obj = obj

    #----------------------------------------------------------------------
    def OnDropFiles(self, x, y, filenames):
        #self.obj.SetInsertionPointEnd(y)
        #self.obj.WriteText("\n%d file(s) dropped at %d,%d:\n" %
        #                   (len(filenames), x, y))
        for filepath in filenames:
            self.obj.WriteText(filepath + '\n')


class MyPanel(wx.Panel):

    def __init__(self, parent):
        wx.Panel.__init__(self, parent)

        #Create some sizers
        mainSizer = wx.BoxSizer(wx.VERTICAL)
        grid = wx.GridBagSizer(hgap=5, vgap=5)
        hSizer = wx.BoxSizer(wx.HORIZONTAL)

        #Create a button
        self.button = wx.Button(self, label="Test")
        #self.Bind(wx.EVT_BUTTON, self.OnClick,self.button)

        # Radio Boxes
        sysList = ['QEXL','QEX10','QEX7']
        wlList = ['1100', '1400', '1800']
        sys = wx.RadioBox(self, label="What system are you calibrating ?",
                        pos=(20, 40), choices=sysList,  majorDimension=3,
                        style=wx.RA_SPECIFY_COLS)
        grid.Add(sys, pos=(1,0), span=(1,3))

        WL = wx.RadioBox(self, label="Maximum WL you currently Calibrating ?",
                        pos=(20, 100), choices=wlList,  majorDimension=0,
                        style=wx.RA_SPECIFY_COLS)
        grid.Add(WL, pos=(2,0), span=(1,3))

        x = 3
        for widget in range(1, 4):
            lbl = wx.StaticText(self, label="Cal File {} :".format(widget))
            grid.Add(lbl, pos=(x,0))
            txt = wx.TextCtrl(self, name="Cal_{}".format(widget),
                                     value="", size=(240,-1))
            dt = MyFileDropTarget(txt)
            txt.SetDropTarget(dt)
            grid.Add(txt, pos=(x,1))
            x += 1

        hSizer.Add(grid, 0, wx.ALL, 5)

        mainSizer.Add(hSizer, 0, wx.ALL, 5)
        mainSizer.Add(self.button, 0, wx.CENTER)
        self.SetSizer(mainSizer)


class MainWindow(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title=title, size=(400,400))
        panel = MyPanel(self)

        self.CreateStatusBar() # A Statusbar in the bottom of the window

        # Creating the menubar.
        menubar = wx.MenuBar()
        fileMenu = wx.Menu()
        helpMenu = wx.Menu()

        menubar.Append(fileMenu, '&File')
        menuOpen = fileMenu.Append(wx.ID_OPEN, "&Open"," Open a file to edit")
        #self.Bind(wx.EVT_MENU, self.OnOpen, menuOpen)
        fileMenu.AppendSeparator()
        menuExit = fileMenu.Append(wx.ID_EXIT,"E&xit"," Terminate the program")
        self.Bind(wx.EVT_MENU, self.OnExit, menuExit)

        menubar.Append(helpMenu, '&Help')
        menuAbout= helpMenu.Append(wx.ID_ABOUT, "&About",
                                " Information about this program")
        self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout)

        self.SetMenuBar(menubar)

        self.Show(True)

    def OnAbout(self,e):
        # A message dialog box with an OK button. wx.OK is a standard ID in wxWidgets.
        dlg = wx.MessageDialog( self, "A quick test to see if your scans pass repeatability", "DOMA-64 Tester", wx.OK)
        dlg.ShowModal() # Show it
        dlg.Destroy() # finally destroy it when finished.

    def OnExit(self,e):
        # Close the frame.
        #del self.fdt
        self.Close(True)


app = wx.App(False)
frame = MainWindow(None, "Sample editor")
app.MainLoop()

请注意,您可以使用循环来创建标签和文本小部件。

答案 1 :(得分:0)

迈克,你的解决方案真的帮助了我,谢谢你。虽然它解决了窗口没有关闭的问题,但却导致了引入文件并显示其名称的问题。我修改了你提供的代码,以便它可以为我工作,并在这里发布,以防其他人有类似的问题。它不是最优雅的解决方案,但它有效。再次感谢。

import wx
import os
#import pandas as pd
#import numpy as np
#import matplotlib.pyplot as ply
#from scipy.stats import linregress

class MyFileDropTarget(wx.FileDropTarget):

    #----------------------------------------------------------------------
    def __init__(self, obj):
        wx.FileDropTarget.__init__(self)
        self.obj = obj

    #----------------------------------------------------------------------
    def OnDropFiles(self, x, y, filenames):
        #self.obj.SetInsertionPointEnd(y)
        #self.obj.WriteText("\n%d file(s) dropped at %d,%d:\n" %
        #                   (len(filenames), x, y))
        for filepath in filenames:
            self.obj.WriteText(filepath + '\n')


class MyPanel(wx.Panel):

    def __init__(self, parent):
        wx.Panel.__init__(self, parent)

        #Create some sizers
        mainSizer = wx.BoxSizer(wx.VERTICAL)
        grid = wx.GridBagSizer(hgap=5, vgap=5)
        hSizer = wx.BoxSizer(wx.HORIZONTAL)

        #Create a button
        self.button = wx.Button(self, label="Test")
        #self.Bind(wx.EVT_BUTTON, self.OnClick,self.button)

        # Radio Boxes
        sysList = ['QEXL','QEX10','QEX7']
        wlList = ['1100', '1400', '1800']
        sys = wx.RadioBox(self, label="What system are you calibrating ?", 
                        pos=(20, 40), choices=sysList,  majorDimension=3,
                        style=wx.RA_SPECIFY_COLS)
        grid.Add(sys, pos=(1,0), span=(1,3))

        WL = wx.RadioBox(self, label="Maximum WL you currently Calibrating ?",
                        pos=(20, 100), choices=wlList,  majorDimension=0,
                        style=wx.RA_SPECIFY_COLS)
        grid.Add(WL, pos=(2,0), span=(1,3))


        self.lblname = wx.StaticText(self, label="Cal File 1 :")
        grid.Add(self.lblname, pos=(3,0))
        self.Cal_1 = wx.TextCtrl(self, name="Cal_1", value="", size=(240,-1))
        Cal1 = MyFileDropTarget(self.Cal_1)
        self.Cal_1.SetDropTarget(Cal1)
        grid.Add(self.Cal_1, pos=(3,1))

        self.lblname = wx.StaticText(self, label="Cal File 2 :")
        grid.Add(self.lblname, pos=(4,0))
        self.Cal_2 = wx.TextCtrl(self, value="", name="Cal_2", size=(240,-1))
        Cal2 = MyFileDropTarget(self.Cal_2)
        self.Cal_2.SetDropTarget(Cal2)
        grid.Add(self.Cal_2, pos=(4,1))

        self.lblname = wx.StaticText(self, label="Cal File 3 :")
        grid.Add(self.lblname, pos=(5,0))
        self.Cal_3 = wx.TextCtrl(self, value="", name="Cal_3", size=(240,-1))
        Cal3 = MyFileDropTarget(self.Cal_3)
        self.Cal_3.SetDropTarget(Cal3)
        grid.Add(self.Cal_3, pos=(5,1))

        hSizer.Add(grid, 0, wx.ALL, 5)

        mainSizer.Add(hSizer, 0, wx.ALL, 5)
        mainSizer.Add(self.button, 0, wx.CENTER)
        self.SetSizer(mainSizer)


class MainWindow(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title=title, size=(400,400))
        panel = MyPanel(self)

        self.CreateStatusBar() # A Statusbar in the bottom of the window

        # Creating the menubar.
        menubar = wx.MenuBar()
        fileMenu = wx.Menu()
        helpMenu = wx.Menu()

        menubar.Append(fileMenu, '&File')
        menuOpen = fileMenu.Append(wx.ID_OPEN, "&Open"," Open a file to edit")
        #self.Bind(wx.EVT_MENU, self.OnOpen, menuOpen)
        fileMenu.AppendSeparator()
        menuExit = fileMenu.Append(wx.ID_EXIT,"E&xit"," Terminate the program")
        self.Bind(wx.EVT_MENU, self.OnExit, menuExit)

        menubar.Append(helpMenu, '&Help')
        menuAbout= helpMenu.Append(wx.ID_ABOUT, "&About",
                                " Information about this program")
        self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout)

        self.SetMenuBar(menubar)

        self.Show(True)

    def OnAbout(self,e):
        # A message dialog box with an OK button. wx.OK is a standard ID in wxWidgets.
        dlg = wx.MessageDialog( self, "A quick test to see if your scans pass repeatability", "DOMA-64 Tester", wx.OK)
        dlg.ShowModal() # Show it
        dlg.Destroy() # finally destroy it when finished.

    def OnExit(self,e):
        # Close the frame.
        #del self.fdt
        self.Close(True)


app = wx.App(False)
frame = MainWindow(None, "Sample editor")
app.MainLoop()