تشغيل أوامر النظام في Python باستخدام اللعنات واللوحة ، والعودة إلى القائمة السابقة

StackOverflow https://stackoverflow.com/questions/19833315

سؤال

أقوم بترميز برنامج نصي Python باستخدام العديد من أدوات Commanline مثل Top ، لذلك أحتاج إلى ردود فعل مرئية مناسبة. حان الوقت الآن لإعطائها قائمة ، لذلك تأتي المشكلة.

لقد وجدت هنا نهجًا رائعًا ما أحتاجه ، ولكن كل محاولة لعرض ملاحظات قبل العودة إلى القائمة السابقة غير مجدية.

أنا فقط بحاجة إلى قوائم ، وقائمة فرعية ، وأوامر الإطلاق ، وإنهائها ، والعودة إلى القائمة السابقة. ستكون مكافأة رائعة لتشغيلها في تقسيم المصطلح.

هل هناك أي نمط/هيكل عظمي/أشياء/أي شيء يجب استخدامه كقالب من أجل عرض عدة أنواع من القطعة مع إخراج يمكن التنبؤ به؟

فيما يلي مثال على التعليمات البرمجية ، وهو مثالان على التشغيل:

#!/usr/bin/env python2                                                       

import curses                                                                
from curses import panel                                                     

class Menu(object):                                                          

    def __init__(self, items, stdscreen):                                    
        self.window = stdscreen.subwin(0,0)                                  
        self.window.keypad(1)                                                
        self.panel = panel.new_panel(self.window)                            
        self.panel.hide()                                                    
        panel.update_panels()                                                

        self.position = 0                                                    
        self.items = items                                                   
        self.items.append(('exit','exit'))                                   

    def navigate(self, n):                                                   
        self.position += n                                                   
        if self.position < 0:                                                
            self.position = 0                                                
        elif self.position >= len(self.items):                               
            self.position = len(self.items)-1                                

    def display(self):                                                       
        self.panel.top()                                                     
        self.panel.show()                                                    
        self.window.clear()                                                  

        while True:                                                          
            self.window.refresh()                                            
            curses.doupdate()                                                
            for index, item in enumerate(self.items):                        
                if index == self.position:                                   
                    mode = curses.A_REVERSE                                  
                else:                                                        
                    mode = curses.A_NORMAL                                   

                msg = '%d. %s' % (index, item[0])                            
                self.window.addstr(1+index, 1, msg, mode)                    

            key = self.window.getch()                                        

            if key in [curses.KEY_ENTER, ord('\n')]:                         
                if self.position == len(self.items)-1:                       
                    break                                                    
                else:                                                        
                    self.items[self.position][1]()                           

            elif key == curses.KEY_UP:                                       
                self.navigate(-1)                                            

            elif key == curses.KEY_DOWN:                                     
                self.navigate(1)                                             

        self.window.clear()                                                  
        self.panel.hide()                                                    
        panel.update_panels()                                                
        curses.doupdate()

######################################################### !# 
######################################################### !#    
############# HERE MY FUNCTIONS examples
############  Everithing works OK, but displays it awfully

def GetPid(name):
    import subprocess
    command= str(("""pgrep %s""") % name )
    p = subprocess.Popen(command, shell = True, stdout = subprocess.PIPE)
    procs = []
    salida = p.stdout
    for line in salida:
        procs.append(str.strip(line))

    return procs


def top():
    os.system("top")    

def menuGP():
    print GetPid("top")  


######################################################### !# 

class MyApp(object):                                                         

    def __init__(self, stdscreen):                                           
        self.screen = stdscreen                                              
        curses.curs_set(0)                                                   

        submenu_items = [                                                    
                ('beep', curses.beep),                                       
                ('top', top)                                      
                ]                                                            
        submenu = Menu(submenu_items, self.screen)                           

        main_menu_items = [                                                  
                ('get PID', GetPid),                                       
                ('submenu', submenu.display)                                 
                ]                                                            
        main_menu = Menu(main_menu_items, self.screen)                       
        main_menu.display()                                                  

if __name__ == '__main__':                                                       
    curses.wrapper(MyApp)

شكرا في المشورة (وآسف على لغتي الإنجليزية القاسية)

هل كانت مفيدة؟

المحلول

لديك حقا خياران. واحد يمكنك ترك وضع اللعنات ، وتنفيذ البرنامج ، ثم استئناف اللعنات. ثانياً ، يمكنك تنفيذ برنامجك بشكل غير متزامن ، وتحليل إخراجه واكتبه على الشاشة.

الأخبار السارة حول الخيار الأول هي أنك لا تحتاج فعليًا إلى كتابة أي طرق Fancy_State / Load_State لواجهة المستخدم. لعنات تفعل هذا من أجلك. إليك مثال بسيط لإظهار وجهة نظري

import curses, time, subprocess

class suspend_curses():
    """Context Manager to temporarily leave curses mode"""

    def __enter__(self):
        curses.endwin()

    def __exit__(self, exc_type, exc_val, tb):
        newscr = curses.initscr()
        newscr.addstr('Newscreen is %s\n' % newscr)
        newscr.refresh()
        curses.doupdate()

def main(stdscr):
    stdscr.addstr('Stdscreen is %s\n' % stdscr)
    stdscr.refresh()
    time.sleep(1)

    with suspend_curses():
        subprocess.call(['ls'])
        time.sleep(1)

    stdscr.refresh()
    time.sleep(5)

curses.wrapper(main)

إذا قمت بتشغيل المثال ، ستلاحظ أن الشاشة التي تم إنشاؤها بواسطة curses.wrapper وتلك التي تم إنشاؤها في curses.initscr عند الاستئناف هي نفس الكائن. وهذا هو ، النافذة التي تم إرجاعها curses.initscr هو المفرد. هذا يتيح لنا الخروج من اللعنات واستئنافًا كما أعلاه دون الحاجة إلى تحديث كل عنصر واجهة مستخدم self.screen المراجع في كل مرة.

الخيار الثاني أكثر مشاركة ولكن أيضًا أكثر مرونة. فيما يلي فقط لتمثيل الفكرة الأساسية.

class procWidget():
    def __init__(self, stdscr):
        # make subwindow / panel
        self.proc = subprocess.Popen(my_args, stdout=subprocess.PIPE)

    def update(self):
        data = self.proc.stdout.readline()
        # parse data as necessary
        # call addstr() and refresh()

ثم في مكان ما في برنامجك سترغب في الاتصال update على كل procwidgets الخاصة بك على مؤقت. يمنحك هذا خيار جعل الرياح الفرعية الخاصة بك أي حجم/مكان حتى تتمكن من الحصول على أكبر عدد ممكن من procwidgets. سيتعين عليك إضافة بعض المعالجة عندما تنتهي العملية وغيرها من الأحداث المماثلة بالطبع.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top