Jednopoložkové kontejnery

Most single-item container widgets have set_child() and unset_child() methods for the child widget. Gtk::Button and Gtk::Window are technically single-item containers, but we have discussed them already elsewhere.

Probírán je také widget Gtk::Paned, který umožňuje rozdělit okno do dvou oddělených „panelů“. Tento widget ve skutečnosti obsahuje dva synovské widgety, ale tento počet je pevně dán, takže je správné jej zařadit sem.

9.1.1. Rám (Frame)

Frames can enclose one or a group of widgets within a box, optionally with a title. For instance, you might place a group of ToggleButtons or CheckButtons in a Frame.

Reference

9.1.1.1. Příklad

Obrázek 9-1Rám (Frame)

Source Code

File: examplewindow.h (For use with gtkmm 4)

#ifndef GTKMM_EXAMPLEWINDOW_H
#define GTKMM_EXAMPLEWINDOW_H

#include <gtkmm.h>

class ExampleWindow : public Gtk::Window
{
public:
  ExampleWindow();
  virtual ~ExampleWindow();

protected:

  //Child widgets:
  Gtk::Frame m_Frame;
};

#endif //GTKMM_EXAMPLEWINDOW_H

File: main.cc (For use with gtkmm 4)

#include "examplewindow.h"
#include <gtkmm/application.h>

int main(int argc, char *argv[])
{
  auto app = Gtk::Application::create("org.gtkmm.example");

  //Shows the window and returns when it is closed.
  return app->make_window_and_run<ExampleWindow>(argc, argv);
}

File: examplewindow.cc (For use with gtkmm 4)

#include "examplewindow.h"

ExampleWindow::ExampleWindow()
{
 /* Set some window properties */
  set_title("Frame Example");
  set_size_request(300, 300);

  /* Sets the margin around the frame. */
  m_Frame.set_margin(10);

  set_child(m_Frame);

  /* Set the frames label */
  m_Frame.set_label("Gtk::Frame Widget");

  /* Align the label at the right of the frame */
  m_Frame.set_label_align(Gtk::Align::END);
}

ExampleWindow::~ExampleWindow()
{
}

9.1.2. Dvojitý panel (Paned)

Dvojitý panel rozdělí widget na dvě části oddělené rozdělovací čárou. Oba panely mohou být orientované buďto vodorovně (vedle sebe) nebo svisle (nad sebou).

Unlike the other widgets in this section, pane widgets contain not one but two child widgets, one in each pane. Therefore, you should use set_start_child() and set_end_child() instead of a set_child() method.

Rozdělovací čáru můžete umístit pomocí metody set_position(), a nejspíše to budete potřebovat udělat.

Reference

9.1.2.1. Příklad

Obrázek 9-2Dvojitý panel (Paned)

Source Code

File: examplewindow.h (For use with gtkmm 4)

#ifndef GTKMM_EXAMPLEWINDOW_H
#define GTKMM_EXAMPLEWINDOW_H

#include "messageslist.h"
#include "messagetext.h"
#include <gtkmm.h>

class ExampleWindow : public Gtk::Window
{
public:
  ExampleWindow();
  virtual ~ExampleWindow();

protected:

  //Child widgets:
  Gtk::Paned m_VPaned;
  MessagesList m_MessagesList;
  MessageText m_MessageText;
};

#endif //GTKMM_EXAMPLEWINDOW_H

File: messageslist.h (For use with gtkmm 4)

#ifndef GTKMM_EXAMPLE_MESSAGESLIST_H
#define GTKMM_EXAMPLE_MESSAGESLIST_H

#include <gtkmm.h>

class MessagesList: public Gtk::ScrolledWindow
{
public:
  MessagesList();
  virtual ~MessagesList();

  class ModelColumns : public Gtk::TreeModel::ColumnRecord
  {
  public:

    ModelColumns()
    { add(m_col_text); }

    Gtk::TreeModelColumn<Glib::ustring> m_col_text;
  };

  ModelColumns m_Columns;

protected:
  Glib::RefPtr<Gtk::ListStore> m_refListStore; //The Tree Model.
  Gtk::TreeView m_TreeView; //The Tree View.
};
#endif //GTKMM_EXAMPLE_MESSAGESLIST_H

File: messagetext.h (For use with gtkmm 4)

#ifndef GTKMM_EXAMPLE_MESSAGETEXT_H
#define GTKMM_EXAMPLE_MESSAGETEXT_H

#include <gtkmm.h>

class MessageText : public Gtk::ScrolledWindow
{
public:
  MessageText();
  virtual ~MessageText();

  void insert_text();

protected:
  Gtk::TextView m_TextView;
};

#endif //GTKMM_EXAMPLE_MESSAGETEXT_H

File: main.cc (For use with gtkmm 4)

#include "examplewindow.h"
#include <gtkmm/application.h>

