2016-09-04 10 views
0

GUI自体にボタンを押して別のボタンをGUIに追加しようとしています。基本的に私はそれを更新しようとしていますが、私はOOPに比較的新しいので、スコープに問題があります。Python GTK:別のボタンでGUIにボタンを追加する

これは私がこれまで持っているものです...

1 #!/usr/bin/env python 
    2 import random, gi, sys 
    3 from gi.repository import Gtk 
    4 import itertools 

23 class Deck: 
24 """A sample card deck""" 
25 def __init__(self): 
26  deck = [] 
27  self.color_list = ["red", "green", "blue"] 
28  for color in self.color_list: 
29  for i in range (1,2): 
30   deck.append((color, i)) 
31  self.deck = deck 
32 
33 def draw_card(self): 
34  print self.deck 
35  try: 
36  card = self.deck.pop() 
37  print self.deck 
38  return card 
39  except IndexError: 
40  print "No cards in deck!" 
41  return 

56 class MyWindow(Gtk.Window): 
57 
58 def __init__(self): 
59  Gtk.Window.__init__(self, title="RGB 3, 2, 1... GO!") 
60  self.set_border_width(10) 
61  self.set_size_request(450,150) 
62 
63  grid = Gtk.Grid() 
64  self.add(grid) 
65 
66  draw_button = Gtk.Button(label="Draw Card") 
67  draw_button.connect("clicked", self.on_draw_button_clicked) 
68  grid.attach(draw_button,0,0,1,1) 
69 
70  end_button = Gtk.Button(label="End Game") 
71  end_button.connect("clicked", self.on_stop_button_clicked) 
72  grid.attach_next_to(end_button,draw_button,Gtk.PositionType.RIGHT,1,1) 
73 
74  update_button = Gtk.Button(label="Update") 
75  update_button.connect("clicked", self.update, grid) 
76  grid.attach_next_to(update_button,end_button,Gtk.PositionType.RIGHT,1,1) 
77 
78 def update(self, widget, grid): 
79  card1_button = Gtk.Button(label="card1") 
80  card1_button.connect("clicked", self.on_card1_button_clicked) 
81  grid.attach_next_to(card1_button,draw_button,Gtk.PositionType.BOTTOM,3,1) 
82  
83 def on_draw_button_clicked(self, widget): 
84 +--- 13 lines: card = my_deck.draw_card()---------------------------------------------------------------------------------------------------- 
97 
98 def on_stop_button_clicked(self, widget): 
99  Gtk.main_quit() 
100  
101 def on_card1_button_clicked(self, widget): 
102  Gtk.main_quit() 

121 # Objects must be instantiated here 
122 my_deck = Deck() 
123 print my_deck.deck 
124 win = MyWindow() 
125 win.connect("delete-event", Gtk.main_quit) 
126 win.show_all() 
127 Gtk.main() 

私はこれを実行すると、私のGUIが開いてポップ。私は次のエラーを取得する私の更新ボタンを押したとき:

Traceback (most recent call last): 
    File "game1.py", line 85, in update 
    grid.attach_next_to(card1_button,draw_button,Gtk.PositionType.BOTTOM,3,1) 
NameError: global name 'draw_button' is not defined 

は、どのように私はすでにデフのinit機能で作成したGUI /グリッドを認識するために、私の更新機能を得るのですか?私がしたいことをするためのより良い方法はありますか?

答えて

1

MyWindowクラスにinstance variableを定義して、そのボタンを追跡します。

たとえば、コードでは、draw_buttonが表示されたときはいつでも、self.draw_buttonに変更します。他の方法でこのボタンを追跡することができます。これは、次のようになります。

import random, gi, sys 
from gi.repository import Gtk 
import itertools 

class Deck: 
    """A sample card deck""" 
    def __init__(self): 
    deck = [] 
    self.color_list = ["red", "green", "blue"] 
    for color in self.color_list: 
     for i in range(1,2): 
     deck.append((color, i)) 
    self.deck = deck 

    def draw_card(self): 
    print self.deck 
    try: 
     card = self.deck.pop() 
     print self.deck 
     return card 
    except IndexError: 
     print "No cards in deck!" 
     return 

