playing video in gtk in a window with a menubar

  • Last Update :
  • Techknowledgy :

The revised code:

from pprint
import pprint

import gi
gi.require_version('Gtk', '3.0')
gi.require_version('Gst', '1.0')
gi.require_version('GstVideo', '1.0')

from gi.repository
import Gtk, Gst
Gst.init(None)
Gst.init_check(None)

class GstWidget(Gtk.Box):
   def __init__(self, pipeline):
   super().__init__()
self.connect('realize', self._on_realize)
self._bin = Gst.parse_bin_from_description('videotestsrc', True)

def _on_realize(self, widget):
   pipeline = Gst.Pipeline()
factory = pipeline.get_factory()
gtksink = factory.make('gtksink')
pipeline.add(gtksink)
pipeline.add(self._bin)
self._bin.link(gtksink)
self.pack_start(gtksink.props.widget, True, True, 0)
gtksink.props.widget.show()
pipeline.set_state(Gst.State.PLAYING)

window = Gtk.ApplicationWindow()

header_bar = Gtk.HeaderBar()
header_bar.set_show_close_button(True)
window.set_titlebar(header_bar) # Place 2

widget = GstWidget('videotestsrc')
widget.set_size_request(200, 200)

window.add(widget)

window.show_all()

def on_destroy(win):
   try:
   Gtk.main_quit()
except KeyboardInterrupt:
   pass

window.connect('destroy', on_destroy)

Gtk.main()

Suggestion : 2

last modified January 6, 2022

1._
#include <gtk/gtk.h>

int main(int argc, char *argv[]) {

  GtkWidget *window;
  GtkWidget *vbox;

  GtkWidget *menubar;
  GtkWidget *fileMenu;
  GtkWidget *fileMi;
  GtkWidget *quitMi;

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);
  gtk_window_set_title(GTK_WINDOW(window), "Simple menu");

  vbox = gtk_vbox_new(FALSE, 0);
  gtk_container_add(GTK_CONTAINER(window), vbox);

  menubar = gtk_menu_bar_new();
  fileMenu = gtk_menu_new();

  fileMi = gtk_menu_item_new_with_label("File");
  quitMi = gtk_menu_item_new_with_label("Quit");

  gtk_menu_item_set_submenu(GTK_MENU_ITEM(fileMi), fileMenu);
  gtk_menu_shell_append(GTK_MENU_SHELL(fileMenu), quitMi);
  gtk_menu_shell_append(GTK_MENU_SHELL(menubar), fileMi);
  gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);

  g_signal_connect(G_OBJECT(window), "destroy",
        G_CALLBACK(gtk_main_quit), NULL);

  g_signal_connect(G_OBJECT(quitMi), "activate",
        G_CALLBACK(gtk_main_quit), NULL);

  gtk_widget_show_all(window);

  gtk_main();

  return 0;
}

The menu in the examle has one menu item. By selecting the item, the application quits.

menubar = gtk_menu_bar_new();

The gtk_menu_bar_new creates a new GtkMenuBar.

filemenu = gtk_menu_new();

The fileMenu is set to the File menu item with the gtk_menu_item_set_submenu function. Menus are containers which hold menu items. They are themselves plugged to a particular menu item.

gtk_menu_shell_append(GTK_MENU_SHELL(fileMenu), quitMi);

The quitMi is added to the File menu with the gtk_menu_shell_append function.

gtk_menu_shell_append(GTK_MENU_SHELL(menubar), fileMi);

Suggestion : 3

GtkSettings:gtk-menu-bar-popup-delay has been deprecated since version 3.10 and should not be used in newly-written code.,GtkSettings:gtk-menu-popup-delay has been deprecated since version 3.10 and should not be used in newly-written code.,GtkSettings:gtk-menu-popdown-delay has been deprecated since version 3.10 and should not be used in newly-written code.,GtkSettings:gtk-menu-bar-accel has been deprecated since version 3.10 and should not be used in newly-written code.

Object Hierarchy

    GObject╰── GtkSettings

Includes

#include <gtk /gtk.h>
1
2
3
4
5
6
gtk_init( & argc, & argv);

// make sure the type is realized
g_type_class_unref(g_type_class_ref(GTK_TYPE_IMAGE_MENU_ITEM));

g_object_set(gtk_settings_get_default(), "gtk-enable-animations", FALSE, NULL);

gtk_settings_get_default ()

GtkSettings *
   gtk_settings_get_default(void);