int main(int argc, char *argv[])
{
  auto app = Gtk::Application::create("org.gtkmm.example");

  //Shows the window and returns when it is closed.
  return app->make_window_and_run<ExampleWindow>(argc, argv);
}

File: examplewindow.cc (For use with gtkmm 4)

#include "examplewindow.h"

ExampleWindow::ExampleWindow()
: m_VPaned(Gtk::Orientation::VERTICAL)
{
  set_title ("Paned Windows");
  set_default_size(450, 400);
  m_VPaned.set_margin(10);

  /* Add a vpaned widget to our toplevel window */
  set_child(m_VPaned);

  /* Now add the contents of the two halves of the window */
  m_VPaned.set_start_child(m_MessagesList);
  m_VPaned.set_end_child(m_MessageText);
}

ExampleWindow::~ExampleWindow()
{
}

File: messageslist.cc (For use with gtkmm 4)

#include "messageslist.h"
#include <sstream>

MessagesList::MessagesList()
{
  /* Create a new scrolled window, with scrollbars only if needed */
  set_policy(Gtk::PolicyType::AUTOMATIC, Gtk::PolicyType::AUTOMATIC);

  set_child(m_TreeView);

  /* create list store */
  m_refListStore = Gtk::ListStore::create(m_Columns);

  m_TreeView.set_model(m_refListStore);

  /* Add some messages to the window */
  for(int i = 0; i < 10; ++i)
  {
    std::ostringstream text;
    text << "message #" << i;

    auto row = *(m_refListStore->append());
    row[m_Columns.m_col_text] = text.str();
  }

  //Add the Model's column to the View's columns:
  m_TreeView.append_column("Messages", m_Columns.m_col_text);
}

MessagesList::~MessagesList()
{
}

File: messagetext.cc (For use with gtkmm 4)

#include "messagetext.h"

MessageText::MessageText()
{
  set_policy(Gtk::PolicyType::AUTOMATIC, Gtk::PolicyType::AUTOMATIC);

  set_child(m_TextView);
  insert_text();
}

MessageText::~MessageText()
{
}

void MessageText::insert_text()
{
  auto refTextBuffer = m_TextView.get_buffer();

  auto iter = refTextBuffer->get_iter_at_offset(0);
  refTextBuffer->insert(iter,
    "From: pathfinder@nasa.gov\n"
    "To: mom@nasa.gov\n"
    "Subject: Made it!\n"
    "\n"
    "We just got in this morning. The weather has been\n"
    "great - clear but cold, and there are lots of fun sights.\n"
    "Sojourner says hi. See you soon.\n"
    " -Path\n");
}

9.1.3. Okno s posuvníky (ScrolledWindow)

ScrolledWindow widgets create a scrollable area. You can insert any type of widget into a ScrolledWindow, and it will be accessible regardless of its size by using the scrollbars. Note that ScrolledWindow is not a Gtk::Window despite the slightly misleading name.

Scrolled windows have scrollbar policies which determine whether the Scrollbars will be displayed. The policies can be set with the set_policy() method. The policy may be for instance Gtk::PolicyType::AUTOMATIC or Gtk::PolicyType::ALWAYS. Gtk::PolicyType::AUTOMATIC will cause the scrolled window to display the scrollbar only if the contained widget is larger than the visible area. Gtk::PolicyType::ALWAYS will cause the scrollbar to be displayed always.

Reference

9.1.3.1. Příklad

Zde je jednoduchý příklad, který sbalí 100 přepínacích tlačítek do okna s posuvníky. Zkuste měnit velikost okna, abyste viděli, jak posuvníky reagují.

Obrázek 9-3Okno s posuvníky (ScrolledWindow)

Source Code

File: examplewindow.h (For use with gtkmm 4)

#ifndef GTKMM_EXAMPLEWINDOW_H
#define GTKMM_EXAMPLEWINDOW_H

#include <gtkmm.h>

class ExampleWindow : public Gtk::Dialog
{
public:
  ExampleWindow();
  virtual ~ExampleWindow();

protected:
  //Signal handlers:
  void on_dialog_response(int response_id);

  //Child widgets:
  Gtk::ScrolledWindow m_ScrolledWindow;
  Gtk::Grid m_Grid;
};

#endif //GTKMM_EXAMPLEWINDOW_H

File: main.cc (For use with gtkmm 4)

#include "examplewindow.h"
#include <gtkmm/application.h>

int main(int argc, char *argv[])
{
  auto app = Gtk::Application::create("org.gtkmm.example");

  //Shows the window and returns when it is closed.
  return app->make_window_and_run<ExampleWindow>(argc, argv);
}

File: examplewindow.cc (For use with gtkmm 4)

#include "examplewindow.h"
#include <iostream>

