pythontkintertkinter-canvaspanda3d

How can I embed a Panda3D window in a Tkinter app?


I am designing a Tkinter app in Python that uses the Panda3D game library to display some 3D models. With my current design, I run the Panda3D engine in headless mode with the option windowType='offscreen', and I periodically take screenshots from the headless window and display them in a Tkinter Canvas widget. However, this view does not have any of the interactive features of Panda3D.

I am using Panda3D version 1.10.13.post1.

Is there a way that I could embed the Panda3D window in Tkinter, so that it could be an interactive 3D view?


Solution

  • Based on example code from https://discourse.panda3d.org/t/an-example-of-panda3d-integration-into-tkinter/28329, as suggested by user acw1668, I got a Panda3D window to run in a Tkinter app.

    from direct.showbase.ShowBase import ShowBase
    from panda3d.core import WindowProperties
    import tkinter as tk
    from tkinter import Button
    
    
    class AppTk(ShowBase):
    
        def __init__(self):
            ShowBase.__init__(self, windowType='none')
            self.startTk()
    
            self.tk = self.tkRoot
            self.tk.geometry("500x400")
    
            self.label_frame = tk.LabelFrame(self.tk, text='Panda3D Example', width=420, height=340)
            self.label_frame.pack()
    
            button = Button(self.tk, text='Click me !', bd='5', command=self.test)
            button.pack()
    
            # Set properties of the Panda3D window
            props = WindowProperties()
            props.set_parent_window(self.label_frame.winfo_id())  # Display within the label frame
            props.set_origin(10, 20)  # Relative to the label frame
            props.set_size(400, 300)
    
            self.make_default_pipe()
            self.open_default_window(props=props)
    
            scene = self.loader.load_model("environment")
            scene.reparent_to(self.render)
    
        def test(self):
            print("Hello")
    
    
    app = AppTk()
    app.run()
    

    Screenshot: PNG

    Note: I had to run pip install Pmw for this to work, which I believe is an unlisted dependency of Panda3D.