gtk_settings_get_for_screen ()

GtkSettings *
   gtk_settings_get_for_screen(GdkScreen * screen);

Suggestion : 4

Create a GtkApplicationWindow with a menubar (with submenus) set to be shown.,Run the app, and open one of the menubar's items at least once.,Create a callback function that calls gtk_application_window_set_show_menubar() ,Connect this callback to the notify::fullscreened signal of the window

(hello: 203502): Gdk - ERROR **: 13: 32: 39.551: The program 'hello'
received an X Window System error.
This probably reflects a bug in the program.
The error was 'BadWindow (invalid Window parameter)'.
   (Details: serial 2032 error_code 3 request_code 12(core protocol) minor_code 0)
   (Note to programmers: normally, X errors are reported asynchronously; that is, you will receive the error a
      while after causing it.To debug your program, run it with the GDK_SYNCHRONIZE environment variable to change this behavior.You can then get a meaningful backtrace from your debugger
      if you
      break on the gdk_x_error()
      function.)
Trace / breakpoint trap(core dumped)

Suggestion : 5

We are going to build a media player using the GTK+ toolkit, but the concepts apply to other toolkits like Qt, for example. A minimum knowledge of GTK+ will help understand this tutorial.,The error_cb, eos_cb and state_changed_cb are not really worth explaining, since they do the same as in all previous tutorials, but from their own function now.,And this is it! The amount of code in this tutorial might seem daunting but the required concepts are few and easy. If you have followed the previous tutorials and have a little knowledge of GTK, you probably understood this one can now enjoy your very own media player!,The main point is telling GStreamer to output the video to a window of our choice. The specific mechanism depends on the operating system (or rather, on the windowing system), but GStreamer provides a layer of abstraction for the sake of platform independence. This independence comes through the GstVideoOverlay interface, that allows the application to tell a video sink the handler of the window that should receive the rendering.

Regarding this tutorial's structure, we are not going to use forward function definitions anymore: Functions will be defined before they are used. Also, for clarity of explanation, the order in which the snippets of code are presented will not always match the program order. Use the line numbers to locate the snippets in the complete code.

#include <gdk /gdk.h>
   #if defined (GDK_WINDOWING_X11)
   #include <gdk /gdkx.h>
      #elif defined (GDK_WINDOWING_WIN32)
      #include <gdk /gdkwin32.h>
         #elif defined (GDK_WINDOWING_QUARTZ)
         #include <gdk /gdkquartzwindow.h>
            #endif

This tutorial is composed mostly of callback functions, which will be called from GStreamer or GTK+, so let's review the main function, which registers all these callbacks.

