Bagaimana cara beralih dari satu jendela ke jendela lain di Gtk.Application dengan Pygobject Gtk+3?

Saya seorang pemula di Gtk dan Python keduanya. Saya menggunakan Python 2.7.14 dan Pygobject(pygi-aio-3.24.1_rev1-setup). Saya memiliki program kerja yang dapat memanggil jendela lain, menampilkan jendela itu dan menutup jendela asli. Yaitu sebagai berikut : Ini adalah program utama.

 #!/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()

Ini adalah file rawa 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>

Ini adalah file lain yang saya tangani dengan mengklik tombol dan juga memanggil jendela berikutnya:

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()

Ini adalah file glade untuk jendela kedua 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>

Program ini bekerja dengan baik. Namun memiliki beberapa kekurangan pada janin. Masalah saya adalah:

  1. Saat beralih ke jendela lain, UI menunjukkan jendela pertama tertutup dan jendela kedua terbuka yang sama sekali tidak dapat diterima oleh pengguna mana pun. Saya rasa saya tidak beralih ke jendela lain dengan benar. Apa cara otentik untuk berpindah jendela dengan cara Gtk.Application dalam melakukan sesuatu? Saya tidak dapat menemukan referensi yang benar di mana pun di web. Tidak dapat menemukan contoh apa pun.

  2. Saya juga ingin kembali ke jendela pertama saya karena aplikasi ini akan memiliki bilah menu dan pengguna akan kembali setelah melakukan tugas kembali ke jendela utama. Bagaimana aku melakukan itu? Contoh apa pun akan sangat membantu.

Beberapa Label tidak dalam bahasa Inggris, jangan pedulikan itu. Terima kasih sebelumnya.


person Rohit S    schedule 02.01.2018    source sumber
comment
jendela pertama ditutup dan jendela kedua terbuka yang sama sekali tidak dapat diterima oleh pengguna mana pun -- jika Anda menghancurkan jendela saat ini dan menampilkan jendela lainnya, sepertinya semuanya berfungsi sesuai permintaan Anda. Anda perlu menjelaskan apa yang Anda harapkan terjadi.   -  person Jussi Kukkonen    schedule 02.01.2018
comment
Saya mencoba untuk beralih ke jendela berikutnya. Saya ingin membuka jendela berikutnya seperti aplikasi normal lainnya. Aplikasi saya akan memiliki jendela login kemudian jendela menu utama tempat saya akan meletakkan bilah menu di atas. dari sana pengguna perlu membuka jendela berbeda dengan menu berbeda dan kembali ke menu utama setelah melakukan tugas. Kode saya tidak melakukan itu dan saya tidak dapat menemukan cara untuk melakukannya.   -  person Rohit S    schedule 03.01.2018
comment
Apakah Anda ingin jendela pertama dan kedua terbuka secara bersamaan? Atau hanya satu jendela dalam satu waktu?   -  person theGtknerd    schedule 04.01.2018
comment
Saya ingin satu jendela pada satu waktu. Masalah saya adalah saya rasa saya tidak menggunakan Gtk.Application sebagaimana yang dimaksudkan untuk digunakan. Pasti ada cara yang tepat untuk mengganti windows. Saya tidak tahu caranya. Tidak ada tutorial yang menunjukkan cara mengelola banyak jendela dan cara mengubahnya. Sumber daya atau contoh apa pun akan sangat membantu.   -  person Rohit S    schedule 05.01.2018
comment
Ini bisa menjadi pembicaraan yang panjang. Mengapa Anda tidak melihat saya di obrolan Gtk?   -  person theGtknerd    schedule 06.01.2018


Jawaban (1)


Ini file .pynya

#!/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())

Dan file pygtk_stack.ui:

<?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>

Versi glade saya tidak mendukung GtkStack, jadi contoh ini agak hacky. Semoga Anda dapat mengetahui apa yang Anda butuhkan. Saya menambahkan transisi yang dapat Anda nonaktifkan jika Anda tidak menyukainya.

person theGtknerd    schedule 06.01.2018
comment
Ini yang saya inginkan tetapi ini tidak menggunakan Gtk.Application. Saya sedang berpikir untuk menggunakan ApplicationWindow dengan Gtk.Application. Apakah mungkin melakukan ini dengan kelas Gtk.Application? - person Rohit S; 06.01.2018
comment
Apakah Anda secara khusus memerlukan Aplikasi Gtk? Bukan untuk meragukanmu atau apapun, hanya memastikan saja. - person theGtknerd; 06.01.2018
comment
@RohitS Fitur GtkApplication manakah yang Anda perlukan? - person theGtknerd; 06.01.2018
comment
Saya mengharapkan objek pusat di mana saya dapat menambah dan menghapus file glade saya sesuai kebutuhan. Saya mengharapkan lengkungan seperti MVC. Saya membaca halaman ini- python-gtk-3-tutorial.readthedocs .io/en/latest/application.html Sepertinya Gtk.Application dibuat untuk melakukan hal seperti ini. Inilah mengapa saya menginginkan Gtk.Application. - person Rohit S; 06.01.2018
comment
@RohitS Jika Anda ingin memiliki aplikasi tipe MVC, GtkApplication tidak akan melakukan apa pun untuk Anda (tetapi menciptakan lebih banyak pekerjaan). Silakan kirim pertanyaan baru yang menguraikan apa yang telah Anda katakan kepada saya, tautkan kembali ke sini, dan saya akan mencoba membantu Anda. - person theGtknerd; 06.01.2018
comment
saya telah mengajukan pertanyaan terpisah. Berikut ini tautannya- stackoverflow.com/questions/48135506/ - person Rohit S; 07.01.2018