2017-10-23 2 views
1

이 예에서는 "df"명령의 출력 결과를 표시하고 "새로 고침"단추를 사용하여 창을 수동으로 새로 고칠 수 있습니다. 다양한 예제와 PyGTK 튜토리얼을 살펴 봤지만 새로 고침 코드를 넣는 정확한 위치는 나를 벗어난다. "freedisk"함수에서 queue_draw를 사용하여 "main"루프의 다른 함수에서 성공없이 시도했습니다.표시 내용은 수동으로 PyGTK에서 새로 고침 (2) (이 단계에서 내가 사용하지 않는 시간 제한)하는 방법을 수동으로 할을 이해하는 문제 PyGTK의 창 창, 또는 일부를 새로 고침, 버전 2</p> <p>I를 갖는

GTK3이 요즘 선호되는 버전입니다.하지만 업데이트하기 전에 차라리이 권한을 얻는 것이 좋습니다.

"freedisk"에 대한 코드 : 다음 간단한 예제를 추가 할 수

#!/usr/bin/env python 

import pango, pygtk, subprocess, re, string, decimal, time 
pygtk.require('2.0') 
import gtk 

def yield_lines(data): 
    for line in data.split("\n"): 
     yield line 

def line_to_list(line): 
    return re.sub(" +", " ", line).split() 

def remov_percent(col): 
    return re.sub("%", "", col) 


class freedisk: 
    def getdiskfree(self): 
     diskfreecmd = ['/usr/bin/df', '-hlT', '-x', 'tmpfs'] 
     diskfree = subprocess.Popen(diskfreecmd, stdout=subprocess.PIPE).communicate()[0] 
     return diskfree 

    def delete_event(self, widget, event, data=None): 
     gtk.main_quit() 
     return False 

    def destroy(self, widget, data=None): 
     gtk.main_quit() 

    def __init__(self): 
     window = gtk.Window(gtk.WINDOW_TOPLEVEL) 
     window.connect("delete_event", self.delete_event) 

     box1 = gtk.VBox(False, 10) 
     box1a = gtk.HBox(False, 0) 
     box2 = gtk.VBox(False, 10) 
     box3 = gtk.HBox(False, 0) 

     frame_1 = gtk.Frame() 

     window.add(box1) 

     diskfreedata = self.getdiskfree() 
     diskfreedata = diskfreedata.replace("Mounted on", "Mounted_on") 

     lines = yield_lines(diskfreedata) 

     headers = line_to_list(lines.next()) 

     columns = [list() for i in range(len(headers))] 

     for i,h in enumerate(headers): 
      columns[i].append(h) 

     for line in lines: 
      for i,l in enumerate(line_to_list(line)): 
       columns[i].append(l) 

     j=0 
     for i in columns[0]: 
      j += 1 

     title = gtk.Label('Disk usage and free space') 
     box1.pack_start(title, False, False, 10) 
     box1.pack_start(box1a, True, True, 0) 
     box1a.pack_start(frame_1, True, True, 20) 
     frame_1.add(box2) 

     ucdiskfreedata = unicode(diskfreedata) 

     label = gtk.Label(diskfreedata) 
     label.set_line_wrap(False) 
     label.set_max_width_chars(80) 
     label.modify_font(pango.FontDescription("monospace")) 

     box_sp1 = gtk.HBox(False, 0) 
     box_sp2 = gtk.HBox(False, 0) 

     refresh_button = gtk.Button("Refresh") 

     close_button = gtk.Button("Close") 
     close_button.connect("clicked", self.delete_event, "quit") 

     mntlabel = [list() for i in range(j)] 
     sizelabel = [list() for i in range(j)] 
     progbar = [list() for i in range(j)] 
     freelabel = [list() for i in range(j)] 
     perlabel = [list() for i in range(j)] 

     rows = [list() for i in range(j)] 

     box2.pack_start(box_sp1, False, False, 0) 

     rows[0] = gtk.HBox(True, 0) 
     box2.pack_start(rows[0], False, False, 5) 

     mntlabel[0] = gtk.Label(columns[6][0]) 
     freelabel[0] = gtk.Label(columns[4][0]) 
     sizelabel[0] = gtk.Label(columns[2][0]) 
     blank = gtk.Label(columns[5][0]) 
     rows[0].pack_start(mntlabel[0], False, False, 0) 
     rows[0].pack_start(sizelabel[0], False, False, 0) 
     rows[0].pack_start(blank, False, False, 0) 
     rows[0].pack_start(freelabel[0], False, False, 0) 

     for i in range(1,j): 
      x = remov_percent(columns[5][i]) 
      y = decimal.Decimal(x)/decimal.Decimal('100') 
      mntlabel[i] = gtk.Label(columns[6][i]) 
      mntlabel[i].set_justify(gtk.JUSTIFY_RIGHT) 
      freelabel[i] = gtk.Label(columns[4][i]) 
      sizelabel[i] = gtk.Label(columns[2][i]) 
      progbar[i] = gtk.ProgressBar() 
      gtk.ProgressBar.set_fraction(progbar[i], y) 
      progbar[i].set_text(str(columns[5][i])) 
      rows[i] = gtk.HBox(True, 0) 
      rows[i].pack_start(mntlabel[i], False, False, 0) 
      rows[i].pack_start(sizelabel[i], False, False, 0) 
      rows[i].pack_start(progbar[i], False, False, 0) 
      rows[i].pack_start(freelabel[i], False, False, 0) 
      box2.pack_start(rows[i], False, False, 0) 

      box2.pack_start(box_sp2, False, False, 10) 

      box3.pack_end(close_button, False, False, 20) 
      box3.pack_end(refresh_button, False, False, 20) 
      box1.pack_start(box3, False, False, 10) 

      box1.show() 
      box1a.show() 
      box2.show() 
      box_sp1.show() 
      box_sp2.show() 
      frame_1.show() 
      title.show() 

      mntlabel[0].show() 
      blank.show() 
      for i in range(0, j): 
       rows[i].show() 
       mntlabel[i].show() 
       sizelabel[i].show() 
       freelabel[i].show() 
      for i in range(1,j): 
       progbar[i].show() 

      refresh_button.show() 
      close_button.show() 
      box3.show() 
      window.show() 


