Panda3D is a framework for 3D rendering and game development for Python and C++ programs.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Panda3D provides a comprehensive GUI system for creating interactive user interfaces with buttons, text, dialogs, and other widgets that can be rendered in 2D overlay or integrated into the 3D scene.
The DirectGUI system provides a complete widget library for user interfaces.
class DirectButton:
def __init__(self,
text: str = "",
command: callable = None,
extraArgs: List = [],
pos: tuple = (0, 0, 0),
scale: float = 1.0,
frameColor: tuple = (0.8, 0.8, 0.8, 1),
text_fg: tuple = (0, 0, 0, 1),
**options) -> None:
"""Create clickable button widget."""
def destroy(self) -> None:
"""Remove and clean up button."""
def setCommand(self, command: callable, extraArgs: List = []) -> None:
"""Set button click command."""
def commandFunc(self, event=None) -> None:
"""Execute button command."""
class DirectLabel:
def __init__(self,
text: str = "",
pos: tuple = (0, 0, 0),
scale: float = 1.0,
text_fg: tuple = (1, 1, 1, 1),
**options) -> None:
"""Create text label widget."""
def setText(self, text: str) -> None:
"""Set label text."""
def getText(self) -> str:
"""Get current text."""
class DirectEntry:
def __init__(self,
text: str = "",
pos: tuple = (0, 0, 0),
scale: float = 1.0,
command: callable = None,
width: float = 10,
**options) -> None:
"""Create text input widget."""
def set(self, text: str) -> None:
"""Set entry text."""
def get(self) -> str:
"""Get current text."""
def enterText(self, text: str) -> None:
"""Enter text programmatically."""
class DirectFrame:
def __init__(self,
pos: tuple = (0, 0, 0),
frameSize: tuple = (-1, 1, -1, 1),
frameColor: tuple = (0.8, 0.8, 0.8, 1),
**options) -> None:
"""Create rectangular frame container."""
def destroy(self) -> None:
"""Remove and clean up frame."""
class DirectCheckBox:
def __init__(self,
text: str = "",
pos: tuple = (0, 0, 0),
command: callable = None,
**options) -> None:
"""Create checkbox input widget."""
def isChecked(self) -> bool:
"""Check if checkbox is checked."""
def setChecked(self, checked: bool) -> None:
"""Set checkbox state."""
class DirectSlider:
def __init__(self,
pos: tuple = (0, 0, 0),
range: tuple = (0, 1),
value: float = 0,
command: callable = None,
**options) -> None:
"""Create slider input widget."""
def getValue(self) -> float:
"""Get current slider value."""
def setValue(self, value: float) -> None:
"""Set slider value."""Pre-built dialog boxes for common user interactions.
class OkDialog:
def __init__(self,
text: str = "",
command: callable = None,
**options) -> None:
"""Create OK-only dialog."""
def show(self) -> None:
"""Show dialog."""
def hide(self) -> None:
"""Hide dialog."""
def destroy(self) -> None:
"""Remove dialog."""
class OkCancelDialog:
def __init__(self,
text: str = "",
command: callable = None,
**options) -> None:
"""Create OK/Cancel dialog."""
class YesNoDialog:
def __init__(self,
text: str = "",
command: callable = None,
**options) -> None:
"""Create Yes/No dialog."""Simple text and image overlays for heads-up displays.
class OnscreenText:
def __init__(self,
text: str = "",
pos: tuple = (0, 0),
scale: float = 1.0,
fg: tuple = (1, 1, 1, 1),
bg: tuple = None,
align: int = None,
font: str = None,
parent: NodePath = None,
**options) -> None:
"""Create text rendered to screen."""
def setText(self, text: str) -> None:
"""Update text content."""
def getText(self) -> str:
"""Get current text."""
def destroy(self) -> None:
"""Remove text."""
class OnscreenImage:
def __init__(self,
image: str = None,
pos: tuple = (0, 0),
scale: float = 1.0,
parent: NodePath = None,
**options) -> None:
"""Create image rendered to screen."""
def setImage(self, image: str) -> None:
"""Set image file."""
def destroy(self) -> None:
"""Remove image."""from direct.showbase.ShowBase import ShowBase
from direct.gui.DirectGui import *
from panda3d.core import *
class GUIDemo(ShowBase):
def __init__(self):
ShowBase.__init__(self)
# Create main menu
self.createMainMenu()
# Game state
self.score = 0
self.playerName = ""
def createMainMenu(self):
"""Create main menu interface."""
# Title
self.title = OnscreenText(
text="My Game",
pos=(0, 0.6),
scale=0.15,
fg=(1, 1, 0, 1),
align=TextNode.ACenter
)
# Player name entry
self.nameLabel = DirectLabel(
text="Player Name:",
pos=(-0.3, 0, 0.2),
scale=0.08,
text_align=TextNode.ALeft
)
self.nameEntry = DirectEntry(
text="Player",
pos=(0.1, 0, 0.2),
scale=0.08,
width=10,
command=self.setPlayerName
)
# Buttons
self.startButton = DirectButton(
text="Start Game",
pos=(0, 0, 0),
scale=0.1,
command=self.startGame
)
self.optionsButton = DirectButton(
text="Options",
pos=(0, 0, -0.2),
scale=0.1,
command=self.showOptions
)
self.exitButton = DirectButton(
text="Exit",
pos=(0, 0, -0.4),
scale=0.1,
command=self.exitGame
)
def setPlayerName(self, text):
"""Set player name from entry."""
self.playerName = text
print(f"Player name set to: {self.playerName}")
def startGame(self):
"""Start the game."""
self.playerName = self.nameEntry.get()
print(f"Starting game for {self.playerName}")
self.hideMainMenu()
self.createGameUI()
def showOptions(self):
"""Show options dialog."""
self.optionsDialog = OkCancelDialog(
text="Options not implemented yet!",
command=self.optionsCallback
)
self.optionsDialog.show()
def optionsCallback(self, value):
"""Handle options dialog result."""
print(f"Options dialog result: {value}")
def exitGame(self):
"""Exit the game."""
self.userExit()
def hideMainMenu(self):
"""Hide main menu elements."""
self.title.destroy()
self.nameLabel.destroy()
self.nameEntry.destroy()
self.startButton.destroy()
self.optionsButton.destroy()
self.exitButton.destroy()
def createGameUI(self):
"""Create in-game UI."""
# Score display
self.scoreText = OnscreenText(
text=f"Score: {self.score}",
pos=(-1.2, 0.9),
scale=0.08,
fg=(1, 1, 1, 1),
align=TextNode.ALeft
)
# Player name display
self.playerText = OnscreenText(
text=f"Player: {self.playerName}",
pos=(1.2, 0.9),
scale=0.08,
fg=(1, 1, 1, 1),
align=TextNode.ARight
)
# Game controls
self.pauseButton = DirectButton(
text="Pause",
pos=(1.2, 0, -0.8),
scale=0.06,
command=self.togglePause
)
# Start score update task
self.taskMgr.add(self.updateScore, "update-score")
def updateScore(self, task):
"""Update score periodically."""
self.score += 1
self.scoreText.setText(f"Score: {self.score}")
task.delayTime = 1.0 # Update every second
return task.again
def togglePause(self):
"""Toggle game pause."""
print("Pause toggled")
app = GUIDemo()
app.run()Install with Tessl CLI
npx tessl i tessl/pypi-panda3d