ExampleWindow::ExampleWindow()
{
  set_title("Gtk::ScrolledWindow example");
  set_size_request(300, 300);

  m_ScrolledWindow.set_margin(10);

  /* the policy is one of Gtk::PolicyType::AUTOMATIC, or Gtk::PolicyType::ALWAYS.
   * Gtk::PolicyType::AUTOMATIC will automatically decide whether you need
   * scrollbars, whereas Gtk::PolicyType::ALWAYS will always leave the scrollbars
   * there.  The first one is the horizontal scrollbar, the second,
   * the vertical. */
  m_ScrolledWindow.set_policy(Gtk::PolicyType::AUTOMATIC, Gtk::PolicyType::ALWAYS);
  m_ScrolledWindow.set_expand();

  get_content_area()->append(m_ScrolledWindow);

  /* set the spacing to 10 on x and 10 on y */
  m_Grid.set_row_spacing(10);
  m_Grid.set_column_spacing(10);

  /* pack the grid into the scrolled window */
  m_ScrolledWindow.set_child(m_Grid);

  /* this simply creates a grid of toggle buttons
   * to demonstrate the scrolled window. */
  for(int i = 0; i < 10; i++)
  {
     for(int j = 0; j < 10; j++)
     {
        char buffer[32];
        sprintf(buffer, "button (%d,%d)\n", i, j);
        auto pButton = Gtk::make_managed<Gtk::ToggleButton>(buffer);
        m_Grid.attach(*pButton, i, j, 1, 1);
     }
  }

  /* Add a "close" button to the bottom of the dialog */
  add_button("_Close", Gtk::ResponseType::CLOSE);
  signal_response().connect(sigc::mem_fun(*this, &ExampleWindow::on_dialog_response));

  /* This makes it so the button is the default.
   * Simply hitting the "Enter" key will cause this button to activate. */
  set_default_response(Gtk::ResponseType::CLOSE);
}

ExampleWindow::~ExampleWindow()
{
}

void ExampleWindow::on_dialog_response(int response_id)
{
  switch (response_id)
  {
  case Gtk::ResponseType::CLOSE:
  case Gtk::ResponseType::DELETE_EVENT:
    hide();
    break;
  default:
    std::cout << "Unexpected response_id=" << response_id << std::endl;
    break;
  }
}

9.1.4. AspectFrame

Widget AspectFrame vypadá podobně jako widget Frame, ale navíc dodržuje poměr stran (poměr mezi šířkou a výškou) synovského widgetu. Využívá k tomu doplňování prázdného místa okolo widgetu v případě potřeby. Využít se dá například k zobrazení fotografie, aniž by ji uživatel při změně velikosti vodorovně nebo svisle deformoval.

Reference

9.1.4.1. Příklad

Následující program použív Gtk::AspectFrame k zobrazení kreslící oblasti, jejíž poměr stran bude vždy 2∶1, bez ohledu na to, jak uživatel mění velikost nadřazeného okna.

Obrázek 9-4AspectFrame

Source Code

File: examplewindow.h (For use with gtkmm 4)

#ifndef GTKMM_EXAMPLEWINDOW_H
#define GTKMM_EXAMPLEWINDOW_H

#include <gtkmm.h>

class ExampleWindow : public Gtk::Window
{
public:
  ExampleWindow();
  virtual ~ExampleWindow();

protected:

  //Child widgets:
  Gtk::AspectFrame m_AspectFrame;
  Gtk::Frame m_Frame;
  Gtk::DrawingArea m_DrawingArea;
};

#endif //GTKMM_EXAMPLEWINDOW_H

File: main.cc (For use with gtkmm 4)

#include "examplewindow.h"
#include <gtkmm/application.h>

int main(int argc, char *argv[])
{
  auto app = Gtk::Application::create("org.gtkmm.example");

  //Shows the window and returns when it is closed.
  return app->make_window_and_run<ExampleWindow>(argc, argv);
}

File: examplewindow.cc (For use with gtkmm 4)

#include "examplewindow.h"

ExampleWindow::ExampleWindow()
: m_AspectFrame(
    Gtk::Align::CENTER, /* center x */
    Gtk::Align::CENTER, /* center y */
    2.0, /* xsize/ysize = 2 */
    false /* ignore child's aspect */),
  m_Frame("2x1" /* label */)
{
  set_title("Aspect Frame");

  // Set a child widget to the aspect frame */
  // Ask for a 200x200 window, but the AspectFrame will give us a 200x100
  // window since we are forcing a 2x1 aspect ratio */
  m_DrawingArea.set_content_width(200);
  m_DrawingArea.set_content_height(200);
  m_Frame.set_child(m_DrawingArea);
  m_AspectFrame.set_child(m_Frame);
  m_AspectFrame.set_margin(10);

  // Add the aspect frame to our toplevel window:
  set_child(m_AspectFrame);
}

ExampleWindow::~ExampleWindow()
{
}

9.1.5. Other Single-item Containers

There are other single-item containers. See the reference documentation for a complete list. Here are links to some example programs that show containers, which are not mentioned elsewhere in this tutorial.

Source Code, Expander

Source Code, Popover