Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making Tkinter window a child of non-Tkinter window

(This question was originally posted to python-tkinter mailing list)

TL;TR How to set Tkinter window's master from HWND on Windows?

I'm using Tkinter in embedded Python interpreter on Windows. There is a desktop Win32 application with a main window opened. The embedded Python runs a script which creates and displays a Tkinter window.

Is there any way to assign master (parent) of Tkinter window based on HWND of a Win32 window?

I'd like to make the Tkinter window a fully modal window in regard to the main Win32 application window.

I know the winfo_* APIs wiht winfo_id() which allows me to query Win32 HWND of Tkinter window, but there seems to be no similar function to set parent by HWND (or id on non-Windows OS).

One of rought ideas I've got is to create a small Python extension, available from my embedded Python, with exposed custom function to overwrite HWND of Tkinter windows's parent, using the Win32 SetParent.

Here is some sort of a pseudo-code of the idea:

PyObject * mywin32_set_parent(PyObject *self, PyObject *args)
{

  /* unpack Tkinter HWND from args */
  HWND hTkinterWindow = ... ;

  /* returns main application window */
  HWND hAppWindow = GetMyAppWindow();

  /* make the main window parent of the Tkinter */
  ::SetParent(hTkinterWindow, hAppWindow)

  Py_INCREF(Py_None);
  return Py_None;
}

and then in Python script code executed by the embedded Python:

import mywin32
root = Tk()
hwnd  = root.winfo_id()
# make root a child of the main application window overwriting its parent
mywin32.set_parent(hwnd)

To simplify, let's assume the only purpose of setting master from HWND is to position the Tkinter window relatively (or on top) to the window which HWND is assigned as master. IOW, the Tkniter window would behave like a modal dialog of non-Tkinter window.

Is there any Tkinter idiomatic way to achive such behaviour?

like image 530
mloskot Avatar asked Oct 14 '13 10:10

mloskot


1 Answers

Try with buttons:

from tkinter import *
def Test():
    Test = Toplevel()
main = Tk()
main.title("<Your title>")
main.geometry("400x400")
Button(main, text="<Your text>", command=Test).grid(row=0, column=0, sticky=W)
main.mainloop()

That's what we get: See the picture

like image 149
Koteinik Avatar answered Nov 15 '22 00:11

Koteinik