int main(int argc, char * argv[]) {
      CustomData data;
      GstStateChangeReturn ret;
      GstBus * bus;

      /* Initialize GTK */
      gtk_init( & argc, & argv);

      /* Initialize GStreamer */
      gst_init( & argc, & argv);

      /* Initialize our data structure */
      memset( & data, 0, sizeof(data));
      data.duration = GST_CLOCK_TIME_NONE;

      /* Create the elements */
      data.playbin = gst_element_factory_make("playbin", "playbin");

      if (!data.playbin) {
         g_printerr("Not all elements could be created.\n");
         return -1;
      }

      /* Set the URI to play */
      g_object_set(data.playbin, "uri", "https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm", NULL);

Standard GStreamer initialization and playbin pipeline creation, along with GTK+ initialization. Not much new.

  /* Connect to interesting signals in playbin */
  g_signal_connect(G_OBJECT(data.playbin), "video-tags-changed", (GCallback) tags_cb, & data);
  g_signal_connect(G_OBJECT(data.playbin), "audio-tags-changed", (GCallback) tags_cb, & data);
  g_signal_connect(G_OBJECT(data.playbin), "text-tags-changed", (GCallback) tags_cb, & data);

All GTK+ widget creation and signal registration happens in this function. It contains only GTK-related function calls, so we will skip over its definition. The signals to which it registers convey user commands, as shown below when reviewing the callbacks.

  /* Instruct the bus to emit signals for each received message, and connect to the interesting signals */
  bus = gst_element_get_bus(data.playbin);
  gst_bus_add_signal_watch(bus);
  g_signal_connect(G_OBJECT(bus), "message::error", (GCallback) error_cb, & data);
  g_signal_connect(G_OBJECT(bus), "message::eos", (GCallback) eos_cb, & data);
  g_signal_connect(G_OBJECT(bus), "message::state-changed", (GCallback) state_changed_cb, & data);
  g_signal_connect(G_OBJECT(bus), "message::application", (GCallback) application_cb, & data);
  gst_object_unref(bus);

Keep in mind that, in order for the bus watches to work (be it a gst_bus_add_watch() or a gst_bus_add_signal_watch()), there must be GLib Main Loop running. In this case, it is hidden inside the GTK+ main loop.

/* Register a function that GLib will call every second */
g_timeout_add_seconds(1, (GSourceFunc) refresh_ui, & data);

Suggestion : 6

Mono will eventually implement a complete compatibility layer for the Windows.Forms user interface toolkit from Microsoft’s .NET platform. Windows.Forms should be seen as a migration strategy: Gtk# is the preferred toolkit for Linux., The -pkg:gtk-sharp option tells the compiler to reference all the Gtk# assemblies. Without it, the compiler wouldn’t know where to find the Gtk namespace. In MonoDevelop, you can control this from the References section of the Projects tab., User activity in one part of the interface often affects another part. Event handlers provide the plumbing.,The widget interaction is simple to understand. The creation of the interface using boxes should also be familiar from the previous lab. However, there are some new features introduced that give the user interface a little more polish and are worth noting:

// 04-gtk/01-basics
using System;
using Gtk;

class MainClass {
   public static void Main(string[] args) {
      Application.Init();

      Window w = new Window("Gtk# Basics");
      Button b = new Button("Hit me");

      // set up event handling: verbose to illustrate
      // the use of delegates.
      w.DeleteEvent += new DeleteEventHandler(Window_Delete);
      b.Clicked += new EventHandler(Button_Clicked);

      // initialize the GUI
      w.Add(b);
      w.SetDefaultSize(200, 100);
      w.ShowAll();

      Application.Run();
   }

   static void Window_Delete(object o, DeleteEventArgs args) {
      Application.Quit();
      args.RetVal = true;
   }

   static void Button_Clicked(object o, EventArgs args) {
      System.Console.WriteLine("Hello, World!");
   }
}
1._
// 04-gtk/01-basics
using System;
using Gtk;

class MainClass {
   public static void Main(string[] args) {
      Application.Init();

      Window w = new Window("Gtk# Basics");
      Button b = new Button("Hit me");

      // set up event handling: verbose to illustrate
      // the use of delegates.
      w.DeleteEvent += new DeleteEventHandler(Window_Delete);
      b.Clicked += new EventHandler(Button_Clicked);

      // initialize the GUI
      w.Add(b);
      w.SetDefaultSize(200, 100);
      w.ShowAll();

      Application.Run();
   }

   static void Window_Delete(object o, DeleteEventArgs args) {
      Application.Quit();
      args.RetVal = true;
   }

   static void Button_Clicked(object o, EventArgs args) {
      System.Console.WriteLine("Hello, World!");
   }
}
$ mcs Main.cs - pkg: gtk - sharp
$ mono Main.exe
3._
Hello, World!
   Hello, World!
   Hello, World!
Hello, World!
   Hello, World!
   Hello, World!
w.DeleteEvent += Window_Delete;
b.Clicked += Button_Clicked;
// 04-gtk/02-layout
using System;
using Gtk;

class MainClass {
   public static void Main(string[] args) {
      Application.Init();
      SetUpGui();
      Application.Run();
   }

   static void SetUpGui() {
      Window w = new Window("Layout Test");

      HBox h = new HBox();
      h.BorderWidth = 6;
      h.Spacing = 6;
      w.Add(h);

      VBox v = new VBox();
      v.Spacing = 6;
      h.PackStart(v, false, false, 0);

      Label l = new Label("Full name:");
      l.Xalign = 0;
      v.PackStart(l, true, false, 0);

      l = new Label("Email address:");
      l.Xalign = 0;
      v.PackStart(l, true, false, 0);

      v = new VBox();
      v.Spacing = 6;
      h.PackStart(v, true, true, 0);

      v.PackStart(new Entry(), true, true, 0);
      v.PackStart(new Entry(), true, true, 0);

      w.DeleteEvent += Window_Delete;
      w.ShowAll();
   }

   static void Window_Delete(object o, DeleteEventArgs args) {
      Application.Quit();
      args.RetVal = true;
   }
}
public void PackStart(Widget child, bool expand, bool fill, uint padding)