关于从wxPython代码中使用py2exe生成的可执行文件

关于从wxPython代码中使用py2exe生成的可执行文件,python,wxpython,py2exe,Python,Wxpython,Py2exe,我已经从我的真实世界应用程序创建了一个示例应用程序。我使用过wxPython 3.0、python 2.7和windows 7 64位操作系统。 这个应用程序很简单。这是一个带有文本字段的GUI,您可以在其中输入IP地址,然后单击按钮,将进行10次nslookup查询。gui.py包含gui代码,lookup.py将包含nslookup过程代码。所有这些之后,我使用py2exe创建了一个可执行文件。我也成功地创建了一个可执行文件 问题:当我执行新创建的可执行文件时,当我的应用程序运行并执行nsl

我已经从我的真实世界应用程序创建了一个示例应用程序。我使用过wxPython 3.0、python 2.7和windows 7 64位操作系统。 这个应用程序很简单。这是一个带有文本字段的GUI,您可以在其中输入IP地址,然后单击按钮,将进行10次nslookup查询。
gui.py
包含gui代码,
lookup.py
将包含nslookup过程代码。所有这些之后,我使用
py2exe
创建了一个可执行文件。我也成功地创建了一个可执行文件

问题:当我执行新创建的可执行文件时,当我的应用程序运行并执行nslookup查询时,cmd控制台也会出现/闪烁!为什么会发生这种情况以及如何避免这种情况?但是,如果我通过键入
gui.py
并点击enter键通过cmd执行我的应用程序,则在nslookup过程中不会出现任何cmd窗口

代码:可下载所有代码和新创建的可执行文件,以避免任何识别问题。如有任何建议,将不胜感激

gui.py

# -*- coding: utf-8 -*-
import wx
from wx.lib.pubsub import setupkwargs
from wx.lib.pubsub import pub as Publisher
from threading import Thread
import threading
import socket
import os
import sys

from lookup import checker

class GUI(wx.Frame):
    def __init__(self):
        filePath = ''
        wx.Frame.__init__(self, None, wx.ID_ANY, "test v1.0", style = wx.DEFAULT_FRAME_STYLE,size=(550,250))
        self.Center()
        self.CreateStatusBar()
        self.mainPanel = mainPanel = wx.Panel(self, -1)
        self.mainPanel.SetBackgroundColour('#EEEEEE')
        mainSizer = wx.BoxSizer(wx.VERTICAL)
        self.myFont = myFont = wx.Font(11, wx.MODERN, wx.NORMAL, wx.NORMAL, False,  "Arial")
        boldFont = wx.Font(11, wx.MODERN, wx.NORMAL, wx.BOLD, False,  "Arial")
        ipPanel = wx.Panel(mainPanel, -1, style=wx.BORDER)
        iptextSizer = wx.BoxSizer(wx.VERTICAL)
        iptitleText = wx.StaticText(ipPanel, -1, 'Please enter the IP and click the Check IP button to proceed!')
        iptitleText.SetFont(myFont)
        iptitleText.SetForegroundColour(wx.BLUE)
        iptextSizer.Add(iptitleText, 0, wx.TOP|wx.EXPAND, 10)
        ipText = wx.StaticText(ipPanel, -1, 'IP adddress: ')
        ipText.SetFont(myFont)
        ipTextCtrl = self.ipTextCtrl = wx.TextCtrl(ipPanel, -1, style = wx.TE_RICH, size=(303,24), name='ipTextCtrl')
        ipTextCtrl.SetFont(boldFont)
        ipTextCtrl.SetBackgroundColour('#FBFE99')
        ipTextCtrl.SetMaxLength(15)
        ipTextCtrl.Bind(wx.EVT_LEFT_DOWN, self.onClick)
        ipTextCtrl.SetToolTip(wx.ToolTip("Please enter the IP address here."))
        self.ipButton = ipButton = wx.Button(ipPanel, -1, 'Check IP', size=(98,35), name='ipButton')
        ipButton.Bind(wx.EVT_LEFT_DOWN, self.onClick)
        ipButton.SetFont(myFont)
        ipButton.SetForegroundColour('#D6FDE2')
        ipButton.SetBackgroundColour('#05C354')
        ipButton.SetToolTip(wx.ToolTip("Click to start the lookup process."))
        ipSizer = wx.BoxSizer(wx.HORIZONTAL)
        ipSizer.AddSpacer(10)
        ipSizer.Add(ipText, 0, wx.TOP, 11)
        ipSizer.Add(ipTextCtrl, 0, wx.TOP, 9)
        ipSizer.AddSpacer(40)
        ipSizer.Add(ipButton, 0)
        ipSizerMain = wx.BoxSizer(wx.VERTICAL)
        ipSizerMain.Add(iptextSizer, 0, wx.ALL|wx.EXPAND, 5)
        ipSizerMain.Add(ipSizer, 0, wx.ALL|wx.EXPAND, 5)
        ipPanel.SetSizer(ipSizerMain)
        mainsizer = wx.BoxSizer(wx.VERTICAL)
        mainSizerA = wx.BoxSizer(wx.HORIZONTAL)
        mainSizerA.Add(ipPanel, 1, wx.ALL, 2)
        mainSizer.AddSpacer(10)
        mainSizer.Add(mainSizerA, 0, wx.EXPAND)
        mainPanel.SetSizer(mainSizer)
        mainPanel.Layout()

    def logger(self, result):
        if result:
            pass
        else:
            self.ipButton.SetLabel('Check IP')
            self.ipButton.SetForegroundColour('#D6FDE2')
            self.ipButton.SetBackgroundColour('#05C354')
            self.iplistButton.SetLabel('Check IP List')
            self.browseButton.SetLabel('Browse IP List')
            self.browseButton.SetBackgroundColour('#05C354')
            self.browseButton.SetForegroundColour('#D6FDE2')
            self.ipButton.Enable()
            self.browseButton.Enable()
            self.stopButton.Disable()

    def onClick(self, e):
        widget = e.GetEventObject()
        widgetName = widget.GetName()
        if widgetName == 'ipButton':
            self.IP = self.ipTextCtrl.GetLineText(0)
            threadgetResults = getResults(self.IP, 'IP', None)

