У меня есть gui в python3, который я хочу вызвать другим python сценарием, используя подпроцесс (или что-то лучше?). У меня основной gui полный экран, что я и хочу. Проблема в том, что когда я запускаю подпроцесс, он изначально становится самым верхним окном в LXDE, и пока все хорошо. Вы можете нажать на основной gui в фоновом режиме, который выводит основной gui на самый верх. Это то, что ожидается от оконного менеджера, но это касается подпроцесса, который у меня в данный момент блокирует основной gui. Мне нужно, чтобы основной gui не принимал фокус во время работы подпроцесса или оставлял подпроцесс как самое верхнее окно.
main gui .py
#!/usr/bin/env python3
import tkinter as tk
import subprocess
def on_escape(event=None):
print("escaped")
root.destroy()
def do_something():
child = subprocess.run(["python3", "childgui.py"], shell=False)
######################################################################
busy=False
root = tk.Tk()
root.title("My GUI")
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
#don't run this as the subprocess blocks #root.attributes("-fullscreen", True) # run fullscreen
root.focus_set()
root.bind("<Escape>", on_escape)
#doesn't work#root.protocol("WM_TAKE_FOCUS", on_focus)
canvas = tk.Canvas(root)
canvas.grid(row=0)
cbutton = tk.Button(root, text = "Run Child", width=50, height=50, bg = "green", compound = "top", command = do_something)
lab = tk.Label(canvas, text = 'Output Here')
lab.grid(row=0, column=1)
cbutton.grid(row=1, column=0)
# --- start ---
root.mainloop()
child gui .py
from tkinter import *
class app(Frame):
def __init__(self, master):
Frame.__init__(self, master=None)
self.master.title("Child Process")
self.master.geometry("500x200")
Button(self.master, text="Grandchild", command=self.dialog).pack()
self.data = StringVar()
self.data.set("Here is the data")
Label(self.master, textvariable=self.data).pack()
def dialog(self):
d = MyDialog(self.master, self.data, "Grandchild", "Enter Data")
self.master.wait_window(d.top)
class MyDialog:
def __init__(self, parent, data, title, labeltext = '' ):
self.data = data
self.rt = parent
self.top = Toplevel(parent)
self.top.transient(parent)
self.top.grab_set()
self.top.geometry("300x100")
if len(title) > 0: self.top.title(title)
if len(labeltext) == 0: labeltext = 'Data'
Label(self.top, text=labeltext).pack()
self.top.bind("<Return>", self.ok)
self.e = Entry(self.top, text=data.get())
self.e.bind("<Return>", self.ok)
self.e.bind("<Escape>", self.cancel)
self.e.pack(padx=15)
self.e.focus_set()
b = Button(self.top, text="OK", command=self.ok)
b.pack(pady=5)
def ok(self, event=None):
print ("The data:", self.e.get())
self.data.set(self.e.get())
self.top.destroy()
def cancel(self, event=None):
self.top.destroy()
def main():
root = Tk()
a = app(root)
root.mainloop()
if __name__ == '__main__':
main()
Редактировать: я должен был упомянуть, что child gui - приложение это не мое. Я только создал это для примера кода, чтобы показать проблему. Хотя self.top.attributes может работать, реальное дочернее приложение довольно большое, и я не хочу менять его, если смогу его избежать. У меня нет проблем с получением фокуса, что на самом деле является проблемой. Основной gui возвращает фокус, в результате чего подпроцесс отстает на go. Когда основной gui установлен в полноэкранный режим (удалите это, чтобы увидеть # не запускайте это как блоки подпроцесса #) основной gui теперь застрял в ожидании закрытия дочернего элемента, к которому вы не можете добраться с помощью мышь