Как отобразить окно уже активного приложения при попытке открыть новый экземпляр этого приложения

Я знаю, что вопрос немного расплывчатый. Я попытаюсь объяснить лучше ниже:

Мое приложение (python / gtk) в основном индикатор. Используя этот индикатор, вы можете показать / скрыть главное окно.

Когда я пытался открыть новый экземпляр приложения, я сделал его так, чтобы он проверял, запущено ли уже приложение. Если это так, то попытка запустить приложение будет прервана.

Теперь я хочу настроить его, поэтому перед прерыванием я хочу вывести главное окно уже активного приложения на передний план. Даже если это окно еще не открыто.

Поэтому я считаю, что мой вопрос: как я могу получить (глобальную?) Переменную / экземпляр моего уже активного приложения из моего нового приложения? (чтобы я мог вывести мое главное окно на передний план)

РЕДАКТИРОВАТЬ:

Я только что нашел этот метод в API: GtkWindow - set_startup_id () .

Это говорит: Обычно, идентификатор запуска управляется автоматически, и вы должны использовать эту функцию только в особых случаях, таких как перенос фокуса с других процессов.

Таким образом, это означает, что должна быть возможность перенести фокус на окно из другого процесса. Но как мне получить этот идентификатор? И как бы я использовал этот идентификатор, чтобы вывести его на передний план?

6
задан 15 July 2012 в 04:13

3 ответа

Благодаря великолепному ответу xubuntix , я создал модуль, который делает его простым:

"""
Allow an application to activate a running instance of itself instead of
starting another instance.
"""

import sys

import gtk
import dbus.service
from dbus.mainloop.glib import DBusGMainLoop

def _get_path(app_id):
    return '/' + app_id.replace('.', '/')

def listen_for_activation(app_id, window):
    """
    Listen for 'activate' events. If one is sent, activate 'window'.
    """
    class MyDBUSService(dbus.service.Object):                                                                                                       
        def __init__(self, window):
            self.window = window

            bus_name = dbus.service.BusName(app_id, bus=dbus.SessionBus())                                                     
            dbus.service.Object.__init__(self, bus_name, _get_path(app_id))

        @dbus.service.method(app_id)                                                                         
        def activate(self):
            print "The process was activated by another instance."
            self.window.present()

    DBusGMainLoop(set_as_default=True)
    _myservice = MyDBUSService(window)

def activate_if_already_running(app_id):
    """
    Activate the existing window if it's already running. Return True if found
    an existing window, and False otherwise.
    """
    bus = dbus.SessionBus()
    try:
        programinstance = bus.get_object(app_id, _get_path(app_id))
        activate = programinstance.get_dbus_method('activate', app_id)
    except dbus.exceptions.DBusException:
        return False
    else:
        print "A running process was found. Activating it."
        activate()
        return True
    finally:
        bus.close()

def test():
    APP_ID = 'com.example.myapp'

    activated = activate_if_already_running(APP_ID)
    if activated:
        sys.exit(0)

    w = gtk.Window()
    b = gtk.Button("Hello!")
    b.set_size_request(200, 200)
    w.add(b)
    w.connect('delete-event', gtk.main_quit)
    w.show_all()

    listen_for_activation(APP_ID, w)

    gtk.main()

if __name__ == '__main__':
    test()

Пожалуйста, обратитесь к следующей сути для любых дальнейших изменений в коде выше: [ 115]

0
ответ дан 15 July 2012 в 04:13

Не уверен, что это ID, который вы ищете:

Откройте System Monitor, перейдя в Приложения, нажав CTRL+ALT+DEL или набрав в терминале gnome-system-monitor.

Перейдите на вкладку View в верхней панели. Выберите All Processes и Зависимости. Перейдите на вкладку Edit в верхней панели и откройте Preferences.

На вкладке Processes в разделе Information Fields выберите ID.

Затем попробуйте найти свою программу в списке. Удачи!

0
ответ дан 15 July 2012 в 04:13

Позволяет запускаются путем высказывания, что существуют партии и много путей. Вы обычно устанавливаете маркер/идентификатор, когда программа запускается, поэтому более поздние экземпляры могут искать существование того маркера.

Я опишу один путь, который использует dbus.

Обзор:

При запуске программы это может зарегистрировать себя на сессии dbus под уникальным именем (например, "org.nicklemaire.myprogram"). Дальнейшие экземпляры программы могут проверить, регистрируется ли такой accesspoint уже, и если так, скажите программу, что сделать через эту dbus точку доступа (например, получить фокус, открыть веб-сайт, играть песню). Последняя часть, вероятно, необходима, когда Вы хотите поведение, подобное "Firefox askubuntu.com", который открывает эту страницу на новой вкладке в уже рабочем экземпляре.

Код:

#!/usr/bin/env python                                                                                                                           
import sys                                                                                                                                      
import gtk                                                                                                                                      
import dbus                                                                                                                                     
import dbus.service                                                                                                                             
from dbus.mainloop.glib import DBusGMainLoop                                                                                                    
from multiprocessing import Process                                                                                                             

class MyDBUSService(dbus.service.Object):                                                                                                       
    def __init__(self):                                                                                                                         
        bus_name = dbus.service.BusName('org.nicklemaire.myprogram', bus=dbus.SessionBus())                                                     
        dbus.service.Object.__init__(self, bus_name, '/org/nicklemaire/myprogram')                                                              

    @dbus.service.method('org.nicklemaire.myprogram', in_signature='s')                                                                         
    def startup(self, arg):                                                                                                                     
        print "got the following parameter from another instance:", arg                                                                         

def call_instance():                                                                                                                            
    try:                                                                                                                                        
        bus = dbus.SessionBus()                                                                                                                 
        programinstance = bus.get_object('org.nicklemaire.myprogram',  '/org/nicklemaire/myprogram')                                            
        bus = dbus.SessionBus()                                                                                                                 
        programinstance = bus.get_object('org.nicklemaire.myprogram',  '/org/nicklemaire/myprogram')                                            
        startup = programinstance.get_dbus_method('startup', 'org.nicklemaire.myprogram')                                                       
        try:                                                                                                                                    
            arg = sys.argv[1]                                                                                                                   
        except IndexError:                                                                                                                      
            arg = ""                                                                                                                            
        startup(arg)                                                                                                                            
        print "Another instance was running and notified."                                                                                      
    except dbus.exceptions.DBusException:                                                                                                       
        exit(-1) # process had an error                                                                                                         

if __name__ == "__main__":                                                                                                                      
    p = Process(target=call_instance)                                                                                                           
    p.start() 
    p.join()                                                                                                                                    
    if p.exitcode > 0: # process had an error                                                                                                   
        DBusGMainLoop(set_as_default=True)                                                                                                      
        myservice = MyDBUSService()                                                                                                             
        gtk.main()

Тест:

Откройте терминал и запустите программу: myprogram.py . Это не завершится, потому что мы в настоящее время хотим иметь его выполнение и ожидание второго экземпляра для запуска.

Теперь сделайте это: откройте другой терминал и запустите программу снова, на этот раз с дополнительным аргументом myprogram.py askubuntu.com. Это должно распечатать: "Другой экземпляр работал и уведомленный". В то время как в первом терминале, необходимо получить вывод, подобный этому: "получил следующий параметр от другого экземпляра: askubuntu.com"

Другая часть Вашего вопроса: повышение программы описано здесь: https://stackoverflow.com/questions/9054462/how-do-i-raise-a-window-that-is-minimized-or-covered-with-pygobject

В основном необходимо звонить mywindow.present() в startup метод.

1
ответ дан 15 July 2012 в 04:13

Другие вопросы по тегам:

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