wxPython: как создать окно оболочки удара?

Я склоняюсь к НЕ NULL, если не вижу другой причины - как кто-то сказал, нравится это или нет, NULL - странный особый случай.

Один из моих любимых вариантов в отношении NULL:

SELECT F1 FROM T WHERE F2 <> 'OK'

... который (по крайней мере в DB2) не будет содержать строк, где f2 равен нулю - потому что в реляционном жаргоне, ( NULL <> 'ОК') NULL. Но ваше намерение было вернуть все не-ОК строки. Вам нужен дополнительный предикат ИЛИ, или вместо этого напишите F2 DISTINCT FROM 'OK' (что, в первую очередь, является специальным кодированием).

IMO, NULL - это всего лишь один из тех инструментов программиста, как арифметика указателей или перегрузка операторов, который требует столько же искусства, сколько наука.

Джо Селко пишет об этом в SQL For Smarties - ловушка использования NULL в приложении заключается в том, что его значение, ну, в общем, не определено. Это может означать неизвестный, неинициализированный, неполный, неприменимый - или, как в немом примере выше, означает ли это ОК или не-ОК?

9
задан Bryan Oakley 15 June 2009 в 21:58
поделиться

3 ответа

Я искал, но похоже, что нет никакой завершающей оболочки bash для wxPython хотя модуль wx.py имеет модуль Shell, который предназначен для интерпретатора python хорошо, что вы можете передать ему свой собственный интерпретатор, поэтому я пришел с очень простым интерпретатором bash. пример в настоящее время читает только одну строку из bash stdout, иначе он застрянет, в реальном коде вы должны читать вывод в потоке или использовать select

import wx
import wx.py
from subprocess import Popen, PIPE

class MyInterpretor(object):
    def __init__(self, locals, rawin, stdin, stdout, stderr):
        self.introText = "Welcome to stackoverflow bash shell"
        self.locals = locals
        self.revision = 1.0
        self.rawin = rawin
        self.stdin = stdin
        self.stdout = stdout
        self.stderr = stderr

        #
        self.more = False

        # bash process
        self.bp = Popen('bash', shell=False, stdout=PIPE, stdin=PIPE, stderr=PIPE)


    def getAutoCompleteKeys(self):
        return [ord('\t')]

    def getAutoCompleteList(self, *args, **kwargs):
        return []

    def getCallTip(self, command):
        return ""

    def push(self, command):
        command = command.strip()
        if not command: return

        self.bp.stdin.write(command+"\n")
        self.stdout.write(self.bp.stdout.readline())

app = wx.PySimpleApp()
frame = wx.py.shell.ShellFrame(InterpClass=MyInterpretor)
frame.Show()
app.SetTopWindow(frame)
app.MainLoop()
0
ответ дан 4 December 2019 в 21:51
поделиться

Посмотрим, что я могу придумать.

Но если вы измените свой подумайте и решите использовать pygtk, вот он:

наслаждайтесь !!

EDIT

Я начал делать версию терминала для бедняков, используя виджет управления текстом. Я остановился, потому что есть недостатки, которые нельзя исправить, например, когда вы используете команду sudo.

import wx
import subprocess

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: MyFrame.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)

        self.prompt = "user@stackOvervlow:~ "
        self.textctrl = wx.TextCtrl(self, -1, '', style=wx.TE_PROCESS_ENTER|wx.TE_MULTILINE)
        self.default_txt = self.textctrl.GetDefaultStyle()
        self.textctrl.AppendText(self.prompt)

        self.__set_properties()
        self.__do_layout()
        self.__bind_events()


    def __bind_events(self):
        self.Bind(wx.EVT_TEXT_ENTER, self.__enter)


    def __enter(self, e):
        self.value = (self.textctrl.GetValue())
        self.eval_last_line()
        e.Skip()


    def __set_properties(self):
        self.SetTitle("Poor Man's Terminal")
        self.SetSize((800, 600))
        self.textctrl.SetFocus()

    def __do_layout(self):
        sizer_1 = wx.BoxSizer(wx.VERTICAL)
        sizer_1.Add(self.textctrl, 1, wx.EXPAND, 0)
        self.SetSizer(sizer_1)
        self.Layout()

    def eval_last_line(self):
        nl = self.textctrl.GetNumberOfLines()
        ln =  self.textctrl.GetLineText(nl-1)
        ln = ln[len(self.prompt):]
        args = ln.split(" ")

        proc = subprocess.Popen(args, stdout=subprocess.PIPE)
        retvalue = proc.communicate()[0]

        c = wx.Colour(239, 177, 177)
        tc = wx.TextAttr(c)
        self.textctrl.SetDefaultStyle(tc)
        self.textctrl.AppendText(retvalue)
        self.textctrl.SetDefaultStyle(self.default_txt)
        self.textctrl.AppendText(self.prompt)
        self.textctrl.SetInsertionPoint(GetLastPosition() - 1)

