Я знаю, что вопрос немного расплывчатый. Я попытаюсь объяснить лучше ниже:
Мое приложение (python / gtk) в основном индикатор. Используя этот индикатор, вы можете показать / скрыть главное окно.
Когда я пытался открыть новый экземпляр приложения, я сделал его так, чтобы он проверял, запущено ли уже приложение. Если это так, то попытка запустить приложение будет прервана.
Теперь я хочу настроить его, поэтому перед прерыванием я хочу вывести главное окно уже активного приложения на передний план. Даже если это окно еще не открыто.
Поэтому я считаю, что мой вопрос: как я могу получить (глобальную?) Переменную / экземпляр моего уже активного приложения из моего нового приложения? (чтобы я мог вывести мое главное окно на передний план)
РЕДАКТИРОВАТЬ:
Я только что нашел этот метод в API: GtkWindow - set_startup_id () .
Это говорит: Обычно, идентификатор запуска управляется автоматически, и вы должны использовать эту функцию только в особых случаях, таких как перенос фокуса с других процессов.
Таким образом, это означает, что должна быть возможность перенести фокус на окно из другого процесса. Но как мне получить этот идентификатор? И как бы я использовал этот идентификатор, чтобы вывести его на передний план?
Благодаря великолепному ответу 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]
Не уверен, что это ID, который вы ищете:
Откройте System Monitor
, перейдя в Приложения, нажав CTRL+ALT+DEL
или набрав в терминале gnome-system-monitor
.
Перейдите на вкладку View
в верхней панели. Выберите All Processes
и Зависимости. Перейдите на вкладку Edit
в верхней панели и откройте Preferences
.
На вкладке Processes
в разделе Information Fields
выберите ID
.
Затем попробуйте найти свою программу в списке. Удачи!
Позволяет запускаются путем высказывания, что существуют партии и много путей. Вы обычно устанавливаете маркер/идентификатор, когда программа запускается, поэтому более поздние экземпляры могут искать существование того маркера.
Я опишу один путь, который использует 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
метод.