@AlexVWill

Почему закрывается приложение GTK?

Пытаюсь написать свою собственную служебную утилиту с параллельным освоением Python3+GTK для Linux, и наткнулся для меня на непонятное.
Вот код:
spoiler
# Load Gtk
import gi
gi.require_version('Gtk', '3.0')
gi.require_version ('AppIndicator3', '0.1')
from gi.repository import Gtk, AppIndicator3 
# When the application is launched…
import os

class SystemTrayApp: 
    def __init__(self): 
        self.app_name = "My System Tray App" 
        self.icon_path = os.path.join(os.path.dirname(__file__), "icon.png") 
 
        self.indicator = AppIndicator3.Indicator.new( 
            self.app_name, self.icon_path, 
            AppIndicator3.IndicatorCategory.APPLICATION_STATUS 
        ) 
        self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE) 
 
        self.menu = Gtk.Menu() 
        self.menu_items = { 
            "Open": self.open_app, 
            "Quit": Gtk.main_quit 
        } 
 
        for label, callback in self.menu_items.items(): 
            menu_item = Gtk.MenuItem(label) 
            menu_item.connect("activate", lambda _: callback()) 
            self.menu.append(menu_item) 
 
        self.menu.show_all() 
        self.indicator.set_menu(self.menu) 
         
    def open_app(self, _): 
        # Add your app's functionality here
        win = Gtk.ApplicationWindow(application=app)
        btn = Gtk.Button(label="Hello, World!")
        btn.connect('clicked', lambda x: win.close())
        win.set_child(btn)
        win.present() 
        #print("Opening the app") 

if __name__ == "__main__": 
    app = SystemTrayApp() 
    Gtk.main()

который запускается, и виден в системном трее, если нажать на иконку приложения в трее появляется меню. Но если нажать на пункт меню Open, то окошко Hello world, которое по идее должно было бы открыться не открывается, а приложение закрывается. Вопрос - а как бы сделать так, чтобы окошко открывалось, а приложение не закрывалось? Где тут ошибка?
Спасибо.
  • Вопрос задан
  • 63 просмотра
Решения вопроса 1
2ord
@2ord
win = Gtk.ApplicationWindow(application=app)
что за переменная app?

Изначально сделал так, заменив кусок
spoiler
for label, callback in self.menu_items.items():
            menu_item = Gtk.MenuItem(label)
            menu_item.connect("activate", lambda _: callback())
            self.menu.append(menu_item)

        self.menu.show_all()
        self.indicator.set_menu(self.menu)

    def open_app(self, _):
        # Add your app's functionality here
        win = Gtk.ApplicationWindow(application=app)
        btn = Gtk.Button(label="Hello, World!")
        btn.connect('clicked', lambda x: win.close())
        win.set_child(btn)
        win.present()
        #print("Opening the app")

на
spoiler
for label, callback in self.menu_items.items():
            menu_item = Gtk.MenuItem(label=label)
            menu_item.connect("activate", callback)
            self.menu.append(menu_item)

        self.menu.show_all()
        self.indicator.set_menu(self.menu)

        self.application = Gtk.Application()
        self.application.connect('activate', self.on_activate)
        self.application_window = None

    def open_app(self, _):
        # Add your app's functionality here
        self.application.register(None)  # Регистрация приложения
        self.application.activate()      # Активация приложения

    def on_activate(self, app):
        if not self.application_window:
            self.application_window = Gtk.ApplicationWindow(application=app)
            btn = Gtk.Button(label="Hello, World!")
            btn.connect('clicked', lambda x: self.application_window.close())
            self.application_window.add(btn)
            self.application_window.show_all()
        else:
            self.application_window.present()

но были другие ошибки в работе, поэтому после их учета стало так:
spoiler
for label, callback in self.menu_items.items():
            menu_item = Gtk.MenuItem(label=label)
            menu_item.connect("activate", callback)
            self.menu.append(menu_item)

        self.menu.show_all()
        self.indicator.set_menu(self.menu)

        self.application = Gtk.Application()
        self.application.connect('activate', self.on_activate)
        self.application_window = None

    def open_app(self, _):
        # Add your app's functionality here
        if not self.application_window:
            self.application.register(None)
        self.application.activate()

    def on_activate(self, app):
        if not self.application_window:
            self.create_window(app)
        else:
            self.application_window.present()

    def create_window(self, app):
        self.application_window = Gtk.ApplicationWindow(application=app)
        self.application_window.set_title("My System Tray App")
        self.application_window.set_default_size(200, 200)
        self.application_window.connect("delete-event", self.on_window_close)

        btn = Gtk.Button(label="Hello, World!")
        btn.connect('clicked', lambda x: self.application_window.hide())  # скрываем окно вместо закрытия
        self.application_window.add(btn)
        self.application_window.show_all()

    def on_window_close(self, window, event):
        self.application_window = None  # устанавливаем в None для воссоздания окна в следующей активации
        window.destroy()
        return True  # значит, уже обработали событие
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы