Как использовать один и тот же виджет дважды в pygtk? - PullRequest
2 голосов
/ 24 августа 2009

Это не очень хорошо работает:

    image_log = gtk.Image()
    image_log.set_from_file("test.png")

    self.out_button = gtk.Button()
    self.out_button.add(image_log)

    self.err_button = gtk.Button()
    self.err_button.add(image_log)

    another_box.pack_start(self.out_button, False)
    another_box.pack_start(self.err_button, False)

Проблема в том, что image_log используется дважды, а GTK это не нравится. Есть ли какой-нибудь метод .copy ()? Или мне просто использовать простую ванильную глубокую копию?

РЕДАКТИРОВАТЬ: Похоже, по умолчанию нет способа клонировать объекты в GTK. Фабрика сделает свое дело в этом случае.

GTK предупреждение:

app/gui.py:248: GtkWarning: gtk_box_pack: assertion `child->parent == NULL' failed
hbox_errlog.pack_start(image_log)

Ответы [ 3 ]

2 голосов
/ 24 августа 2009

Вы можете использовать заводскую функцию, чтобы уменьшить дублирование кода

def make_image_from_file(fname):
  im = gtk.Image()
  im.set_from_file(fname)
  return im

self.out_button.set_image(make_image_from_file(..))

* 1004 Пересмотр * Существует гораздо более естественный способ. Тебе понравится. В PyGTK 2.12 +: gtk.image_new_from_file(filename) У меня в голове было что-то, что говорило мне об этом, но я не искал это. http://www.pygtk.org/docs/pygtk/class-gtkimage.html#function-gtk--image-new-from-file

2 голосов
/ 14 мая 2011

Используйте

def clone_widget(widget):
    widget2=widget.__class__()
    for prop in dir(widget):
        if prop.startswith("set_") and prop not in ["set_buffer"]:
            prop_value=None
                try:
                    prop_value=getattr(widget, prop.replace("set_","get_") )()
                except:
                    try:
                        prop_value=getattr(widget, prop.replace("set_","") )
                    except:
                        continue
                if prop_value == None:
                    continue
                try:
                    getattr(widget2, prop)( prop_value ) 
                except:
                    pass
return widget2

Все это попробуйте ... кроме блоков, потому что не все свойства могут быть скопированы с помощью set_prop (get_prop). Я еще не проверял это для всех свойств и виджетов, но он хорошо работал для gtkEntry. Может быть, это медленно, но приятно использовать:)

1 голос
/ 24 августа 2009

Почему бы не

image_log = gtk.Image()
image_log.set_from_file("test.png")
image_logb = gtk.Image()
image_logb.set_from_file("test.png")

self.out_button = gtk.Button()
self.out_button.add(image_log)

self.err_button = gtk.Button()
self.err_button.add(image_logb)

another_box.pack_start(self.out_button, False)
another_box.pack_start(self.err_button, False)

Это всего лишь две дополнительные строки кода, и, возможно, более эффективный, чем клонирование / копирование первого объекта изображения.

Таким образом, вы можете обрабатывать out_button и err_button независимо. Но имеет смысл использовать один и тот же gtk.Image() объект для обеих кнопок ... это просто изображение.

Редактировать Чтобы избежать дублирования (кажется, что overkill ) вы можете написать фабрику для объектов gtk.Image () из того же изображения.

def gtkimage_factory(num_objs, image_file):
    i=0
    imglist = []
    while i<num_objs:
        img_ob = gtk.Image()
        img_ob.set_from_file(image_file)
        imglist.append( img_ob )
        i+=1
    return imglist

Или что-то в этом роде, вы поняли идею. Но фабрика кажется излишней, если вы не производите загрузок этих вещей и не нуждаетесь в них независимо от GTK. Тогда ...

image_list = gtkimg_factory(2, "test.png")

self.out_button = gtk.Button()
self.out_button.add(image_list[0])

self.err_button = gtk.Button()
self.err_button.add(image_list[1])

another_box.pack_start(self.out_button, False)
another_box.pack_start(self.err_button, False)

Может быть, это как-то связано с управлением ресурсами GTK?

...