0
votes

I am a beginner in Gtk and Python both. I am using Python 2.7.14 and Pygobject(pygi-aio-3.24.1_rev1-setup). I have a working program that can call other window, show that window and close the original window. Which is as follows: This is the main program.

 #!/usr/bin/python
# coding=utf8

from gi.repository import GObject, Gio, Gdk, Gtk
import blnkwin1

class MyApplication(Gtk.Application):
    # Main initialization routine
    def __init__(self, application_id, flags):
        Gtk.Application.__init__(self, application_id=application_id, flags=flags)
        self.connect("activate", self.new_window)

    def new_window(self, *args):
        AppWindow(self)

class AppWindow(object):
    def __init__(self, application):
        self.Application = application

        # Read GUI from file and retrieve objects from Gtk.Builder
        try:
            GtkBuilder = Gtk.Builder.new_from_file("Lgnwin.glade")
            GtkBuilder.connect_signals(blnkwin.lgn(application,GtkBuilder))
        except GObject.GError:
            print("Error reading GUI file")
            raise

        # Fire up the main window
        self.MainWindow = GtkBuilder.get_object("LoginWindow")
        self.MainWindow.set_application(application)
        self.MainWindow.show()
        if GtkBuilder.get_application.get_window_by_id(2):
            GtkBuilder.get_application.get_window_by_id(2).destroy()

    def close(self, *args):
            self.MainWindow.destroy()

# Starter
def main():
    # Initialize GTK Application
    Application = MyApplication("com.b.example", Gio.ApplicationFlags.FLAGS_NONE)

    # Start GUI
    Application.run()

if __name__ == "__main__": main()

This is glade file Lgnwin.glade:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.19.0 -->
<interface>
  <requires lib="gtk+" version="3.12"/>
  <object class="GtkApplicationWindow" id="LoginWindow">
    <property name="width_request">800</property>
    <property name="height_request">600</property>
    <property name="can_focus">False</property>
    <property name="resizable">False</property>
    <property name="icon">icon100.png</property>
    <child>
      <object class="GtkGrid" id="grid1">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <child>
          <object class="GtkBox" id="box1">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="halign">center</property>
            <property name="valign">center</property>
            <property name="hexpand">True</property>
            <property name="vexpand">True</property>
            <property name="orientation">vertical</property>
            <child>
              <object class="GtkLabel" id="label1">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="vexpand">True</property>
                <property name="label" translatable="yes">लॉगीन करा</property>
                <attributes>
                  <attribute name="font-desc" value="Mangal 16"/>
                </attributes>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">0</property>
              </packing>
            </child>
            <child>
              <object class="GtkLabel" id="label2">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="margin_top">5</property>
                <property name="margin_bottom">5</property>
                <property name="label" translatable="yes">युजरनेम</property>
                <attributes>
                  <attribute name="font-desc" value="&lt;Enter Value&gt; 14"/>
                  <attribute name="foreground" value="#201f4a4a8787"/>
                </attributes>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">1</property>
              </packing>
            </child>
            <child>
              <object class="GtkEntry" id="uname">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="margin_top">2</property>
                <property name="margin_bottom">2</property>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">2</property>
              </packing>
            </child>
            <child>
              <object class="GtkLabel" id="label3">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="margin_top">5</property>
                <property name="margin_bottom">5</property>
                <property name="label" translatable="yes">पासवर्ड</property>
                <attributes>
                  <attribute name="font-desc" value="&lt;Enter Value&gt; 14"/>
                  <attribute name="foreground" value="#201f4a4a8787"/>
                </attributes>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">3</property>
              </packing>
            </child>
            <child>
              <object class="GtkEntry" id="pswd">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="margin_top">2</property>
                <property name="margin_bottom">2</property>
                <property name="visibility">False</property>
                <property name="invisible_char">●</property>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">4</property>
              </packing>
            </child>
            <child>
              <object class="GtkButton" id="loginbtn">
                <property name="label" translatable="yes">लॉगीन</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <property name="margin_top">10</property>
                <signal name="clicked" handler="loginbtn_clicked_cb" swapped="no"/>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">5</property>
              </packing>
            </child>
          </object>
          <packing>
            <property name="left_attach">1</property>
            <property name="top_attach">1</property>
          </packing>
        </child>
        <child>
          <placeholder/>
        </child>
        <child>
          <placeholder/>
        </child>
        <child>
          <placeholder/>
        </child>
      </object>
    </child>
  </object>
</interface>

This is another file in which I am handling button click and also calling next window:

from gi.repository import GObject, Gio, Gdk, Gtk
class lgn(object):
    def __init__(self, application, builder):
        self.Application = application
def loginbtn_clicked_cb(self, button):
    builder = Gtk.Builder.new_from_file("blankwin.glade")
    builder.connect_signals(self)
    self.lgnwins = builder.get_object("applicationwindow1")
    self.lgnwins.set_application(self.Application)

    self.Application.get_window_by_id(2).set_visible(True)
    self.Application.get_window_by_id(1).destroy()

