Держите подпроцесс как самый верхний на Linux ОС в python3 - PullRequest
1 голос
/ 07 января 2020

У меня есть 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 теперь застрял в ожидании закрытия дочернего элемента, к которому вы не можете добраться с помощью мышь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...