Je sais que la question est un peu vague. Je vais essayer d'expliquer mieux ci-dessous:
Mon application (python/gtk) est principalement un indicateur. En utilisant cet indicateur, vous pouvez choisir d’afficher/masquer la fenêtre principale.
Lorsque j'essaie d'ouvrir une nouvelle instance de l'application, je l'ai créée afin de vérifier si l'application est déjà en cours d'exécution. Si tel est le cas, il essaierait de lancer l'application.
Maintenant, je veux l'ajuster. Par conséquent, avant d'abandonner, je veux qu'il fasse apparaître la fenêtre principale de l'application déjà active au premier plan. Même si cette fenêtre n'est pas ouverte pour le moment.
Je pense donc que ma question est la suivante: comment puis-je obtenir une variable/instance (globale?) De mon application déjà active à partir de ma nouvelle application? (je peux donc amener ma fenêtre principale au premier plan)
MODIFIER:
Je viens de trouver cette méthode dans l'api: GtkWindow - set_startup_id () .
Cela dit: Normalement, l'identifiant de démarrage est géré automatiquement et vous ne devez utiliser cette fonction que dans des cas particuliers tels que le transfert du focus depuis d'autres processus.
Cela signifie donc qu'il devrait être possible de mettre en évidence une fenêtre provenant d'un autre processus. Mais comment pourrais-je obtenir cet identifiant? Et comment pourrais-je utiliser cet identifiant pour l'amener au premier plan?
Grâce à la bonne réponse de xubuntix , j'ai créé un module qui simplifie les choses:
"""
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 __== '__main__':
test()
Veuillez vous reporter à l’essentiel suivant pour toute révision ultérieure dans le code ci-dessus:
Commençons par dire qu'il y a beaucoup de façons. Vous configurez normalement un jeton/identificateur au démarrage du programme afin que des instances ultérieures puissent rechercher l'existence de ce jeton.
Je vais décrire un moyen qui utilise dbus.
Vue d'ensemble:
Lors du démarrage d’un programme, il peut s’inscrire lui-même sur la session dbus sous un nom unique (par exemple, "org.nicklemaire.myprogram"). D'autres instances du programme peuvent vérifier si un tel point d'accès est déjà enregistré et, le cas échéant, indiquer au programme ce qu'il doit faire via ce point d'accès dbus (par exemple, sélectionnez le focus, ouvrez un site Web, jouez une chanson). La dernière partie est probablement nécessaire lorsque vous souhaitez un comportement similaire à "firefox askubuntu.com", qui ouvre cette page dans un nouvel onglet dans une instance en cours d'exécution.
Code:
#!/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 __== "__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()
Test:
Ouvrez un terminal et lancez le programme: myprogram.py
. Il ne se terminera pas car nous souhaitons actuellement qu'il soit exécuté et en attente du démarrage d'une deuxième instance.
Maintenant, faites ceci: ouvrez un autre terminal et exécutez le programme à nouveau, cette fois avec un argument supplémentaire myprogram.py askubuntu.com
. Il devrait imprimer: "Une autre instance était en cours d'exécution et notifiée." Dans le premier terminal, vous devriez obtenir une sortie semblable à celle-ci: "a obtenu le paramètre suivant à partir d'une autre instance: askubuntu.com"
L’autre partie de votre question: la création d’un programme est décrite ci-après: https://stackoverflow.com/questions/9054462/how-do-i-raise-a-window-that-is-minimized-or- couvert-avec-pygobject
En gros, vous devez appeler mywindow.present()
dans la méthode startup
.
Pas sûr que ce soit l'ID que vous recherchez:
Ouvrez System Monitor
, soit en accédant aux applications, en appuyant sur CTRL+ALT+DEL
, soit en saisissant le terminal gnome-system-monitor
.
Accédez à l'onglet View
, dans la barre supérieure. Sélectionnez All Processes
et les dépendances. Allez sur l'onglet Edit
, dans la barre supérieure, et ouvrez Preferences
.
Sur l'onglet Processes
, sous Information Fields
, sélectionnez ID
.
Ensuite, essayez de trouver votre programme dans la liste. Bonne chance!