0
# User Interface
1
2
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.
3
4
## Capabilities
5
6
### DirectGUI Widgets
7
8
The DirectGUI system provides a complete widget library for user interfaces.
9
10
```python { .api }
11
class DirectButton:
12
def __init__(self,
13
text: str = "",
14
command: callable = None,
15
extraArgs: List = [],
16
pos: tuple = (0, 0, 0),
17
scale: float = 1.0,
18
frameColor: tuple = (0.8, 0.8, 0.8, 1),
19
text_fg: tuple = (0, 0, 0, 1),
20
**options) -> None:
21
"""Create clickable button widget."""
22
23
def destroy(self) -> None:
24
"""Remove and clean up button."""
25
26
def setCommand(self, command: callable, extraArgs: List = []) -> None:
27
"""Set button click command."""
28
29
def commandFunc(self, event=None) -> None:
30
"""Execute button command."""
31
32
class DirectLabel:
33
def __init__(self,
34
text: str = "",
35
pos: tuple = (0, 0, 0),
36
scale: float = 1.0,
37
text_fg: tuple = (1, 1, 1, 1),
38
**options) -> None:
39
"""Create text label widget."""
40
41
def setText(self, text: str) -> None:
42
"""Set label text."""
43
44
def getText(self) -> str:
45
"""Get current text."""
46
47
class DirectEntry:
48
def __init__(self,
49
text: str = "",
50
pos: tuple = (0, 0, 0),
51
scale: float = 1.0,
52
command: callable = None,
53
width: float = 10,
54
**options) -> None:
55
"""Create text input widget."""
56
57
def set(self, text: str) -> None:
58
"""Set entry text."""
59
60
def get(self) -> str:
61
"""Get current text."""
62
63
def enterText(self, text: str) -> None:
64
"""Enter text programmatically."""
65
66
class DirectFrame:
67
def __init__(self,
68
pos: tuple = (0, 0, 0),
69
frameSize: tuple = (-1, 1, -1, 1),
70
frameColor: tuple = (0.8, 0.8, 0.8, 1),
71
**options) -> None:
72
"""Create rectangular frame container."""
73
74
def destroy(self) -> None:
75
"""Remove and clean up frame."""
76
77
class DirectCheckBox:
78
def __init__(self,
79
text: str = "",
80
pos: tuple = (0, 0, 0),
81
command: callable = None,
82
**options) -> None:
83
"""Create checkbox input widget."""
84
85
def isChecked(self) -> bool:
86
"""Check if checkbox is checked."""
87
88
def setChecked(self, checked: bool) -> None:
89
"""Set checkbox state."""
90
91
class DirectSlider:
92
def __init__(self,
93
pos: tuple = (0, 0, 0),
94
range: tuple = (0, 1),
95
value: float = 0,
96
command: callable = None,
97
**options) -> None:
98
"""Create slider input widget."""
99
100
def getValue(self) -> float:
101
"""Get current slider value."""
102
103
def setValue(self, value: float) -> None:
104
"""Set slider value."""
105
```
106
107
### Dialog Boxes
108
109
Pre-built dialog boxes for common user interactions.
110
111
```python { .api }
112
class OkDialog:
113
def __init__(self,
114
text: str = "",
115
command: callable = None,
116
**options) -> None:
117
"""Create OK-only dialog."""
118
119
def show(self) -> None:
120
"""Show dialog."""
121
122
def hide(self) -> None:
123
"""Hide dialog."""
124
125
def destroy(self) -> None:
126
"""Remove dialog."""
127
128
class OkCancelDialog:
129
def __init__(self,
130
text: str = "",
131
command: callable = None,
132
**options) -> None:
133
"""Create OK/Cancel dialog."""
134
135
class YesNoDialog:
136
def __init__(self,
137
text: str = "",
138
command: callable = None,
139
**options) -> None:
140
"""Create Yes/No dialog."""
141
```
142
143
### OnScreen Elements
144
145
Simple text and image overlays for heads-up displays.
146
147
```python { .api }
148
class OnscreenText:
149
def __init__(self,
150
text: str = "",
151
pos: tuple = (0, 0),
152
scale: float = 1.0,
153
fg: tuple = (1, 1, 1, 1),
154
bg: tuple = None,
155
align: int = None,
156
font: str = None,
157
parent: NodePath = None,
158
**options) -> None:
159
"""Create text rendered to screen."""
160
161
def setText(self, text: str) -> None:
162
"""Update text content."""
163
164
def getText(self) -> str:
165
"""Get current text."""
166
167
def destroy(self) -> None:
168
"""Remove text."""
169
170
class OnscreenImage:
171
def __init__(self,
172
image: str = None,
173
pos: tuple = (0, 0),
174
scale: float = 1.0,
175
parent: NodePath = None,
176
**options) -> None:
177
"""Create image rendered to screen."""
178
179
def setImage(self, image: str) -> None:
180
"""Set image file."""
181
182
def destroy(self) -> None:
183
"""Remove image."""
184
```
185
186
## Usage Examples
187
188
### Basic GUI Application
189
190
```python
191
from direct.showbase.ShowBase import ShowBase
192
from direct.gui.DirectGui import *
193
from panda3d.core import *
194
195
class GUIDemo(ShowBase):
196
def __init__(self):
197
ShowBase.__init__(self)
198
199
# Create main menu
200
self.createMainMenu()
201
202
# Game state
203
self.score = 0
204
self.playerName = ""
205
206
def createMainMenu(self):
207
"""Create main menu interface."""
208
# Title
209
self.title = OnscreenText(
210
text="My Game",
211
pos=(0, 0.6),
212
scale=0.15,
213
fg=(1, 1, 0, 1),
214
align=TextNode.ACenter
215
)
216
217
# Player name entry
218
self.nameLabel = DirectLabel(
219
text="Player Name:",
220
pos=(-0.3, 0, 0.2),
221
scale=0.08,
222
text_align=TextNode.ALeft
223
)
224
225
self.nameEntry = DirectEntry(
226
text="Player",
227
pos=(0.1, 0, 0.2),
228
scale=0.08,
229
width=10,
230
command=self.setPlayerName
231
)
232
233
# Buttons
234
self.startButton = DirectButton(
235
text="Start Game",
236
pos=(0, 0, 0),
237
scale=0.1,
238
command=self.startGame
239
)
240
241
self.optionsButton = DirectButton(
242
text="Options",
243
pos=(0, 0, -0.2),
244
scale=0.1,
245
command=self.showOptions
246
)
247
248
self.exitButton = DirectButton(
249
text="Exit",
250
pos=(0, 0, -0.4),
251
scale=0.1,
252
command=self.exitGame
253
)
254
255
def setPlayerName(self, text):
256
"""Set player name from entry."""
257
self.playerName = text
258
print(f"Player name set to: {self.playerName}")
259
260
def startGame(self):
261
"""Start the game."""
262
self.playerName = self.nameEntry.get()
263
print(f"Starting game for {self.playerName}")
264
self.hideMainMenu()
265
self.createGameUI()
266
267
def showOptions(self):
268
"""Show options dialog."""
269
self.optionsDialog = OkCancelDialog(
270
text="Options not implemented yet!",
271
command=self.optionsCallback
272
)
273
self.optionsDialog.show()
274
275
def optionsCallback(self, value):
276
"""Handle options dialog result."""
277
print(f"Options dialog result: {value}")
278
279
def exitGame(self):
280
"""Exit the game."""
281
self.userExit()
282
283
def hideMainMenu(self):
284
"""Hide main menu elements."""
285
self.title.destroy()
286
self.nameLabel.destroy()
287
self.nameEntry.destroy()
288
self.startButton.destroy()
289
self.optionsButton.destroy()
290
self.exitButton.destroy()
291
292
def createGameUI(self):
293
"""Create in-game UI."""
294
# Score display
295
self.scoreText = OnscreenText(
296
text=f"Score: {self.score}",
297
pos=(-1.2, 0.9),
298
scale=0.08,
299
fg=(1, 1, 1, 1),
300
align=TextNode.ALeft
301
)
302
303
# Player name display
304
self.playerText = OnscreenText(
305
text=f"Player: {self.playerName}",
306
pos=(1.2, 0.9),
307
scale=0.08,
308
fg=(1, 1, 1, 1),
309
align=TextNode.ARight
310
)
311
312
# Game controls
313
self.pauseButton = DirectButton(
314
text="Pause",
315
pos=(1.2, 0, -0.8),
316
scale=0.06,
317
command=self.togglePause
318
)
319
320
# Start score update task
321
self.taskMgr.add(self.updateScore, "update-score")
322
323
def updateScore(self, task):
324
"""Update score periodically."""
325
self.score += 1
326
self.scoreText.setText(f"Score: {self.score}")
327
328
task.delayTime = 1.0 # Update every second
329
return task.again
330
331
def togglePause(self):
332
"""Toggle game pause."""
333
print("Pause toggled")
334
335
app = GUIDemo()
336
app.run()
337
```