class getResults(Thread):
    def __init__(self, IP, code, filePath):
        Thread.__init__(self)
        self.IP = IP
        self.code = code
        self.filePath = filePath
        self.daemon = True
        self.start()
    def run(self):
        if self.code == 'IP':
            blCheckerObj = checker()
            output = blCheckerObj.lookup(self.IP)
        else:
            pass
#---------------------------  MAIN  -------------------------------
if __name__=='__main__':
    app = wx.App()
    frame = GUI().Show()
    app.MainLoop()
lookup.py

import subprocess
import time
import os
import sys
import random

class checker:
    def lookup(self, IP):
        self.IP = IP
        cmd = 'nslookup ' +self.IP
        print ' QUERY: '+cmd+'\n'
        for i in range(0,10):
            p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            self.out, self.err = p.communicate()
            print self.out
            time.sleep(3)
setup.py用于构建可执行文件

from distutils.core import setup
import py2exe

dll_excludes = ['OLEAUT32.dll','USER32.dll','COMCTL32.dll','SHELL32.dll',
                'ole32.dll','MSVCP90.dll','WINMM.dll','WSOCK32.dll',
                'COMDLG32.dll','ADVAPI32.dll','NETAPI32.dll','WS2_32.dll',
                'WINSPOOL.DRV','GDI32.dll','RPCRT4.dll','VERSION.dll',
                'KERNEL32.dll','ntdll.dll']

setup (
    name='Test',
    description="Script to test py2exe for packaging",
    version="0.1",
    windows=['gui.py'],#windows=[{'script': 'gui.py'}],
    platforms=["windows"],
    options={ 'py2exe': {
            'packages': 'encodings, wx.lib.pubsub',
            "excludes": dll_excludes,
            }
        },
    )
py2exe日志

编辑:如果您在执行python脚本时以及在创建可执行文件的过程中观察到cmd控制台窗口的任何闪烁/出现,我将非常感谢您中的任何一位能够测试我的脚本并在此处发布


解决方案:我采纳了来自的建议,最终决定使用模块而不是
nslookup
命令,现在我的问题解决了

将wx.App的实例化更改为以下内容:

app = wx.App(False)
windows=['gui.py']
这告诉wxPython不要将stdout/stderr重定向到窗口。我还认为
setup.py
文件也有错误。尝试将
windows=
行设置为以下值:

app = wx.App(False)
windows=['gui.py']
另见:


尝试了两种选择,但不幸的是没有任何改变。在我的问题中,我提供了py2exe的日志。也许它给你提供了一个线索。在日志中,我看到许多结节和库丢失了。由于我的exe工作正常,我可以忽略这些丢失的东西吗。我想这不是我问题的原因。如果我错了,请更正。您是否尝试删除
lookup.py
中的
print
语句?也可能是因为您在单独的进程中打开nslookup。可以尝试
子流程。调用
而不是
Popen
。或者您可以尝试将stdout重定向到一个文件或类似文件的对象。我尝试删除print语句,还尝试使用subprocess.call而不是popen,但仍然没有任何更改。在执行py2exe创建的可执行文件期间,cmd控制台显示/闪烁。但是当我执行python代码时,cmd控制台不会出现/闪烁。实际上,当我只运行脚本本身时,我看到了闪烁。当我将它构建到可执行文件中时,我也会看到它。我在Windows7上使用wxPython 3,Python 2.7 32位。您可以尝试使用Python模块或包而不是nslookup。例如,您可以使用套接字。看见