是啥导致不同 GTK 版本之间 GtkIconView 的显示行为不同?

Posted

技术标签:

【中文标题】是啥导致不同 GTK 版本之间 GtkIconView 的显示行为不同?【英文标题】:What causes the different display behaviour for a GtkIconView between different GTK versions?是什么导致不同 GTK 版本之间 GtkIconView 的显示行为不同? 【发布时间】:2012-12-14 22:24:47 【问题描述】:

图片会解释标题:

在 LMDE 和 Ubuntu 12.04 下,我的 GtkIconView 看起来像这样 - 就图标之间的间距而言,它是正确的:

在 Ubuntu 12.10、13.04 和 Fedora 17 下相同的代码显示如下:

注意- 这是一个节奏盒python插件-源代码是here on GitHub

我检查了以下 GtkIconView 属性 - 它们在 Ubuntu 12.04 和错误显示的 12.10 版本中完全相同。

项目填充 行间距 列间距 项目宽度

当我将 text_columnma​​rkup_column(图标下的文本)设置为可见列(即从 -1 更改值)时,此显示行为会立即发生到列号。

如果文本列/标记列被隐藏(即值 -1),则所有发行版上的显示都是正确的。

由于在完全相同的音乐收藏上运行相同的代码 - 我只能推测 Fedora 17/Ubuntu 12.10/13.04 中较新的 GTK 库的行为不同。

我的 google-fu 只找到了听起来相同的 this reference。但是检查 ubuntu-accomplishment-viewer 源代码并没有真正启发我。

有没有其他人遇到过这种情况?对进一步调查的最佳方式有何建议?


好的 - 我已尝试将其简化为基本要素 - 这个简单的 glade 文件和这个简单的代码会产生这个问题。但是我仍然不知道是什么导致了这种视觉效果:/

#!/usr/bin/env python 从 gi.repository 导入 Gtk, GdkPixbuf 窗口 = Gtk.Window() window.connect('delete_event', Gtk.main_quit) ui = Gtk.Builder() ui.add_from_file('reproduce.ui') page = ui.get_object('main_box') window.add(页面) ls = Gtk.ListStore(str, GdkPixbuf.Pixbuf) 图标 = GdkPixbuf.Pixbuf.new_from_file_at_size( str("/usr/share/icons/gnome/48x48/actions/zoom-out.png"), 90, 90) 对于范围内的 i (15): ls.append(['项目 %d' % i, 图标]) cover_view = ui.get_object('covers_view') cover_view.set_model(ls) 封面视图.set_text_column(0) 覆盖视图.set_pixbuf_column(1) cover_view.set_item_width(100) # 这些行更容易看出问题 crt, crp = cover_view.get_cells() crt.set_property('背景', '#000') crt.set_property('前景', '#AAA') 打印 crt.get_request_mode() window.set_default_size(600,400) window.show_all() gtk.main()

还有林间空地 - http://pastebin.com/uvQ9mWeg


根据deinonychusaur 的建议,我查看了gtkparasite

仅供参考 - 我在 Ubuntu 12.04 和 12.10 中都使用了现成的 PPA from AnthonyWong。

两个版本的结果相同。尝试使用应用更改 IconView 属性并没有真正解决这个问题。

恐爪龙的下一个建议看起来很有趣,我可以确认 - 即

IconView CellRendererText 是 Fedora 17/12.10/13.04 中 IconView Pixbuf 大小的 2 倍,但 12.04 中 IconView Pixbuf 大小 1 倍。

【问题讨论】:

两个想法:您是否 (a) 测试过使用 gtk 检查程序来查看可能导致问题的属性?如果这不可能 (b) 检查不同平台上的 gtk-versions,因为也许至少有一些更改日志可以引导您正确了解更改的内容? 工具:unix.stackexchange.com/questions/37626/… 和变更日志,我也不知道,但也许在 gtk 开发项目中...... gtk3 的 python 绑定确实记录不足。 您就在上面,因为它与文本相关,因为CellRendererText 的首选宽度为 180,如果设置为 100,则此值在 window.show_all() 处再次更改为 180。即使在显示所有内容后改回,它仍然会在Gtk.main() 期间更改为 180。 (如果实际上将自己设置为 CellRendererPixbuf 的 2 倍宽度,可以看出如果将其更改为 100 而不是 90,导致 CellRendererText 变为 200) 我还可以补充一点,该效果与包含两个渲染器的CellAreaBox 中的方向无关(如果其方向切换为水平,问题仍然存在)。也就是说,这不是打包 + 展开的问题。 我在您的代码中添加了一些行(希望没问题),所以CellRendererText 的大小是可见的。另外,如果您检查打印语句,上面写着<enum GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH of type GtkSizeRequestMode>,这可能与问题有关?有Gtk.SizeRequestMode.CONSTANT_SIZE,不知道怎么改。 【参考方案1】:

观察原因。

上游 GTK 开发者决定 change the algorithm 关于如何计算 IconView 的 TextRenderer 单元格的宽度。

我们还是用原来的猜测,尝试图标大小并设置双倍 在列表中找到的第一个图标的大小,天真但很有效 时间