This is glade file for second window blankwin.glade:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.19.0 -->
<interface>
  <requires lib="gtk+" version="3.12"/>
  <object class="GtkApplicationWindow" id="applicationwindow1">
    <property name="can_focus">False</property>
    <property name="default_width">800</property>
    <property name="default_height">600</property>
    <child>
      <object class="GtkLabel" id="label1">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="label" translatable="yes">This is Just a blank Window</property>
      </object>
    </child>
  </object>
</interface>

This program is working alright. But has several fetal flaws.My problem is:

  1. When switching to another window UI is showing the first window closes and second window opens which is totally unacceptable to any user. I don't think I am switching to other window correctly. What is the authentic way to switch windows in Gtk.Application way of doing things? I could not find correct reference anywhere on web. Couldn't find any examples.

  2. I also want to go back to my first window as this application will have menu bar and user will return after doing the task back to the main window. How do I do that? Any Examples would be helpful.

Some Labels are not in english don't mind them.Thanks in Advance.

1
"the first window closes and second window opens which is totally unacceptable to any user" -- if you destroy the current window and show another, that sounds like everything is working as you requested. You need to explain what you expect to happen.Jussi Kukkonen
I am trying to switch to next window. I want to go to next window like any other normal application will. My app will have login window then main menu window where I will put menu bar on top. from there user need to open different windows with different menus and get back to main menu after doing the task. My code is not doing that and I could not find any way to do it.Rohit S
Do you want both first and second window open at the same time? Or just one window at a time?theGtknerd
I want one window at a time. My problem is I think I am not using Gtk.Application as it is intended to be used. There must be a right way to change windows. I cant figure out how. None of the tutorials show how to manage multiple windows and how to change between them. Any resources or example will be very helpful.Rohit S
This could become a lengthy conversation. Why don't you see me in Gtk chat?theGtknerd

1 Answers

1
votes

Here is the .py file

#!/usr/bin/env python3

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
import os, sys

UI_FILE = "pygtk_stack.ui"


class GUI:
    def __init__(self):

        self.builder = Gtk.Builder()
        self.builder.add_from_file(UI_FILE)
        self.builder.connect_signals(self)

        self.stack = Gtk.Stack()
        self.stack.set_transition_type(Gtk.StackTransitionType.CROSSFADE)
        self.view_one = self.builder.get_object('box1')
        self.view_two = self.builder.get_object('box2')
        self.stack.add_named(self.view_one, "view one" )
        self.stack.add_named(self.view_two, "view two" )
        window = self.builder.get_object('window')
        window.add(self.stack)
        window.show_all()

    def view_two_activated (self, meuitem):
        self.stack.set_visible_child(self.view_two)

    def view_one_clicked (self, button):
        self.stack.set_visible_child(self.view_one)

    def on_window_destroy(self, window):
        Gtk.main_quit()

def main():
    app = GUI()
    Gtk.main()

if __name__ == "__main__":
    sys.exit(main())

And the pygtk_stack.ui file:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
  <requires lib="gtk+" version="3.12"/>
  <object class="GtkBox" id="box1">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="orientation">vertical</property>
    <child>
      <object class="GtkMenuBar" id="menubar1">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <child>
          <object class="GtkMenuItem" id="menuitem3">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="label" translatable="yes">_View</property>
            <property name="use_underline">True</property>
            <child type="submenu">
              <object class="GtkMenu" id="menu1">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <child>
                  <object class="GtkMenuItem" id="menuitem1">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="label" translatable="yes">View 2</property>
                    <property name="use_underline">True</property>
                    <signal name="activate" handler="view_two_activated" swapped="no"/>
                  </object>
                </child>
              </object>
            </child>
          </object>
        </child>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="fill">True</property>
        <property name="position">0</property>
      </packing>
    </child>
    <child>
      <placeholder/>
    </child>
  </object>
  <object class="GtkBox" id="box2">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="orientation">vertical</property>
    <child>
      <object class="GtkButton" id="button1">
        <property name="label" translatable="yes">Go back</property>
        <property name="visible">True</property>
        <property name="can_focus">True</property>
        <property name="receives_default">True</property>
        <signal name="clicked" handler="view_one_clicked" swapped="no"/>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="fill">True</property>
        <property name="position">0</property>
      </packing>
    </child>
    <child>
      <object class="GtkLabel" id="label1">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="label" translatable="yes">Second view</property>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="fill">True</property>
        <property name="position">1</property>
      </packing>
    </child>
  </object>
  <object class="GtkWindow" id="window">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="title" translatable="yes">window</property>
    <property name="default_width">500</property>
    <property name="default_height">400</property>
    <signal name="destroy" handler="on_window_destroy" swapped="no"/>
    <child>
      <placeholder/>
    </child>
  </object>
</interface>

My version of glade does not support GtkStack, so this example is a bit hacky. Hopefully you can figure out what you need. I added a transition you can disable if you don't like it.