Python3 Gtk +如何获取以下网格布局? (图片)

问题描述 投票:0回答:1

我需要在主应用程序窗口中包含不同小部件的网格。由于我刚接触Gtk,因此我决定从创建一个简单的布局开始,以便我可以更好地理解其背后的逻辑。

以下图像是我要获取的布局:

enter image description here

如您所见,我已经有一个菜单 ((Archivo | Preferencias | Ayuda)] >>和[toolbar (Nuevo | Abrir | Deshacer | Pantalla completa)。]]。

因此,在红色矩形中,我试图获取scrolledwindow

(假设我在大列中具有图像名称列表),绿色线将是separator,最后,“蓝色”矩形将是一个小部件,用于在选择滚动窗口的图像时显示图像。

下图是当前输出。请注意,滚动窗口位于工具栏的右下方,占据所有垂直空间和宽度的99%,而左侧宽度的1%则是在窗口的右边缘显示分隔符的位置(因此,白色部分在工具栏的右侧)

enter image description here

最后,如果要运行它,这是此UI的代码。 网格是在Window类的初始化中构建的。

application.py

# -*- encoding: utf-8 -*-

# Author:
# Diego Suárez García, [email protected]

# ## ## ## ## ## ## ## ## ## ## ## ## # ## ## ## ## ## ## ## ## ## ## ## ## # 
# ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ #
#                                                                           #
#   application.py :                                                        #
#                                                                           #
# ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ # 
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##

import json

import sys

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import Gio
from gi.repository import Gdk

# Constants
MENU_FILE = "menubar.ui"

## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
# ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ #
# ~                             Window Class                              ~ #
# ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ # 
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##

class Window(Gtk.ApplicationWindow):

    def __init__(self, app):

        # Main window initialization
        super(Window, self).__init__(title="FreeComet 1.0", application=app)
        self.set_default_size(800, 600)

        # The project filename
        self.project_filename = None

        # The grid to attach the toolbar
        grid = Gtk.Grid()
        # The toolbar
        toolbar = self.__create_toolbar()
        toolbar.set_hexpand(True)               # with extra horizontal space

        # The Toolbar Actions
        undo_action = Gio.SimpleAction.new("undo", None)
        undo_action.connect("activate", self.undo_callback)
        self.add_action(undo_action)

        fullscreen_action = Gio.SimpleAction.new("fullscreen", None)
        fullscreen_action.connect("activate", self.fullscreen_callback)
        self.add_action(fullscreen_action)

        new_action = Gio.SimpleAction.new("new-project", None)
        new_action.connect("activate", self.new_project_callback)
        self.add_action(new_action)

        open_project_action = Gio.SimpleAction.new("open-project", None)
        open_project_action.connect("activate", self.open_project_callback)
        self.add_action(open_project_action)

        # The scrolledwindow
        scrolled_window = Gtk.ScrolledWindow()
        scrolled_window.set_border_width(10)
        scrolled_window.set_vexpand(True)
        scrolled_window.set_hexpand(False)
        # there is always the scrollbar (otherwise: AUTOMATIC - only if needed
        # - or NEVER)
        scrolled_window.set_policy(
            Gtk.PolicyType.ALWAYS, Gtk.PolicyType.ALWAYS)

        # a horizontal separator
        hseparator = Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL)
        # a vertical separator
        vseparator = Gtk.Separator(orientation=Gtk.Orientation.VERTICAL)

        # Build grid
        grid.add(toolbar)
        grid.attach(scrolled_window, 0, 1, 1, 1)
        grid.attach(vseparator, 1, 1, 1, 1)
        grid.attach(Gtk.Button(), 2, 1, 1, 1)
        # Add the grid to the window
        self.add(grid)




    def __create_toolbar(self):

        # Toolbar initialization (primary toolbar of the application)
        toolbar = Gtk.Toolbar()
        toolbar.get_style_context().add_class(Gtk.STYLE_CLASS_PRIMARY_TOOLBAR)

        # Button for the 'new' action
        new_button = Gtk.ToolButton.new_from_stock(Gtk.STOCK_NEW)
        new_button.set_property("has-tooltip", True)
        new_button.connect("query-tooltip", self.new_project_tooltip_callback)
        new_button.set_is_important(True)
        toolbar.insert(new_button, 0)
        new_button.set_action_name("win.new-project")

        # Button for the 'open' action
        open_button = Gtk.ToolButton.new_from_stock(Gtk.STOCK_OPEN)
        open_button.set_property("has-tooltip", True)
        open_button.connect("query-tooltip", self.open_project_tooltip_callback)
        open_button.set_is_important(True)
        toolbar.insert(open_button, 1)
        open_button.set_action_name("win.open-project")

        # Button for the 'undo' action
        undo_button = Gtk.ToolButton.new_from_stock(Gtk.STOCK_UNDO)
        undo_button.set_property("has-tooltip", True)
        undo_button.connect("query-tooltip", self.undo_tooltip_callback)
        undo_button.set_is_important(True)
        toolbar.insert(undo_button, 2)
        undo_button.set_action_name("win.undo")

        # Button for the 'fullscreen/leave fullscreen' action
        self.fullscreen_button = Gtk.ToolButton.new_from_stock(
            Gtk.STOCK_FULLSCREEN)
        self.fullscreen_button.set_property("has-tooltip", True)
        self.fullscreen_button.connect("query-tooltip", 
            self.fullscreen_tooltip_callback)
        self.fullscreen_button.set_is_important(True)
        toolbar.insert(self.fullscreen_button, 3)
        self.fullscreen_button.set_action_name("win.fullscreen")

        # return the complete toolbar
        return toolbar


## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
# ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ #
# ~                               Callbacks                               ~ #
# ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ # 
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## 

    #                                            #
    # #       Toolbar Tooltips Callbacks       # #
    #                                            #

    def new_project_tooltip_callback(self, widget, x, y, keyboard_mode, tooltip):
        tooltip.set_text("Crear un nuevo proyecto")
        tooltip.set_icon_from_stock("gtk-new", Gtk.IconSize.MENU)
        return True

    def open_project_tooltip_callback(self, widget, x, y, keyboard_mode, tooltip):
        tooltip.set_text("Abrir un proyecto existente")
        tooltip.set_icon_from_stock("gtk-open", Gtk.IconSize.MENU)
        return True

    def undo_tooltip_callback(self, widget, x, y, keyboard_mode, tooltip):
        tooltip.set_text("Deshacer la última acción")
        tooltip.set_icon_from_stock("gtk-undo", Gtk.IconSize.MENU)
        return True

    def fullscreen_tooltip_callback(self, widget, x, y, keyboard_mode, tooltip):
        tooltip.set_text("Modo pantalla completa")
        tooltip.set_icon_from_stock("gtk-fullscreen", Gtk.IconSize.MENU)
        return True

    #                                            #
    # #           Toolbar Callbacks            # #
    #                                            #

    def new_project_callback(self, action, parameter):
        print("You clicked \"New Project\".")

    def open_project_callback(self, action, parameter):
        # Create a filechooserdialog to open:
        # The arguments are: title of the window, parent_window, action,
        # (buttons, response)
        open_project_dialog = Gtk.FileChooserDialog("Seleccione un proyecto", self,
                                            Gtk.FileChooserAction.OPEN,
                                           (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                                            Gtk.STOCK_OPEN, Gtk.ResponseType.ACCEPT))

        # Not only local files can be selected in the file selector
        open_project_dialog.set_local_only(False)
        # Connect the dialog with the callback function open_response_callback_response()
        open_project_dialog.connect("response", self.__open_project_callback_response)
        # Show the dialog
        open_project_dialog.show()

    def __open_project_callback_response(self, dialog, response_id):

        open_project_dialog = dialog
        if response_id == Gtk.ResponseType.ACCEPT:
            # Filename we get from the FileChooserDialog
            self.project_filename = open_project_dialog.get_filename()

        dialog.destroy()

        # Read project
        #data = json.load(self.project_filename)

    def undo_callback(self, action, parameter):
        print("You clicked \"Undo\".")

    def fullscreen_callback(self, action, parameter):
        # check if the state is the same as Gdk.WindowState.FULLSCREEN, which
        # is a bit flag
        is_fullscreen = self.get_window().get_state(
        ) & Gdk.WindowState.FULLSCREEN != 0
        if not is_fullscreen:
            self.fullscreen_button.set_stock_id(Gtk.STOCK_LEAVE_FULLSCREEN)
            self.fullscreen()
        else:
            self.fullscreen_button.set_stock_id(Gtk.STOCK_FULLSCREEN)
            self.unfullscreen()


## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
# ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ #
# ~                           Application Class                           ~ #
# ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ # 
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##    

class Application(Gtk.Application):

    def __init__(self):
        super(Application, self).__init__()

    def do_activate(self):    
        self._win_main = Window(self)
        self._win_main.show_all()

    def do_startup(self):
        # FIRST THING TO DO: do_startup()
        Gtk.Application.do_startup(self)

        # The Application Menubar
        builder = Gtk.Builder()
        try:
            builder.add_from_file(MENU_FILE)
        except:
            print("ERROR: " + MENU_FILE +" not found")
            sys.exit()
        self.set_menubar(builder.get_object("menubar"))

        # [2] The Menubar Actions
        new_project_action = Gio.SimpleAction.new("new", None)
        new_project_action.connect("activate", self.new_project_callback)
        self.add_action(new_project_action)

        open_project_action = Gio.SimpleAction.new("open", None)
        open_project_action.connect("activate", self.open_project_callback)
        self.add_action(open_project_action)

        save_action = Gio.SimpleAction.new("save", None)
        save_action.connect("activate", self.save_callback)
        self.add_action(save_action)

        save_as_action = Gio.SimpleAction.new("save-as", None)
        save_as_action.connect("activate", self.save_as_callback)
        self.add_action(save_as_action)

        quit_action = Gio.SimpleAction.new("quit", None)
        quit_action.connect("activate", self.quit_callback)
        self.add_action(quit_action)


    #                                   #
    # #       Menubar Callbacks       # #
    #                                   #

    def new_project_callback(self, action, parameter):
        print("You clicked \"New\"")

    def open_project_callback(self, action, parameter):
        self._win_main.open_project_callback(action, parameter)

    def save_callback(self, action, parameter):
        print("You clicked \"Save\"") 

    def save_as_callback(self, action, parameter):
        print("You clicked \"Save as..\"") 

    def quit_callback(self, action, parameter):
        self.quit()  


if __name__ == "__main__":
    app = Application()
    app.run(sys.argv)

menubar.ui

<?xml version="1.0" encoding="UTF-8"?>

<interface>
  <menu id="menubar">
    <submenu>
      <attribute name="label" translatable="yes">_Archivo</attribute>
      <section>
        <item>
          <attribute name="label" translatable="yes">Nuevo</attribute>
          <attribute name="action">app.new</attribute>
        </item>
        <item>
          <attribute name="label" translatable="yes">Abrir...</attribute>
          <attribute name="action">app.open</attribute>
          <attribute name="accel">&lt;Primary&gt;o</attribute>
        </item>
      </section>
      <section>
        <item>
          <attribute name ="label" translatable="yes">Guardar</attribute>
          <attribute name="action">app.save</attribute>
          <attribute name="accel">&lt;Primary&gt;s</attribute>
        </item>
        <item>
          <attribute name ="label" translatable="yes">Guardar Como...</attribute>
          <attribute name="action">app.save-as</attribute>
          <!--<attribute name="accel">&lt;Primary&gt;a</attribute>-->
        </item>
      </section>
      <section>
        <item>
          <attribute name ="label" translatable="yes">Salir</attribute>
          <attribute name="action">app.quit</attribute>
          <attribute name="accel">&lt;Primary&gt;q</attribute>
        </item>
      </section>
    </submenu>
    <submenu>
      <attribute name="label" translatable="yes">_Preferencias</attribute>
      <section>
        <item>
          <attribute name="label" translatable="yes">_Idioma</attribute>
          <attribute name="action">app.language</attribute>
        </item>
      </section>
    </submenu>
    <submenu>
      <attribute name="label" translatable="yes">A_yuda</attribute>
      <section>
        <item>
          <attribute name="label" translatable="yes">Acerca de FreeComet</attribute>
          <attribute name="action">app.about</attribute>
        </item>
      </section>
    </submenu>
  </menu>
</interface>

我需要在主应用程序窗口中包含不同小部件的网格。由于我刚接触Gtk,所以我决定从创建一个简单的布局开始,以便我可以更好地理解其背后的逻辑。 ...

python-3.x gtk3 grid-layout
1个回答
0
投票

这是您可能要查看的快速汇总的.ui文件。附带说明,我可以将所有小部件都放在.ui文件中,因为我可以在Glade中查看层次结构。

© www.soinside.com 2019 - 2024. All rights reserved.