此更改是在 Ubuntu 12.04 和 LMDE 中的旧 GTK 版本之后提交的。它进入了 Ubuntu 12.10、13.04 和 Fedora 17 中的更高 GTK 版本。

错误或没有错误

自从 Ubuntu 12.04 发布以来,这个问题已经出现了一年多,看来这不是一个错误,而是一个设计决定。

可能有点奇怪 - 在 Bugzilla this was reported 上用于另一个应用程序(Pitivi 视频编辑器),但在撰写本文时仍处于未确认状态。

解决方法

该链接中有用的是一个附件,它提供了一种解决方法,您可以在其中创建 CellRendererText 并将其分配给 IconView,然后再定义标记/文本列。

以下是我对解决方法的解释

封面大小=100 markup_text="一些文字" self._text_renderer = Gtk.CellRendererText() self._text_renderer.props.alignment = Pango.Alignment.CENTER self._text_renderer.props.wrap_mode = Pango.WrapMode.WORD self._text_renderer.props.xalign = 0.5 self._text_renderer.props.yalign = 0 self._text_renderer.props.width = cover_size self._text_renderer.props.wrap_width = cover_size self._cover_view.pack_end(self._text_renderer, False) self._cover_view.add_attribute(self._text_renderer, 'markup', markup_text)

【讨论】:

【参考方案2】:

使用@qama 所说的关于“on-resize-set-size-request hack”的内容,可以修复该行为(尽管以一种非常骇人听闻的方式)。

只需添加一个回调:

def keep_size(crt, *args):

    crt.handler_block(crt_notify)
    crt.set_property('width', 100)
    crt.handler_unblock(crt_notify)

并将其连接到CellRendererText:

crt, crp = covers_view.get_cells()
crt_notify = crt.connect('notify', keep_size)

如果您将print crt, args 添加到回调中,您可以看到它会出现大约10-20 次...同时处理属性widthwrap-width

【讨论】:

+1 感谢您对此的帮助 - 您的解决方法确实有效。正是您的观察对此有所帮助,因此,我会将我的答案标记为已接受的答案-因为您将我引向正确的方向,所以我会给您赏金。干杯。【参考方案3】:

为了正确重现:

不要使用系统 gtk rc 不要使用用户 gtk rc 仅应用您自己的 gtk rc 设置两个版本,例如虚拟盒子 均衡系统参数,例如dpi 使用相同的数据运行 发布使用的精确版本、py、pygtk、gtk+、依赖库

话虽如此,但我遇到了不同版本的 gtk+ 行为不同的问题,以至于我无法在 linux(最新的 gtk)上可靠地开发并部署到 Windows(固定版本)。

随着时间的推移在 gtk+ 中修复了错误,引入了新功能,您不能真正期望在不同版本之间实现像素完美的再现。

【讨论】:

我明白了你的观点,但如果你检查我上面的 cmets,在某些 gtk 主题和/或 gtk 版本中似乎有一条规则说:'在 IconView 中,使 CellRendererText 成为 CellRendererPixbuf 的 2 倍宽度' .这应该可以以某种方式覆盖。 不太可能是规则,如果是,在app rc中找到并覆盖。要查看它是否与文本相关,请尝试不使用标签。最后,它很可能是 gtk 中的一个错误。无论如何,您需要先进行分类,是数据、rc 还是 gtk? (我不是问 q 的人),但我的投票是它与数据无关,而是与规则有关,因为当我将 CellRendererPixbuf 宽度链接到 CellRendererText 宽度时,它自己得到了进入一个以 6400 宽(我猜是最大值)结束的循环,即使所有项目的文本都是“我”,问题仍然存在。 糟糕,没注意到,我的椭圆文本也有类似的情况,在某些情况下,我的是滚动窗口,椭圆或自动换行的文本不会椭圆或自动换行,而是展开。我不得不用可怕的 on-resize-set-size-request hack 来覆盖它。那是几年前的事了,我希望这个案例现在已经在 gtk+ 中得到解决,并且 op 看到了一个不同的问题。无论如何,为了得到好的答案,op 必须重现和分类。我怀疑 screenshot2 来自用户或其他开发人员。 @qarma - 感谢您的回答 - 只是为了确认,省略号是我们的代码 - 没有换行文本,只有两行 "\n" pango 等。屏幕截图来自同一个 OP,使用相同源数据和相同的代码 - 一个在 ubuntu 12.04(屏幕截图 1)和 ubuntu 12.10(屏幕截图 2)上 - 我已经独立验证了 LMDE 和 Fedora 17 上的情况。CellRenderer 的东西看起来是正确的地方。

以上是关于是啥导致不同 GTK 版本之间 GtkIconView 的显示行为不同?的主要内容,如果未能解决你的问题,请参考以下文章

你如何知道 Ubuntu 上安装了哪个版本的 GTK+?

将 Gtk.Widget 打印到打印机的最佳方法是啥?

在 GTK3 中显示股票图标的非弃用方式是啥?

用于聊天窗口 irc 的 GTK 最好的小部件是啥? [关闭]

http协议不同版本之间的对比(1.0 1.1 2.0)

GTK# 图像按钮在运行时不显示图像