下面的代码创建一个包含三个标签的列.我想采用中间标签,并在初始创建UI后使用标签中的文本将其替换为另一个小部件.
我的实际用例是使用GTKBuilder填充的UI,并在运行时用动态包装的标签替换任何特定的命名标签.(我在这里使用了一个按钮,因为它很简单但很独特.)然后我仍然可以使用Glade设置UI,包括标签,如果我以后想要制作标签包装,不要用我的Python代码加错标签和字符串.
现在的代码不起作用 - 新的按钮被添加到列的末尾,我希望它保持在中间,从那里label2开始.我能做些什么,最好是在哪里wrap_in_button,以确保它最终到达正确的位置?我宁愿保持一般,因为父母可能是一个Box或一个Table或任何将军Container.
import pygtk
import gtk
def destroy(widget, data=None):
gtk.main_quit()
def wrap_in_button(label):
text = label.get_text()
button = gtk.Button(text)
parent = label.get_parent()
if parent:
parent.remove(label)
parent.add(button)
def Main():
# Pretend that this chunk is actually replaced by GTKBuilder work
# From here...
window = gtk.Window()
window.connect('destroy', destroy)
box = gtk.VBox()
window.add(box)
label1 = gtk.Label("Label 1")
label2 = gtk.Label("Label 2")
label3 = gtk.Label("Label 3")
box.pack_start(label1)
box.pack_start(label2)
box.pack_start(label3)
# ...up to here
# Comment this to see the original layout
wrap_in_button(label2)
window.show_all()
gtk.main()
if __name__ == "__main__":
Main()
Run Code Online (Sandbox Code Playgroud)
我在gazpacho界面设计器的代码中找到了解决方案.
你可以使用这个功能:
def replace_widget(current, new):
"""
Replace one widget with another.
'current' has to be inside a container (e.g. gtk.VBox).
"""
container = current.parent
assert container # is "current" inside a container widget?
# stolen from gazpacho code (widgets/base/base.py):
props = {}
for pspec in gtk.container_class_list_child_properties(container):
props[pspec.name] = container.child_get_property(current, pspec.name)
gtk.Container.remove(container, current)
container.add(new)
for name, value in props.items():
container.child_set_property(new, name, value)
Run Code Online (Sandbox Code Playgroud)
关键似乎是在运行后将子属性从旧窗口小部件转移到新窗口小部件gtk.Container.add().
应用于您的示例,这将是:
import pygtk
import gtk
def replace_widget(current, new):
"""
Replace one widget with another.
'current' has to be inside a container (e.g. gtk.VBox).
"""
container = current.parent
assert container # is "current" inside a container widget?
# stolen from gazpacho code (widgets/base/base.py):
props = {}
for pspec in gtk.container_class_list_child_properties(container):
props[pspec.name] = container.child_get_property(current, pspec.name)
gtk.Container.remove(container, current)
container.add(new)
for name, value in props.items():
container.child_set_property(new, name, value)
def destroy(widget, data=None):
gtk.main_quit()
def wrap_in_button(label):
text = label.get_text()
button = gtk.Button(text)
replace_widget(label, button)
def Main():
# Pretend that this chunk is actually replaced by GTKBuilder work
# From here...
window = gtk.Window()
window.connect('destroy', destroy)
box = gtk.VBox()
window.add(box)
label1 = gtk.Label("Label 1")
label2 = gtk.Label("Label 2")
label3 = gtk.Label("Label 3")
box.pack_start(label1)
box.pack_start(label2)
box.pack_start(label3)
# ...up to here
wrap_in_button(label2)
window.show_all()
gtk.main()
if __name__ == "__main__":
Main()
Run Code Online (Sandbox Code Playgroud)
这适用于使用Python 2.6.6和PyGTK 2.17.
作为原始问题的解决方案,我label_set_autowrap() 从这里开始使用它大部分时间都在工作.但是,它不是一个完美的解决方案,因为我无法正确对齐自动包装的文本.