Центрировать фиксированный размер виджета 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()
И образец файла 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>
И наконец... образец изображения проблемы... https://imgur.com/eyTvO.png
2 ответа
В GTK 2.x добавьте GtkAlignment в качестве родителя того, что вы хотите центрировать и выровняйте 0,5 (отключить заливку).
В 3.x есть свойства xalign и yalign для всех виджетов, для которых установлено значение CENTER.
Обновление: из примера файла glade проблема в том, что заливка не отключена; Мне было лень искать, как свойства вызывались ранее, в GtkAlignment это xscale=0.0 yscale=0.0, что означает не расширять дочерний элемент для заполнения доступного пространства. Значение по умолчанию xscale=1.0 yscale=1.0 означает, что дочерний элемент будет заполнять доступное пространство, и, таким образом, центрирование ничего не делает.
В примере файла Glade мне также пришлось сделать "добавить родителя -> область просмотра", чтобы добавить область просмотра между прокручиваемым окном и выравниванием. Вы должны иметь предупреждение на консоли об этом.
Fixed будет использовать все доступное пространство, что вам нужно здесь, чтобы поймать событие изменения размера на одном из родителей, либо в окне просмотра, либо в Fixed, я предполагаю, что Viewport будет работать лучше, затем получит размер Fixed и переместится это ребенок в зависимости от размера ребенка и размера фиксированного.
Вы можете сделать это либо с помощью Viewport, получая дочерние виджеты, либо из DrawingArea, получая родителей.