我有一个带有 TreeView 的 GTK3 Python 程序,我想要一个主要包含文本的列,但也可以包含图像。我一直在询问 ChatGPT,但这已经是我能得到的最接近的了:
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GdkPixbuf
class TreeViewExample(Gtk.Window):
def __init__(self):
super().__init__(title="TreeView Table Example")
self.set_default_size(400, 300)
# Create a ListStore model with two columns
self.model = Gtk.ListStore(object, str) # Using 'object' type for the first column
self.model.append([self.load_image("path/to/your/image.png"), "Value A"]) # First row with an image
self.model.append(["Row 2", "Value B"]) # Second row with text
self.model.append(["Row 3", "Value C"])
# Create a TreeView
self.treeview = Gtk.TreeView(model=self.model)
# Create the first column with custom cell renderers
column1 = Gtk.TreeViewColumn("Column 1")
self.treeview.append_column(column1)
# Create a text renderer for the first column
cell_renderer_text = Gtk.CellRendererText()
column1.pack_start(cell_renderer_text, expand=True)
column1.add_attribute(cell_renderer_text, "text", 1) # Display text
column1.set_cell_data_func(cell_renderer_text, self.render_first_column) # Custom rendering function
# Create an image renderer for the first column
cell_renderer_pixbuf = Gtk.CellRendererPixbuf()
column1.pack_start(cell_renderer_pixbuf, expand=True)
column1.add_attribute(cell_renderer_pixbuf, "pixbuf", 0) # Display image
# Create the second column with a text renderer
cell_renderer2 = Gtk.CellRendererText()
column2 = Gtk.TreeViewColumn("Column 2", cell_renderer2, text=1)
self.treeview.append_column(column2)
# Add the TreeView to the window
self.add(self.treeview)
def load_image(self, image_path):
# Load an image from file and return a GdkPixbuf.Pixbuf
try:
pixbuf = GdkPixbuf.Pixbuf.new_from_file(image_path)
return pixbuf
except GLib.Error:
print(f"Error loading image from {image_path}")
return None
def render_first_column(self, column, cell, model, iter_, data=None):
# Custom rendering function for the first column
value = model.get_value(iter_, 0)
if isinstance(value, GdkPixbuf.Pixbuf):
cell.set_property("pixbuf", value) # Display the image
else:
cell.set_property("text", str(value)) # Display text
if __name__ == "__main__":
app = TreeViewExample()
app.connect("destroy", Gtk.main_quit)
app.show_all()
Gtk.main()
第一个模型列是一个“对象”,因此它可以是 str 或 pixbuf,这似乎是正确的。但是set_cell_data_func的调用有一个cell_renderer_text参数,所以当调用self.render_first_column函数时,cell参数总是看起来是一个CellRendererText,所以当值为pixbuf并且运行命令时:
cell.set_property("pixbuf", value)
如果失败:
builtins.TypeError: object of type `GtkCellRendererText' does not have property `pixbuf'
这篇文章(如何在 GtkTreeview 中制作带有字符串和 pixbuf 的列?)似乎在不使用 cell_data_func 的情况下将两个 CellRenderer 放在一起,但我在这些方面的尝试也没有成功。
有人可以帮我把它变成工作代码吗?
我也希望能帮助您理解column.pack_start 和column.add_attribute 方法。看起来 pack_start 方法是为了在同一个单元格中拥有多个 CellRenderer,但是它如何知道使用哪一个呢?
谢谢, 杰夫
我能够使用 pack_start 从同一列中显示的模型中获取两列数据,但它不会将它们放在相同的位置 - 第一项出现在左侧,第二项出现在右侧(有点像列中的两列)。看起来是这样的:
这不是很有帮助...我希望图像出现在与其他行中的文本相同的位置。
这是产生此输出的代码(您必须提供适当的图像):
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GdkPixbuf
class TreeViewExample(Gtk.Window):
def __init__(self):
super().__init__(title="TreeView Table Example")
self.set_default_size(400, 300)
# Create a ListStore model with two columns
self.model = Gtk.ListStore(str, str, GdkPixbuf.Pixbuf) # Using 'object' type for the first column
self.model.append(["", "Value A", self.load_image("mypic.png")]) # First row with an image
self.model.append(["Row 2", "Value B", None])
self.model.append(["Row 3", "Value C", None])
# Create a TreeView
self.treeview = Gtk.TreeView(model=self.model)
# Create the first column
column1 = Gtk.TreeViewColumn("Column 1")
self.treeview.append_column(column1)
cell_renderer_pixbuf = Gtk.CellRendererPixbuf()
column1.pack_start(cell_renderer_pixbuf, expand=True);
column1.add_attribute(cell_renderer_pixbuf, "pixbuf", 2);
cell_renderer_text = Gtk.CellRendererText()
column1.pack_start(cell_renderer_text, expand=True);
column1.add_attribute(cell_renderer_text, "text", 0);
# Create the second column with another text renderer
cell_renderer2 = Gtk.CellRendererText()
column2 = Gtk.TreeViewColumn("Column 2", cell_renderer2, text=1)
self.treeview.append_column(column2)
# Add the TreeView to the window
self.add(self.treeview)
def load_image(self, image_path):
# Load an image from file and return a GdkPixbuf.Pixbuf
try:
pixbuf = GdkPixbuf.Pixbuf.new_from_file(image_path)
return pixbuf
except GLib.Error:
print(f"Error loading image from {image_path}")
return None
if __name__ == "__main__":
app = TreeViewExample()
app.connect("destroy", Gtk.main_quit)
app.show_all()
Gtk.main()
所以我仍在寻找答案,也许模型中可以有一个“对象”,可以是文本或pixbuf,并且TreeView将正确显示模型中的任何内容。