我试图通过按下GUI本身上的按钮向GUI添加另一个按钮。基本上我只是想尝试更新它,但我对OOP来说相对较新,所以我遇到了范围问题。
这就是我到目前为止......
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
如何让我的更新功能识别我已经在def init 功能中创建的GUI /网格?有没有更好的方法来做我想要的?
答案 0 :(得分: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之前停止。我不确定那是你想要的。
self.show_all()
方法的末尾添加MyWindow.update()
,否则您将无法看到新创建的按钮。self.close()
和Gtk.main_quit()
方法中使用MyWindow.on_stop_button_clicked()
代替MyWindow.on_card1_button_clicked()
,否则您的代码将无法在单击这些按钮时正确销毁您的窗口。 这就是这些建议的看法:
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()