2017-10-23 8 views
1

を手動で(私はこの段階でタイムアウトを使用していない)する方法を理解するトラブルを持ってはPyGTKでリフレッシュウィンドウ、またはPyGTKのウィンドウの一部を更新し、バージョン2表示内容を手動で私は(2)

この例では、 "df"コマンドの出力を選択し、 "refresh"ボタンを使用して手動でウィンドウをリフレッシュできるようにしたいと考えています。私はさまざまな例とPyGTKのチュートリアルを見てきましたが、リフレッシュコードを置く正確な場所が私を逃しています。 "main"ループの中の別の関数で "freedisk"関数でqueue_drawを使用して、成功せずに試みました。

最近、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」出力の1行につき1つのHBoxを持つVBoxコンテナがあり、テキスト形式の列出力をいくつか再現しますが、進捗バーは1列です。

データの変換と行の作成私は別の機能に移動しました。

これは最初に呼び出され、「更新」ボタンが押されるたびに呼び出されます。

垂直ボックス内の既存の行は、データが再計算されてから再出力される前に破棄されます。そして、これがパズルの最後の部分がどこに落ちたかです。

ウィジェットを破棄して置き換えた後、再表示する必要があるとは思いませんでした。 1つの最終行 "widget.show_all()"を追加することで問題が解決されました。

関連する問題