Source

py-sdl2 / doc / tutorial / helloworld.rst

Full commit

Hello World

Ahhh, the great tradition of saying "Hello World" in a programming language. To whet your appetite, we will do this with a most simple application, which will display an image. It is not important to understand everything at once, which will be used by the example. Nearly all parts used now are explained in later chapters, so do not hesitate, if the one or other explanation is missing.

Importing

Let's start with importing some basic modules, which are necessary to display a small nice window and to do some basic drawing within that window.

import sys

try:
    import sdl2.ext as sdl2ext
except ImportError:
    import traceback
    traceback.print_exc()
    sys.exit(1)

from sdl2.ext import Resources
RESOURCES = Resources(__file__, "resources")

At first, we try to import the :mod:`sdl2.ext` module, which is necessary for displaying the window and image. :mod:`sdl2.ext` requires :mod:`sdl2`, so in case it could not load the SDL2 bindings, we will print the exact error stack information and exit with a failure.

We also need some resources from the resources folder, so that we have a test image around to display on the window later on. In your own applications, it is unlikely that you will ever need to import them, but we need them here, so we use the :mod:`sdl2.ext.Resources` class to have them available.

Window creation and image loading

Any graphical application requires access to the screen, mostly in form of a window, which basically represents a portion of the screen, the application has access to and the application can manipulate. In most cases that portion has a border and title bar around it, allowing the user to move it around on the screen and reorganise everything in a way to fit his needs.

Once we have imported all necessary parts, let's create a window to have access to the screen, so we can display the logo and thus represent it to the user.

sdl2ext.init ()

window = sdl2ext.Window("Hello World!", size=(640, 480))
window.show()

factory = sdl2ext.SpriteFactory(sdl2ext.SOFTWARE)
sprite = factory.from_image(RESOURCES.get_path("hello.bmp"))

spriterenderer = factory.create_sprite_renderer(window)
spriterenderer.render(sprite)

First, we initialise the :mod:`sdl2.ext` internals to gain access to the screen and and to be able to create windows on top of it. Once done with that, :class:`sdl2.ext.Window` will create the window for us and we supply a title to be shown on the window's border along with its initial size. Since :class:`sdl2.ext.Window` instances are not shown by default, we have to tell the operating system and window manager that there is a new window to display by calling :meth:`sdl2.ext.Window.show()`.

Afterwards, we get an image from the resources folder and create a :class:`sdl2.ext.Sprite` from it, which can be easily shown later on. This is done via a :class:`sdl2.ext.SpriteFactory`, since the factory allows us to switch between texture-based, hardware-accelerated, and software-based sprites easily.

To display the image, we will use a :class:`sdl2.ext.SpriteRenderer`, which supports the sprite type (texture- or software-based) and can copy the image to the window for display. The :class:`sdl2.ext.SpriteRenderer` needs to know, where to copy to, thus we have to supply the window as target for copy and display operations.

All left to do is to initiate the copy process by calling :class:`sdl2.ext.SpriteRenderer.render()` with the image we created earlier.

Tip

You will notice that the sprite used above will always be drawn at the top-left corner of the :class:`sdl2.ext.Window`. You can change the position of where to draw it by changing its :attr:`sdl2.ext.Sprite.position` value.

# will cause the renderer to draw the sprite 10px to the right and
# 20 px to the bottom
sprite.position = 10, 20

# will cause the renderer to draw the sprite 55px to the right and
# 10 px to the bottom
sprite.position = 55, 10

Experiment with different values to see their effect. Do not forget to do this before spriterenderer.render(sprite) is called.

Making the application responsive

We are nearly done now. We have an image to display, we have a window, where the image should be displayed on, so we can execute the written code, not?

Well, yes, but the only thing that will happen is that we will notice a short flickering before the application exits. Maybe we can even see the window with the image for a short moment, but that's not what we want, do we?

To keep the window on the screen and to make it responsive to user input, such as closing the window, react upon the mouse cursor or key presses, we have to add a so-called event loop. The event loop will deal with certain types of actions happening on the window or while the window is focused by the user and - as long as the event loop is running - will keep the window shown on the screen.

processor = sdl2ext.TestEventProcessor()
processor.run(window)

Since this is a very first tutorial, we keep things simple here and use a dummy class for testing without actually dealing with the event loop magic. By calling :meth:`sdl2.ext.TestEventProcessor.run()`, we implicitly start an event loop, which takes care of the most important parts for us.

And here it ends...

The window is shown, the image is shown, great! All left to do is to clean up everything, once the application finishes. Luckily the :class:`sdl2.ext.TestEventProcessor` knows when the window is closed, so it will exit from the event loop. Once it exits, we should clean up the video internals, we initialised at the beginning. Thus, a final call to

sdl2ext.quit()

should be made.