Diferències
Ací es mostren les diferències entre la revisió seleccionada i la versió actual de la pàgina.
| Ambdós costats versió prèvia Revisió prèvia Següent revisió | Revisió prèvia | ||
| info:cursos:pue:python-pcpp1:m3:1.1 [19/12/2023 07:50] – mate | info:cursos:pue:python-pcpp1:m3:1.1 [22/12/2023 03:20] (actual) – mate | ||
|---|---|---|---|
| Línia 79: | Línia 79: | ||
| == Widgets | == Widgets | ||
| + | The user interacts with the GUI by using gestures: a mouse' | ||
| + | |||
| + | The GUI elements designed to receive such gestures are called **controls** or **widgets**. | ||
| + | |||
| + | Note that the whole GUI idea was inspired by electrical control panels – devices full of switches, gauges, and colored warning lights. You'll find some traces of these inspirations in widget names. Don't be surprised. | ||
| + | |||
| + | One of the widgets living inside a particular window owns the focus. The widget (which is also called the **focused widget**) is the default recipient of some or all of the user's actions. Of course, the focus may change its owner, which is usually done by pressing the Tab key. | ||
| + | |||
| + | For example, pressing the space bar may activate different activities depending on which of the window' | ||
| + | |||
| + | Now let's take a look at a very simple window. | ||
| + | |||
| + | Let's try to identify all visible window components. This is a very important distinction, | ||
| + | |||
| + | First of all, the window has a **title bar**. It's one of the typical window decorations. | ||
| + | {{ : | ||
| + | |||
| + | Inside the title bar there is (or can be) a set of control buttons. Our sample window contains only one: the **closing button**. Note that the location of these buttons is OS-dependent. | ||
| + | {{ : | ||
| + | |||
| + | Inside the title bar (as the name suggests) there is a window **title**. Of course, some of the windows may also be untitled. | ||
| + | {{ : | ||
| + | |||
| + | The window' | ||
| + | |||
| + | One of these non-clickables is an **icon** – a small picture that usually helps the user to quickly identify the issue. | ||
| + | {{ : | ||
| + | |||
| + | Another non-clickable member of the window' | ||
| + | {{ : | ||
| + | |||
| + | As our sample window performs a very specific task (it asks a question and forces the user to reply), it needs two buttons assigned to the user's possible answers. | ||
| + | |||
| + | The first of them is titled Yes and – look carefully! – it's currently focused! | ||
| + | {{ : | ||
| + | |||
| + | Can you guess how we know that? | ||
| + | |||
| + | Yes, it's shown by the thin dotted line drawn around the button. If you press the space bar now, it will be taken as an affirmative answer. | ||
| + | |||
| + | The second of the buttons is not focused yet. | ||
| + | |||
| + | What can we do to move the focus to the button? | ||
| + | |||
| + | Yes, we can press the Tab key. | ||
| + | {{ : | ||
| + | |||
| + | Note: the underlined letters within the buttons' | ||
| + | |||
| + | And what does all this mean? | ||
| + | |||
| + | This means something very important to us. You may not want to believe us at the moment, but the traditional programming paradigm in which the programmer is responsible for responding to literally all the user's actions is completely useless in visual programming. | ||
| + | |||
| + | Why? | ||
| + | |||
| + | Because the number of all possible user moves is so substantial that continuous checking of the window' | ||
| + | |||
| + | In a slightly more suggestive way, you could also say that widgets aren't introverts. They are not in the habit of concealing their emotions, and like very much to influence other widgets (e.g., moving the focus always engages two widgets: the one that loses the focus and the one that gains it). This means that the programmer is obliged not only to control each of the widgets separately, but also their pair, triple, and so on. | ||
| + | |||
| + | Let's try to imagine it. | ||
| + | |||
| + | < | ||
| + | while True: | ||
| + | wait_for_user_action() | ||
| + | if user_pressed_button_yes(): | ||
| + | : | ||
| + | elif user_pressed_button_no(): | ||
| + | : | ||
| + | elif user_move_mouse_coursor_over_button_yes(): | ||
| + | : | ||
| + | elif user_move_mouse_coursor_over_button_no(): | ||
| + | : | ||
| + | elif user_pressed_Tab_key(): | ||
| + | if isfocused(button_yes): | ||
| + | : | ||
| + | elif isfocused(button_no): | ||
| + | : | ||
| + | : | ||
| + | : | ||
| + | </ | ||
| + | |||
| + | Note: The pseudo-code is deprived of all details. Moreover, it's not complete. It covers less than about 10 % of all possible events, and should be heavily developed to behave in a reasonable way. | ||
| + | |||
| + | Believe us: you don't want to write a code like this one. Fortunately, | ||
| + | |||
| + | Visual programming demands a completely different philosophy, or (expressing this thought in a more fashionable way) it needs a different paradigm. | ||
| + | |||
| + | This paradigm exists, and is widely applied to create GUI applications. | ||
| + | |||
| + | It's called **event-driven programming**. | ||
| + | |||
| + | == Classical vs. event-driven paradigm | ||
| + | What is EDP like? Or rather, what is EDP unlike? | ||
| + | |||
| + | First of all, detecting, registering and classifying all of a user's actions is beyond the programmer' | ||
| + | |||
| + | You have to inform the event controller what you want to perform when a particular event (e.g., a mouse click). This is done by writing specialized functions called event handlers. You write these handlers only for the events you want to serve – all other events will activate default behaviors (e.g., focus moving and window closing). | ||
| + | |||
| + | Of course, just implementing an event handler is not enough – you also have to make the event controller aware of it. | ||
| + | |||
| + | Let's imagine that we have a function named '' | ||
| + | |||
| + | In the classical paradigm we would have to: | ||
| + | |||
| + | * discover the click and check if it happened over our button; | ||
| + | * redraw the button to reflect the click (e.g., to show that it is actually pressed) | ||
| + | * invoke the function. | ||
| + | |||
| + | In the event-driven paradigm our duties look completely different: | ||
| + | |||
| + | * the event controller detects the clicks on its own; | ||
| + | * it identifies the target of the click on its own; | ||
| + | * it invokes the desired function on its own; | ||
| + | * all these actions take place behind the scenes! Really! | ||
| + | Sounds good? Oh, yes, it does! | ||
| + | |||
| + | == Events | ||
| + | Have you noticed? We silently introduced a new word into our discussion. It’s the **event**. | ||
| + | |||
| + | What it is? Or rather, what could it be? | ||
| + | |||
| + | There are lots of events which an event manager is committed to recognizing, | ||
| + | |||
| + | * pressing the mouse button; | ||
| + | * releasing the mouse button (actually, an ordinary mouse click consists of these two subsequent events) | ||
| + | * moving the mouse cursor; | ||
| + | * dragging something under the mouse cursor; | ||
| + | * pressing and releasing a key; | ||
| + | * tapping a screen; | ||
| + | * tracking the passage of time; | ||
| + | * monitoring a widget’s state change; | ||
| + | * and many, many more... | ||
| + | |||
| + | == TkInter | ||
| + | Unfortunately, | ||
| + | |||
| + | This means that if we want to build portable GUI applications (i.e., apps able to work under different operating environments that always look the same) we need something more – we need an adapter. A set of uniform facilities enables us, the programmers, | ||
| + | |||
| + | Such an adapter is called a **widget toolkit**, a **GUI toolkit**, or a **UX library**. | ||
| + | |||
| + | One of these toolkits, which is very attractive to us, is Tk. | ||
| + | |||
| + | Here are some of its features: | ||
| + | |||
| + | * it’s free and open (we don’t need to pay for anything) | ||
| + | * it has been developed since 1991 (which means it’s stable and mature) | ||
| + | * it defines and serves more than thirty different universal widgets (which is enough even for quite complex applications) | ||
| + | * its implementation is available for many programming languages (of course, for Python too) | ||
| + | |||
| + | The module that brings Tk to the Python world is named TkInter, which is short for Tk Interface. It’s free and open, too. | ||
| + | |||
| + | You may have some trouble believing that you’ve been using TkInter for a long time, actually since your very first encounter with programming in Python. | ||
| + | |||
| + | Yes, it’s true – IDLE, the very first Python IDE, is written using TkInter. | ||
| + | |||
| + | We think this is the best recommendation – don’t you? | ||
| + | |||
| + | |||