将固定大小的 GtkDrawingArea 小部件置于父小部件内的中心
我有一个林间空地布局,其中有一个固定大小的 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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在 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.
固定将使用所有可用空间,您在这里需要的是捕获父级之一(视口或固定)的调整大小事件,我的猜测是视口会更好地工作,然后获取固定的大小,然后移动它的子项根据子项的大小而固定。
您可以使用视口(获取子窗口小部件)或从绘图区域(获取父窗口小部件)来执行此操作。
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.