def main(): 
    gtk.main() 

if __name__ == "__main__": 
    freedisk() 
    main() 

편집 (24.10.17), 그냥 "ls"의 명령의 출력을 보여줍니다

#!/usr/bin/env python 

import pango, pygtk, subprocess, re, string, decimal, time 
pygtk.require('2.0') 
import gtk 


class PyGlist: 

    def getlisting(self): 
     listingcmd = ['ls', '-1'] 
     listing = subprocess.Popen(listingcmd, stdout=subprocess.PIPE).communicate()[0] 
     return listing 

    def delete_event(self, widget, event, data=None): 
     gtk.main_quit() 
     return False 

    def destroy(self, widget, data=None): 
     gtk.main_quit() 

    def __init__(self): 
     # nothing here 
     return None 

    def processlisting(self): 
     listingdata = self.getlisting() 
     print (listingdata) 
     loclabel = gtk.Label(listingdata) 
     loclabel.set_line_wrap(False) 
     loclabel.set_max_width_chars(80) 
     loclabel.modify_font(pango.FontDescription("monospace")) 
     return loclabel 

    def refresh(self, widget, data): 
     widget = self.processlisting() 
     widget.queue_draw() 
     return 

    def main(self): 
     window = gtk.Window(gtk.WINDOW_TOPLEVEL) 
     window.connect("delete_event", self.delete_event) 

     box1 = gtk.VBox(False, 10) 
     box1a = gtk.HBox(False, 0) 
     box2 = gtk.VBox(False, 10) 
     box3 = gtk.HBox(False, 0) 
     frame_1 = gtk.Frame() 
     window.add(box1) 

     title = gtk.Label('Listing') 
     box1.pack_start(title, False, False, 10) 
     box1.pack_start(box1a, True, True, 0) 
     box1a.pack_start(frame_1, True, True, 20) 
     frame_1.add(box2) 

     label = self.processlisting() 

     box_sp1 = gtk.HBox(False, 0) 
     box_sp2 = gtk.HBox(False, 0) 

     box2.pack_start(label, False, False, 0) 

     refresh_button = gtk.Button("Refresh") 
     refresh_button.connect("clicked", self.refresh, label) 

     close_button = gtk.Button("Close") 
     close_button.connect("clicked", self.delete_event, "quit") 

     box3.pack_end(close_button, False, False, 20) 
     box3.pack_end(refresh_button, False, False, 20) 
     box1.pack_start(box3, False, False, 10) 

     box1.show() 
     box1a.show() 
     label.show() 
     box2.show() 
     box_sp1.show() 
     box_sp2.show() 
     frame_1.show() 
     title.show() 

     refresh_button.show() 
     close_button.show() 
     box3.show() 
     window.show() 

     gtk.main() 


if __name__ == "__main__": 
    pyglist =PyGlist() 
    pyglist.main() 

I을 지금 무슨 일이 일어나고 있는지 이해하고 있습니다. 나는 컨셉을 잡는 데 단지 느리다.

+1

꽤 많은 코드가 있습니다. 문제에 초점을 맞춘 [mcve]로 줄일 수 있다면 도움을받을 가능성이 더 큽니다. 나는 당신이 당신이 원하는 행동을 얻기 위해 코드를 재구성해야 할 것이라고 생각한다. '__init__' 메쏘드는 한번 호출됩니다. GUI 인스턴스가 생성되면 GUI를 새로 고치고 다시 할 수있는 일을 다시 할 수 없습니다. 그래서 거기에 여러 번 수행해야 할 것들이 있다면 그것은'__init__'가 아닌 다른 방법에 있어야합니다. –

답변

0

processlisting에 매번 새 라벨을 만들었지 만 결코 위젯 트리에 추가하지 않았기 때문에 결코 표시되지 않습니다. 사용자 인터페이스에서 이미 추가 한 레이블을 재사용하고 수정하십시오. 새로 고침 버튼의 신호 인 clicked에 연결할 때 매개 변수로 전달하십시오.

