Skip to content

Commit bb7f231

Browse files
Fix #3.
1 parent f998488 commit bb7f231

File tree

2 files changed

+97
-2
lines changed

2 files changed

+97
-2
lines changed

README.md

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Use `pip install ingame` to install the project.
3232

3333
```python
3434
from ingame.core import InGame, Screen, EventType
35-
from ingame.objects import Text, Button, Input
35+
from ingame.objects import Text, Button, Input, Image
3636

3737
app = InGame()
3838

@@ -59,6 +59,12 @@ def ht_click() -> None:
5959

6060
Button(screen, text="Print input value", command=ht_click, packargs={"pady": 10})
6161

62+
# Display a local image (resize to 100x100)
63+
img = Image(screen, source="/path/to/image.png", width=100, height=100, packargs={"pady": 10})
64+
65+
# Display a remote image (auto-size)
66+
# img2 = Image(screen, source="https://example.com/image.jpg")
67+
6268

6369

6470
screen.show()
@@ -85,7 +91,26 @@ Handles registering and triggering events:
8591
* `@event(type: EventType.Key)`: Registers a function for a specific key event.
8692
* `trigger_event(type)`: Manually triggers an event.
8793

88-
### `Screen`
94+
95+
### `Image`
96+
97+
Displays an image from a local file or remote URL.
98+
99+
**Constructor:**
100+
101+
```python
102+
Image(screen_obj, source, packargs=None, width=None, height=None, **kwargs)
103+
```
104+
105+
- `screen_obj`: The `Screen` to attach the image to
106+
- `source`: Path to local file or remote URL
107+
- `packargs`: Optional dict for layout (e.g., `{"pady": 10}`)
108+
- `width`, `height`: Resize image (preserves aspect ratio if only one is set)
109+
- `**kwargs`: Additional tkinter.Label options
110+
111+
**Methods:**
112+
- `config(**kwargs)`: Configure the image widget
113+
- `destroy()`: Remove the image from the GUI
89114

90115
Simple `tkinter` window with key event binding:
91116

src/ingame/objects.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,76 @@ def destroy(
101101

102102
self.text_obj.destroy()
103103

104+
class Image(Object):
105+
"""
106+
Displays an image (from file or URL) on the given Screen, packs it with optional args,
107+
and provides a destroy() method for cleanup. Supports basic transformations (resize, scale, position).
108+
"""
109+
110+
image_obj: tk.Label
111+
_photo_image: Any
112+
113+
114+
def __init__(
115+
self,
116+
screen_obj: Screen,
117+
source: str,
118+
/,
119+
packargs: Optional[dict[Any, Optional[Any]]] = None,
120+
width: Optional[int] = None,
121+
height: Optional[int] = None,
122+
**kwargs: Any
123+
) -> None:
124+
"""
125+
source: Path to local file or URL
126+
width, height: Optional resize dimensions
127+
"""
128+
import io
129+
from PIL import Image as PILImage, ImageTk
130+
import requests
131+
132+
if not isinstance(screen_obj, Screen):
133+
raise TypeError("screen_obj must be an instance of Screen")
134+
135+
if packargs is None:
136+
packargs = {}
137+
138+
# Load image from file or URL
139+
img_data = None
140+
if source.startswith("http://") or source.startswith("https://"):
141+
resp = requests.get(source)
142+
resp.raise_for_status()
143+
img_data = io.BytesIO(resp.content)
144+
else:
145+
img_data = source
146+
147+
pil_img = PILImage.open(img_data)
148+
if width or height:
149+
# If only one is provided, keep aspect ratio
150+
orig_w, orig_h = pil_img.size
151+
if width and not height:
152+
height = int(orig_h * (width / orig_w))
153+
elif height and not width:
154+
width = int(orig_w * (height / orig_h))
155+
pil_img = pil_img.resize((width, height), PILImage.LANCZOS)
156+
157+
self._photo_image = ImageTk.PhotoImage(pil_img)
158+
self.image_obj = tk.Label(screen_obj.root, image=self._photo_image, **kwargs)
159+
self.image_obj.pack(**{k: v for k, v in packargs.items() if v is not None})
160+
161+
def config(
162+
self,
163+
**kwargs
164+
) -> None:
165+
"""Configure object"""
166+
self.image_obj.config(**kwargs)
167+
168+
def destroy(
169+
self
170+
) -> None:
171+
"""Destroy image widget"""
172+
self.image_obj.destroy()
173+
104174
class Input(Object):
105175
"""
106176
Creates a single line text input box on the given Screen, packs it with optional args,

0 commit comments

Comments
 (0)