class MyWindow(Gtk.Window): 

    def __init__(self): 
    Gtk.Window.__init__(self, title="RGB 3, 2, 1... GO!") 
    self.set_border_width(10) 
    self.set_size_request(450,150) 

    grid = Gtk.Grid() 
    self.add(grid) 

    # Here we create the instance variable and use it afterward 
    self.draw_button = Gtk.Button(label="Draw Card") 
    self.draw_button.connect("clicked", self.on_draw_button_clicked) 
    grid.attach(self.draw_button,0,0,1,1) 

    end_button = Gtk.Button(label="End Game") 
    end_button.connect("clicked", self.on_stop_button_clicked) 
    grid.attach_next_to(end_button, self.draw_button, Gtk.PositionType.RIGHT, 1, 1) 

    update_button = Gtk.Button(label="Update") 
    update_button.connect("clicked", self.update, grid) 
    grid.attach_next_to(card1_button, self.draw_button, Gtk.PositionType.BOTTOM, 3, 1) 

    def update(self, widget, grid): 
    card1_button = Gtk.Button(label="card1") 
    card1_button.connect("clicked", self.on_card1_button_clicked) 
    # Here we recall the value stored in self.draw_button 
    grid.attach_next_to(card1_button, self.draw_button, Gtk.PositionType.BOTTOM, 3, 1) 

    def on_draw_button_clicked(self, widget): 
    for x in range(13): 
     card = my_deck.draw_card() 

    def on_stop_button_clicked(self, widget): 
    Gtk.main_quit() 

    def on_card1_button_clicked(self, widget): 
    Gtk.main_quit() 

# Objects must be instantiated here 
my_deck = Deck() 
print my_deck.deck 
win = MyWindow() 
win.connect("delete-event", Gtk.main_quit) 
win.show_all() 
Gtk.main() 

しかし、あなたのコード内の他のいくつかの問題がある:

  • 私はあなたがGtkの3.0を使用していると推定します。その場合は、あなたはこのようにGtkをインポートする前に、それを必要とする必要があります

    gi.require_version('Gtk', '3.0') 
    from gi.repository import Gtk 
    
  • Deck.__init__()では、forループでrange(1,2)を使用していました。問題はrange(1, 2)[1]と等価であるということです。なぜなら、1から始まり2の直前で停止する範囲を求めているからです。あなたが望むものであるかどうかは分かりません。

  • MyWindow.update()メソッドの最後にself.show_all()を追加すると、新しく作成されたボタンが表示されません。
  • MyWindow.on_stop_button_clicked()MyWindow.on_card1_button_clicked()の方法でGtk.main_quit()の代わりにself.close()を使用する必要があります。そうしないと、コードをクリックしてもウィンドウが正しく破棄されません。

これはこれは、これらの提言をどのように見えるかです:

import random, gi, sys 
import itertools 

gi.require_version('Gtk', '3.0') 
from gi.repository import Gtk 

class Deck: 
    """A sample card deck""" 
    def __init__(self): 
    deck = [] 
    self.color_list = ["red", "green", "blue"] 
    for color in self.color_list: 
     for i in range(1,2): # Check to see if this is valid 
     deck.append((color, i)) 
    self.deck = deck 

    def draw_card(self): 
    print self.deck 
    try: 
     card = self.deck.pop() 
     print self.deck 
     return card 
    except IndexError: 
     print "No cards in deck!" 
     return 

class MyWindow(Gtk.Window): 

    def __init__(self): 
    Gtk.Window.__init__(self, title="RGB 3, 2, 1... GO!") 
    self.set_border_width(10) 
    self.set_size_request(450,150) 

    grid = Gtk.Grid() 
    self.add(grid) 

    self.draw_button = Gtk.Button(label="Draw Card") 
    self.draw_button.connect("clicked", self.on_draw_button_clicked) 
    grid.attach(self.draw_button,0,0,1,1) 

    end_button = Gtk.Button(label="End Game") 
    end_button.connect("clicked", self.on_stop_button_clicked) 
    grid.attach_next_to(end_button, self.draw_button, Gtk.PositionType.RIGHT, 1, 1) 

    update_button = Gtk.Button(label="Update") 
    update_button.connect("clicked", self.update, grid) 
    grid.attach_next_to(update_button, end_button, Gtk.PositionType.RIGHT, 1, 1) 

    def update(self, widget, grid): 
    card1_button = Gtk.Button(label="card1") 
    card1_button.connect("clicked", self.on_card1_button_clicked) 
    grid.attach_next_to(card1_button, self.draw_button, Gtk.PositionType.BOTTOM, 3, 1) 
    self.show_all()  # So that we can see the freshly created button 

    def on_draw_button_clicked(self, widget): 
    for x in range(13): 
     card = my_deck.draw_card() 

    def on_stop_button_clicked(self, widget): 
    self.close()   # Instead of Gtk.main_quit() 

    def on_card1_button_clicked(self, widget): 
    self.close()   # Instead of Gtk.main_quit() 

# Objects must be instantiated here 
my_deck = Deck() 
print my_deck.deck 
win = MyWindow() 
win.connect("delete-event", Gtk.main_quit) 
win.show_all() 
Gtk.main() 
+0

ありがとうございました! また、「他の方法でこのボタンを追跡できるようになります。」ということは、これがどのように一緒に働くかを理解する助けになります:) – Twitchykid

関連する問題