Cookbook GUI interface for a command-line script

2019-02-11 00:05发布

问题:

I have a command-line Python script that works well to convert one sort of file into another given a few parameters and would now like to deploy this to some of my colleagues who may not know what a command line is.

I could work for hours trying to determine which Python GUI toolkit is "best", then learning how to do what I need, but it seems like this would have been done before.

Is there a relatively cook-book method to GUIify my program? Direction to either some sort of lesson/tutorial or an existing, documented, concise program would be excellent.

回答1:

Just a quick and simple example which may teach you enough wxPython to get going:

import wx
from subprocess import Popen, PIPE

class MainWindow(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)

        self.panel = wx.Panel(self)
        self.button = wx.Button(self.panel, label="Run!")
        self.command = wx.TextCtrl(self.panel)
        self.result = wx.TextCtrl(self.panel, style=wx.TE_MULTILINE)

        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.command, 0, wx.EXPAND)
        self.sizer.Add(self.button, 0, wx.EXPAND)
        self.sizer.Add(self.result, 1, wx.EXPAND)

        self.command.SetValue("dir")
        self.button.Bind(wx.EVT_BUTTON, self.CallCommand)

        self.panel.SetSizerAndFit(self.sizer)  
        self.Show()

    def CallCommand(self, e):
        p = Popen(self.command.GetValue(), shell=True, 
                  stdin=PIPE, stdout=PIPE, stderr=PIPE)
        r = p.communicate()
        self.result.SetValue(r[0])

app = wx.App(False)
win = MainWindow(None)
app.MainLoop()

To complete the example, following code runs command line in another thread and shows the result line by line:

import wx
from wx.lib.delayedresult import startWorker 
from subprocess import Popen, PIPE

class MainWindow(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)

        self.panel = wx.Panel(self)
        self.button = wx.Button(self.panel, label="Run!")
        self.command = wx.TextCtrl(self.panel)
        self.result = wx.TextCtrl(self.panel, style=wx.TE_MULTILINE)

        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.command, 0, wx.EXPAND)
        self.sizer.Add(self.button, 0, wx.EXPAND)
        self.sizer.Add(self.result, 1, wx.EXPAND)

        self.command.SetValue("dir")
        self.button.Bind(wx.EVT_BUTTON, self.CallCommand)

        self.panel.SetSizerAndFit(self.sizer)  
        self.Show()

    def CallCommand(self, e):
        startWorker(self.WorkCommandDone, self.WorkCommand)

    def WorkCommand(self):
        self.button.Disable()
        p = Popen(self.command.GetValue(), shell=True, 
                  stdin=PIPE, stdout=PIPE, stderr=PIPE)
        while True:
            line = p.stdout.readline()
            if line != '':
                wx.CallAfter(self.result.AppendText, line)
            else:
                break

    def WorkCommandDone(self, result):
        self.button.Enable()

app = wx.App(False)
win = MainWindow(None)
app.MainLoop()


回答2:

There are a few answers advocating wxpython. However, any toolkit will work for this project. Tkinter has the added benefit tha you and your collegues already have it installed and it is very easy to use.

That being said, the other toolkits are more-or-less equally easy to use but you might have to jump through a hoop or two to get them installed. If installation is not an issue it won't matter which one you pick.

Unfortunately, telling you how to "GUIfy" your program is hard since we know nothing about your app. Probably all it will involve is putting up a few labels and input widgets, then creating a button that collects all the data and then runs your program with the subprocess module.



回答3:

Basically you just need to figure out what widgets will hold the data you want the best. I suspect you could use a couple combo boxes to hold different sets of extensions. Or you could just use the path name strings to figure that out. Hit a button and run the conversion process, probably in another thread so the GUI remains responsive.

I'm biased for wxPython. However, you're better off taking a look at their demos and documentation and seeing which GUI toolkit fits your brain the easiest.



回答4:

This depends mostly on your need. If your need is simple, you can just go with tkinter that is bundled with python itself. If you use this, you will not be relying on third party library to implement your GUI. Since you are wanting to make this available for your collegues, this might be easier to compile with py2exe or other similar stuffs to exe which might be tricky if you use third party library for GUI. However, if you want to add more functionality to your GUI, wxpython/pyqt/pyGTK are the GUI toolkit to look for. Personally, I favor wxpython due to its cross-platform nature but pyqt and pyGTK are also equally good as far as I have heard.