Центрирование виджета GtkDrawingArea фиксированного размера внутри родительского виджета - PullRequest
2 голосов
/ 22 апреля 2011

У меня есть макет поляны, и в нем есть фиксированный размер 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>

И, наконец ... примерное изображение вопроса ... Screeshot @ imgur

Ответы [ 2 ]

5 голосов
/ 23 апреля 2011

В 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 мне также пришлось сделать «добавить родителя -> область просмотра», чтобы добавить область просмотра между прокручиваемым окном и выравниванием. На консоли должно быть предупреждение об этом.

0 голосов
/ 23 апреля 2011

Fixed будет использовать все доступное пространство, что вам нужно здесь, чтобы поймать событие изменения размера на одном из родителей, либо в окне просмотра, либо в Fixed, я предполагаю, что Viewport будет работать лучше, тогда получите размер Fixed и переместите его в соответствии с размером ребенка и размером фиксированного.

Это можно сделать либо с помощью видового экрана, получая дочерние виджеты, либо из DrawingArea, получая родителей.

...