if __name__ == "__main__":
    app = wx.PySimpleApp(0)
    wx.InitAllImageHandlers()
    frame_1 = MyFrame(None, -1, "")
    app.SetTopWindow(frame_1)
    frame_1.Show()
    app.MainLoop()

Если бы действительно захотелось, с этим можно было бы работать.

0
ответ дан 4 December 2019 в 21:51
поделиться

ok here is another try, which reads all output and errors too, in a separate thread and communicates via Queue. I know it is not perfect(e.g. command with delayed output will not work and there output will get into next commnd for example tryr sleep 1; date) and replicating whole bash not trivial but for few commands i tested it seems to work fine

Regarding API of wx.py.shell I just implemented those method which Shell class was calling for Interpreter, if you go thru source code of Shell you will understand. basically

  • push is where user entered command is sent to interpreter
  • getAutoCompleteKeys returns keys which user can user for auto completing commands e.g. tab key
  • getAutoCompleteList return list of command matching given text

  • getCallTip "Display argument spec and docstring in a popup window. so for bash we may show man page :)

here is the source code

import threading
import Queue
import time

import wx
import wx.py
from subprocess import Popen, PIPE

class BashProcessThread(threading.Thread):
    def __init__(self, readlineFunc):
        threading.Thread.__init__(self)

        self.readlineFunc = readlineFunc
        self.outputQueue = Queue.Queue()
        self.setDaemon(True)

    def run(self):
        while True:
            line = self.readlineFunc()
            self.outputQueue.put(line)

    def getOutput(self):
        """ called from other thread """
        lines = []
        while True:
            try:
                line = self.outputQueue.get_nowait()
                lines.append(line)
            except Queue.Empty:
                break
        return ''.join(lines)

class MyInterpretor(object):
    def __init__(self, locals, rawin, stdin, stdout, stderr):
        self.introText = "Welcome to stackoverflow bash shell"
        self.locals = locals
        self.revision = 1.0
        self.rawin = rawin
        self.stdin = stdin
        self.stdout = stdout
        self.stderr = stderr

        self.more = False

        # bash process
        self.bp = Popen('bash', shell=False, stdout=PIPE, stdin=PIPE, stderr=PIPE)

        # start output grab thread
        self.outputThread = BashProcessThread(self.bp.stdout.readline)
        self.outputThread.start()

        # start err grab thread
        self.errorThread = BashProcessThread(self.bp.stderr.readline)
        self.errorThread.start()

    def getAutoCompleteKeys(self):
        return [ord('\t')]

    def getAutoCompleteList(self, *args, **kwargs):
        return []

    def getCallTip(self, command):
        return ""

    def push(self, command):
        command = command.strip()
        if not command: return

        self.bp.stdin.write(command+"\n")
        # wait a bit
        time.sleep(.1)

        # print output
        self.stdout.write(self.outputThread.getOutput())

        # print error
        self.stderr.write(self.errorThread.getOutput())

app = wx.PySimpleApp()
frame = wx.py.shell.ShellFrame(InterpClass=MyInterpretor)
frame.Show()
app.SetTopWindow(frame)
app.MainLoop()
7
ответ дан 4 December 2019 в 21:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: