将固定大小的 GtkDrawingArea 小部件置于父小部件内的中心

发布于 2024-11-02 22:46:23 字数 4427 浏览 5 评论 0原文

我有一个林间空地布局,其中有一个固定大小的 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()

以及一个具有相同问题的示例林间空地文件:

<?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>

最后......问题的示例图像。 ..

I've got a glade layout going, and in it I have a fixed-size GtkDrawingArea. The current relevant part of the hierarchy is:

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

Currently, the GtkFixed widget draws at the top-left corner of the GtkViewport.

However, I'd really like it if the GtkFixed (and thus its only child, the GtkDrawingArea) were centered within GtkViewport (except, of course, when the widget is compressed to the point where it doesn't fit its contents and the scrollbars appear).

What's the best way to accomplish this?
(I'm using pygtk to do actual application logic, but this should be a general gtk question)

Here is a representative code sample:

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()

And a sample glade file with the same issue:

<?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>

And lastly... a sample image of the issue...
Screeshot @ imgur

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

离旧人 2024-11-09 22:46:23

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

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

更新:从示例林间空地文件来看,问题是填充未被禁用;我懒得去查找之前调用的属性,在 GtkAlignment 中这是 xscale=0.0 yscale=0.0,这意味着不要扩展子级来填充可用空间。默认 xscale=1.0 yscale=1.0 意味着子级将填充可用空间,因此居中不会执行任何操作。

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

In GTK 2.x add a GtkAlignment as the parent of whatever you want to center and align 0.5 (disable fill).

In 3.x, there are xalign and yalign properties on all widgets, set to CENTER.

Update: from the sample glade file, the issue is that fill isn't disabled; I was too lazy to look up what the properties were called earlier, in GtkAlignment this is xscale=0.0 yscale=0.0, which means don't expand the child to fill available space. The default xscale=1.0 yscale=1.0 means the child will fill the available space and thus centering does not do anything.

In the sample Glade file I also had to do "add parent -> viewport" to add a viewport between the scrolled window and the alignment. You should have a warning on the console about this.

夜巴黎 2024-11-09 22:46:23

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

您可以使用视口(获取子窗口小部件)或从绘图区域(获取父窗口小部件)来执行此操作。

Fixed will use all space available, what you need here is to catch the resize event on one of the parents, either the viewport or the Fixed, my guess is that Viewport will work better, then, get the size of the Fixed, and move it's child according tho the size of the child and the size of the fixed.

You can do this either with the Viewport, getting child widgets, or from the DrawingArea, getting parents.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文