【问题标题】:Center fixed-size GtkDrawingArea widget inside of parent widget在父小部件中居中固定大小的 GtkDrawingArea 小部件
【发布时间】:2011-04-21 23:11:36
【问题描述】:

我有一个林间空地布局,其中我有一个固定大小的 GtkDrawingArea。层次结构的当前相关部分是:

GtkWindow > GtkVBox > GtkHPaned > GtkViewport > GtkAlignment > GtkFixed > GtkDrawingArea

目前,GtkFixed 小部件绘制在 GtkViewport 的左上角。

但是,如果 GtkFixed(以及它唯一的孩子,GtkDrawingArea)在 GtkViewport 中居中,我真的很喜欢它(当然,当小部件被压缩到不适合其内容的程度时除外并出现滚动条)。

完成此任务的最佳方法是什么? (我是用pygtk做实际的应用逻辑,不过这应该是一个通用的gtk问题)

这是一个有代表性的代码示例:

import gtk

class Controller:

    def on_window1_destroy(self, widget, data=None):
        gtk.main_quit()

    def __init__(self):
        self.builder = gtk.Builder()
        self.builder.add_from_file("sample.glade")
        self.window = self.builder.get_object("window1")
        self.builder.connect_signals(self)

    def on_drawingarea1_expose_event(self, widget, event):
        cr = widget.window.cairo_create()
        cr.set_source_rgb(0,0,0)
        cr.paint()
        return True

if __name__ == "__main__":
    client = Controller()
    client.window.show()
    gtk.main()

还有一个具有相同问题的示例 glade 文件:

<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <requires lib="gtk+" version="2.16"/>
  <!-- interface-naming-policy project-wide -->
  <object class="GtkWindow" id="window1">
    <signal name="destroy" handler="on_window1_destroy"/>
    <child>
      <object class="GtkVBox" id="vbox1">
        <property name="visible">True</property>
        <child>
          <object class="GtkHPaned" id="hpaned1">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <child>
              <object class="GtkLabel" id="label1">
                <property name="visible">True</property>
                <property name="label" translatable="yes">label</property>
              </object>
              <packing>
                <property name="resize">False</property>
                <property name="shrink">True</property>
              </packing>
            </child>
            <child>
              <object class="GtkScrolledWindow" id="scrolledwindow1">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="hscrollbar_policy">automatic</property>
                <property name="vscrollbar_policy">automatic</property>
                <child>
                  <object class="GtkAlignment" id="alignment1">
                    <property name="visible">True</property>
                    <child>
                      <object class="GtkFixed" id="fixed1">
                        <property name="width_request">300</property>
                        <property name="height_request">300</property>
                        <property name="visible">True</property>
                        <child>
                          <object class="GtkDrawingArea" id="drawingarea1">
                            <property name="width_request">300</property>
                            <property name="height_request">300</property>
                            <property name="visible">True</property>
                            <signal name="expose_event" handler="on_drawingarea1_expose_event"/>
                          </object>
                        </child>
                      </object>
                    </child>
                  </object>
                </child>
              </object>
              <packing>
                <property name="resize">True</property>
                <property name="shrink">True</property>
              </packing>
            </child>
          </object>
          <packing>
            <property name="position">0</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>

最后...问题的示例图片...

【问题讨论】:

    标签: python gtk pygtk glade gtkbuilder


    【解决方案1】:

    在 GTK 2.x 中,添加一个 GtkAlignment 作为您想要居中并对齐 0.5(禁用填充)的任何内容的父级。

    在 3.x 中,所有小部件都有 xalign 和 yalign 属性,设置为 CENTER。

    更新:从示例 glade 文件中,问题是填充没有被禁用;之前我懒得去查这些属性是怎么调用的,在GtkAlignment中这是xscale=0.0 yscale=0.0,意思是不要扩展child来填满可用空间。默认的 xscale=1.0 yscale=1.0 表示子元素将填充可用空间,因此居中不会做任何事情。

    在示例 Glade 文件中,我还必须执行“添加父级 -> 视口”以在滚动窗口和对齐之间添加一个视口。您应该在控制台上看到有关此问题的警告。

    【讨论】:

    • 我已经尝试过 GtkAlignment,正如您之前描述的 GtkFixed 的父级,它没有使小部件居中。
    • 您可能需要发布林间空地文件以便人们查看。
    • 我已经发布了一个示例 glade 文件和一个匹配的 python 脚本,它将我想保持居中的区域绘制为黑色。理想情况下,黑色绘图区域将保持在其 GtkViewport 的中心。
    • 我添加了一个视口并设置了 x/yscale=0.0,它似乎在这里工作。
    • 糟糕!忘记将 GtkViewport 放在示例文件中!但问题确实是 x/y 比例。
    【解决方案2】:

    Fixed 将使用所有可用空间,您需要在这里捕获其中一个父级(视口或 Fixed)上的调整大小事件,我的猜测是 Viewport 会更好地工作,然后,获取 Fixed 的大小,并根据孩子的大小和固定的大小移动它的孩子。

    您可以通过 Viewport 获取子小部件或从 DrawingArea 获取父小部件来执行此操作。

    【讨论】:

    • 调整大小时 GtkFixed 保持固定大小。 GtkViewport 是可以扩展/收缩的,我想像它一样将 Fixed 居中。
    猜你喜欢
    • 2014-11-20
    • 1970-01-01
    • 1970-01-01
    • 2021-08-22
    • 2021-03-26
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    • 1970-01-01
    相关资源
    最近更新 更多