0

我一直致力于为命令行程序创建 GUI 前端,我在这里得到的所有帮助都令人惊叹。我永远无法感谢你们。

这是我一直在研究的一个测试程序,它在 Windows 中显示 .CAB 文件的内容:

#!python2.7

import sys
import os
from tkFileDialog import *
from subprocess import *
from Tkinter import *

def getfilename():
    blankline = 0 # counter to help remove blank lines
    filename = askopenfilename(filetypes=[("All files","*"), ("Cab files","*.cab")]) # get the filename
    if filename == "": # if the user hits the Cancel button, don't change anything in the list box
        return
    listbox.delete(0, END) # clear the list box
    numberinlist = 0 # count the number of lines in the list box to delete the extra blank line at the end of the list
    if os.name == 'nt': # send the command without opening a command window
        start_info = subprocess.STARTUPINFO()
        start_info.dwFlags |= subprocess._subprocess.STARTF_USESHOWWINDOW
    commandline = Popen(['expand', '-D', filename], shell=False, stdout=PIPE, stdin=PIPE, stderr=STDOUT, startupinfo=start_info)
    # commend the above 4 lines and uncomment the below line and the program works but opens a command window
    #commandline = Popen(['expand', '-D', filename], shell=False, stdout=PIPE, stdin=PIPE, stderr=STDOUT)
    while True: # read expand.exe's output and strip undeeded characters at the end of each line
        listboxline = commandline.stdout.readline().rstrip()
        listbox.insert(END, listboxline)
        numberinlist += 1
        if len(listboxline) ==0: # check for blank lines
            blankline += 1
            if blankline == 3: # expand.exe sends an extra three blank lines, see if it's the third blank line
                listbox.delete(numberinlist - 1) # if it is the third blank line remove the extra line at the end
                break # quit the while loop, expand.exe is finished after the third blank line

# set up the window    
mywindow = Tk()
mywindow.geometry('400x400')

# add a frame to position the list box in
frame1 = Frame(mywindow)
frame1.pack(fill=BOTH, expand=1)

# name the scroll bars
vertscrollbar = Scrollbar(frame1, orient=VERTICAL)
horzscrollbar = Scrollbar(frame1, orient=HORIZONTAL)

# name the list box and attach the scroll bars
listbox = Listbox(frame1, selectmode=EXTENDED, yscrollcommand=vertscrollbar.set, xscrollcommand=horzscrollbar.set)
vertscrollbar.config(command=listbox.yview)
horzscrollbar.config(command=listbox.xview)

# create the scroll bars and list box
vertscrollbar.pack(side=RIGHT, fill=Y)
horzscrollbar.pack(side=BOTTOM, fill=X)
listbox.pack(side=LEFT, fill=BOTH, expand=1)

# add another frame to position the button in
frame2 = Frame(mywindow)
frame2.pack(fill=X)

# create the button and tell it to go to the getfilename function when clicked
filebutton = Button(frame2, text="Open cab file", command=getfilename)
filebutton.pack()

# start the GUI
mywindow.mainloop()

我添加了很多评论,所以如果有人正在寻找不同问题的答案,他们可能会在这个程序示例中找到答案。这个想法是将'expand.exe -D'的结果逐行显示到列表框中,而不弹出Windows,命令行,shell窗口,而是将其保留在后台。从第一行 (shebang) 可以看出,我使用的是 Python 2.7。我遇到的问题是我收到了错误:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 1410, in __call__
    return self.func(*args)
  File "D:\Python\2.7\listcab.pyw", line 17, in getfilename
    start_info = subprocess.STARTUPINFO()
NameError: global name 'subprocess' is not defined

我一直在搜索 stackoverflow 和 Google 以查找此错误,但我一直找不到任何东西。我确定这是我的导入列表的一个简单问题,但我不知道它是什么。我仍然没有完全理解 Python 的不同导入命令,使用哪些,何时使用它们以及它们之间的区别是什么。

4

1 回答 1

2

由于您使用了星形导入...

from subprocess import *

您不应该为从中导入的内容添加前缀:

subprocess.STARTUPINFO()

其实应该只是...

STARTUPINFO()

如果你想使用前缀,你只想做......

import subprocess

它不是将所有名称从subprocess全局命名空间导入,而是导入subprocess自身,然后让您使用其名称和前缀。

然后你会使用像subprocess.Popen(), subprocess.STARTUPINFO(), 等等这样的东西。

这通常被认为是进行导入的首选方式;如果两个不同的模块具有类似命名的函数,它可以避免名称冲突,并使事物的来源更加清晰。

于 2013-01-27T18:48:06.520 回答