또한 각 위젯에서 show을 호출 할 필요가 없으며 최상위 gtk 창에서 show_all을 호출하면됩니다.

마지막으로 gtk_main_quit으로 전화하기 위해서는 destroy 신호에 연결하면됩니다. delete-event은 창을 닫으려는 사용자를 차단하고 기본 동작을 변경하려는 경우입니다.

#!/usr/bin/env python 

import pango, pygtk, subprocess, re, string, decimal, time 
pygtk.require('2.0') 
import gtk 


class PyGlist: 

    def getlisting(self): 
     listingcmd = ['ls', '-1'] 
     listing = subprocess.Popen(listingcmd, stdout=subprocess.PIPE).communicate()[0] 
     print listing 
     return listing 

    def on_destroy(self, widget, data=None): 
     gtk.main_quit() 

    def refresh(self, refresh_button, label): 
     label.set_text(self.getlisting()) 

    def main(self): 
     window = gtk.Window(gtk.WINDOW_TOPLEVEL) 
     window.connect("destroy", self.on_destroy) 

     box1 = gtk.VBox(False, 10) 
     box1a = gtk.HBox(False, 0) 
     box2 = gtk.VBox(False, 10) 
     box3 = gtk.HBox(False, 0) 
     frame_1 = gtk.Frame() 
     window.add(box1) 

     title = gtk.Label('Listing') 
     box1.pack_start(title, False, False, 10) 
     box1.pack_start(box1a, True, True, 0) 
     box1a.pack_start(frame_1, True, True, 20) 
     frame_1.add(box2) 

     label = gtk.Label(self.getlisting()) 
     label.set_line_wrap(False) 
     label.set_max_width_chars(80) 
     label.modify_font(pango.FontDescription("monospace")) 

     box_sp1 = gtk.HBox(False, 0) 
     box_sp2 = gtk.HBox(False, 0) 

     box2.pack_start(label, False, False, 0) 

     refresh_button = gtk.Button("Refresh") 
     refresh_button.connect("clicked", self.refresh, label) 

     close_button = gtk.Button("Close") 
     close_button.connect("clicked", self.on_destroy) 

     box3.pack_end(close_button, False, False, 20) 
     box3.pack_end(refresh_button, False, False, 20) 
     box1.pack_start(box3, False, False, 10) 

     window.show_all() 

     gtk.main() 


if __name__ == "__main__": 
    pyglist =PyGlist() 
    pyglist.main() 
+0

대단히 감사합니다. queue_data 행의 변형을 시도했지만 기존의 것을 갱신하지 않고 매번 새 레이블을 작성한다는 것을 알 수 없었습니다. – commandlinegamer

+0

이제 GTK 3로 전환하는 것에 대해 생각하고 대답을 수락 할 수 있습니다.). GTK 3는 수년간 안정적인 버전이었으며 GTK 4가 출시 될 예정이므로 이제 시작해야합니다. 다음은 pyGObject를 사용하는 python + GTK3에 대한 공식 자습서입니다. https://pygobject.readthedocs.io/en/latest/ https://python-gtk-3-tutorial.readthedocs.io/en/latest/index.html – liberforce

+0

네, 간단한 예제의 해결책은 꽤 잘 작동합니다. 그러나 원래의 문제는 "df"명령의 내용을 표시하기 위해 여러 행 (레이블 및 진행 막대 위젯이 포함 된 hbox)을 만들어야합니다. 새로 고침이 수행되고 디스크 볼륨이 마운트/마운트 해제 된 경우 해당 행을 추가하거나 제거해야 할 수 있습니다. 최신 버전의 "freedisk"프로그램을 포함하여 또 다른 편집본을 추가했습니다. – commandlinegamer

0

나는 그것을 마침내 깨뜨 렸습니다. 위의 포스터 덕분에.

더 간단한 예제는 나에게 내가 지나치게 복잡하게 만드는 부분을 보여 줬다.

원본 프로그램 "freedisk"나는 더 많은 코드를 별도의 함수로 옮겨서 어떤 일이 일어나고 있는지 쉽게 알 수있게되었습니다.

기본적으로 목표는 "df"의 출력을 가져 와서 하이브리드 텍스트 및 그래픽 디스플레이로 약간 조정하는 것입니다.

서식 상자, 제목 등을 제외하고 "df"출력 행 당 하나의 HBox가있는 VBox 컨테이너가 있으며 텍스트 형식의 일부 기둥 형 출력을 다시 만들지 만 진행 막대는 한 열로 다시 작성합니다.

데이터 변환과 행 생성은 별도의 기능으로 옮겨졌습니다.

이것은 처음에 호출되고 "새로 고침"버튼을 누를 때마다 호출됩니다.

수직 상자 안의 기존 행은 데이터가 다시 계산되고 다시 출력되기 전에 파괴됩니다. 그리고 이것은 퍼즐의 마지막 부분이 자리를 잡은 곳이었습니다.

위젯을 삭제하고 바꾼 후, 나는 그들이 다시 보여줘야한다는 것을 깨닫지 못했습니다. 최종 행 하나를 추가하면 "widget.show_all()"이 문제를 해결했습니다.

관련 문제