issue136:python
Différences
Ci-dessous, les différences entre deux révisions de la page.
Prochaine révision | Révision précédente | ||
issue136:python [2018/09/05 08:14] – créée d52fr | issue136:python [2018/09/17 16:06] (Version actuelle) – andre_domenech | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
- | A little while ago, I wrote a blog article about a problem with Python and Tkinter. It has to do with the Checkbox widget not responding properly to the click event, at least in my mind. Here is how it all came about. | + | **A little while ago, I wrote a blog article about a problem with Python and Tkinter. It has to do with the Checkbox widget not responding properly to the click event, at least in my mind. Here is how it all came about. |
I was working on a custom widget for use with a database that implemented a scrolled checked list box. I figured that it would be helpful to be able to show a series of selected items from a list of categories on a per-record basis. As normal, I was using Page to create the GUI. | I was working on a custom widget for use with a database that implemented a scrolled checked list box. I figured that it would be helpful to be able to show a series of selected items from a list of categories on a per-record basis. As normal, I was using Page to create the GUI. | ||
- | I wanted the widget to raise an event whenever any of the checkboxes in the widget were clicked, then display a list of all the selected items. It didn’t really seem like a horribly daunting task at the time. However, when the event fired, and my callback code ran, the last checkbox that was clicked wasn’t on the list. To make matters worse, if I clicked on the same button again, basically unchecking the button, that button THEN showed up on the list. Now that didn’t make any sense to me. I started digging and found the problem. | + | I wanted the widget to raise an event whenever any of the checkboxes in the widget were clicked, then display a list of all the selected items. It didn’t really seem like a horribly daunting task at the time. However, when the event fired, and my callback code ran, the last checkbox that was clicked wasn’t on the list. To make matters worse, if I clicked on the same button again, basically unchecking the button, that button THEN showed up on the list. Now that didn’t make any sense to me. I started digging and found the problem.** |
- | As you probably know, the Checkbutton widget looks just like any GUI checkbutton. It’s an empty box that, when you click it, it shows a check in the box. If you click it again, the check goes away and the box is blank again. Under Tkinter, the Checkbutton widget provides a variable that you can monitor to show the state of the widget by using the .get() method of the widget. If it returns a “1”, then the checkbutton is checked, and if it returns a “0”, it’s unchecked. Pretty simple. I wanted to use the mouse-click event to be the trigger to check the state of the widget. | + | Il y a quelque temps, j'ai écrit un billet de blog au sujet d'un problème avec Python et Tkinter, car le widget des cases à cocher ne répondait pas comme il fallait à l' |
+ | |||
+ | Je travaillais sur un widget personnalisé qui implémentait une fenêtre avec une liste cochée défilante pour l' | ||
+ | |||
+ | Je voulais que le widget présente un événement chaque fois que n' | ||
+ | |||
+ | **As you probably know, the Checkbutton widget looks just like any GUI checkbutton. It’s an empty box that, when you click it, it shows a check in the box. If you click it again, the check goes away and the box is blank again. Under Tkinter, the Checkbutton widget provides a variable that you can monitor to show the state of the widget by using the .get() method of the widget. If it returns a “1”, then the checkbutton is checked, and if it returns a “0”, it’s unchecked. Pretty simple. I wanted to use the mouse-click event to be the trigger to check the state of the widget. | ||
Most of my work these days in under Linux, so that’s the operating system that I did the base work under. I tried various workarounds and still couldn’t get the silly thing to work the way it should. So, I went back to the basics. I created a simple GUI using Page and started exploring. | Most of my work these days in under Linux, so that’s the operating system that I did the base work under. I tried various workarounds and still couldn’t get the silly thing to work the way it should. So, I went back to the basics. I created a simple GUI using Page and started exploring. | ||
Ligne 11: | Ligne 17: | ||
It looked something like this… | It looked something like this… | ||
- | Nothing spectacular, | + | Nothing spectacular, |
+ | |||
+ | Comme vous le savez sans doute, le widget Checkbutton (case à cocher) ressemble à n' | ||
+ | |||
+ | Ces jours-ci, je travaille principalement sous Linux ; aussi, c'est le système d' | ||
+ | |||
+ | Ça ressemblait un peu à ceci... | ||
+ | |||
+ | Rien de spectaculaire, | ||
- | The first two lines are provided by Page as a simple notification that the user has triggered the callback function. I usually leave these in until I’m done with the majority of the early testing. The last line of the function simply shows a ‘1’ or a ‘0’ in the terminal window, to show me what is going on. The thought being that when I click to check the button, I will see a 1 in the terminal. | + | **The first two lines are provided by Page as a simple notification that the user has triggered the callback function. I usually leave these in until I’m done with the majority of the early testing. The last line of the function simply shows a ‘1’ or a ‘0’ in the terminal window, to show me what is going on. The thought being that when I click to check the button, I will see a 1 in the terminal. |
However, what I saw when I ran the program and clicked the widget, was… | However, what I saw when I ran the program and clicked the widget, was… | ||
Ligne 23: | Ligne 37: | ||
chkbtntest_support.on_ChkBtnClick | chkbtntest_support.on_ChkBtnClick | ||
- | 1 | + | 1** |
- | It didn’t make any sense at all. The check value is 180 degrees out of sync with the visual indicator, just like in my custom widget. I’ve used the Checkbutton widget before, many times, and used the .get() method to query the status of that widget, but always from another event like a ‘Save’ button or something like that. | + | Les deux premières lignes sont fournies par Page comme une notification simple du fait que l' |
+ | |||
+ | Toutefois, quand j'ai exécuté le programme et cliqué sur le widget, ce qui j'ai vu était... | ||
+ | |||
+ | chkbtntest_support.on_ChkBtnClick | ||
+ | |||
+ | Et pourtant, je savais que je n' | ||
+ | |||
+ | chkbtntest_support.on_ChkBtnClick | ||
+ | |||
+ | 1 | ||
+ | |||
+ | **It didn’t make any sense at all. The check value is 180 degrees out of sync with the visual indicator, just like in my custom widget. I’ve used the Checkbutton widget before, many times, and used the .get() method to query the status of that widget, but always from another event like a ‘Save’ button or something like that. | ||
Frustrated to the MAX, I decided out of desperation to try the < | Frustrated to the MAX, I decided out of desperation to try the < | ||
Ligne 31: | Ligne 57: | ||
This made me feel much better, since now I have a workaround at least. I modified the code for my custom widget, and it still worked, so I was a happy camper. I even tried the code under both Python 2.x and 3.x and it worked as I wanted. However, this elation was only to be short lived. | This made me feel much better, since now I have a workaround at least. I modified the code for my custom widget, and it still worked, so I was a happy camper. I even tried the code under both Python 2.x and 3.x and it worked as I wanted. However, this elation was only to be short lived. | ||
- | I took my code over to a Windows 10 machine and started it up. Knowing that I had gotten it all figured out, I knew it would work just fine, since the code is all very basic (forgive the term) and nothing would go wrong. | + | I took my code over to a Windows 10 machine and started it up. Knowing that I had gotten it all figured out, I knew it would work just fine, since the code is all very basic (forgive the term) and nothing would go wrong.** |
+ | |||
+ | Ce n' | ||
+ | |||
+ | Ma frustration étant MAXIMALE, j'ai décidé par désespoir d' | ||
+ | |||
+ | Puisque j' | ||
+ | |||
+ | J'ai transféré le code sur une machine sous Windows 10 et l'ai démarré. Sachant que j' | ||
- | Much to my surprise, it couldn’t have gone worse. Not only did the capture of the widget state not work on the mouse release event, it didn’t work using the mouse down event. I could query the state from a different “standard” button AFTER I had clicked the Checkbutton, | + | **Much to my surprise, it couldn’t have gone worse. Not only did the capture of the widget state not work on the mouse release event, it didn’t work using the mouse down event. I could query the state from a different “standard” button AFTER I had clicked the Checkbutton, |
Eventually I came up with a very “dirty” workaround for it under Windows and basically called it a day. I still wanted to find out what was going on, but other projects came up so that project was left for a while. Then, one day, I got some free time and decide to enhance the custom widget to support the scroll wheel. The scroll bar worked with the scroll wheel, but, if you tried to scroll from the center of the widget, nothing happened. That was so counterintuitive that I couldn’t let it go. After a bunch of research, I found a way to do it. Unfortunately, | Eventually I came up with a very “dirty” workaround for it under Windows and basically called it a day. I still wanted to find out what was going on, but other projects came up so that project was left for a while. Then, one day, I got some free time and decide to enhance the custom widget to support the scroll wheel. The scroll bar worked with the scroll wheel, but, if you tried to scroll from the center of the widget, nothing happened. That was so counterintuitive that I couldn’t let it go. After a bunch of research, I found a way to do it. Unfortunately, | ||
- | The other day, I get an email from Don Rozenberg, who is the author of Page. Among other things, he said “Under Linux Mint, pressing and holding button-1 on one of the checkboxes causes it to toggle, whereas under Windows the checkbox doesn' | + | The other day, I get an email from Don Rozenberg, who is the author of Page. Among other things, he said “Under Linux Mint, pressing and holding button-1 on one of the checkboxes causes it to toggle, whereas under Windows the checkbox doesn' |
- | I decided to go back to basics and try to figure out, once and for all, a way to monitor the check state correctly for both operating systems. | + | À ma très grande surprise, cela n' |
+ | |||
+ | Ayant trouvé après maints efforts un très « sale » contournement sous Windows, j'ai décidé de m' | ||
+ | |||
+ | L' | ||
+ | |||
+ | **I decided to go back to basics and try to figure out, once and for all, a way to monitor the check state correctly for both operating systems. | ||
I recreated my simple Checkbutton test GUI app in Page and was in the middle of doing the bindings when I realized that I had forgotten that the Checkbutton widget also has a command attribute that you can use to respond to the mouse events. The main reason that I don’t use it more is that you can’t pass the event object into the callback function, which many times is useful to have since it includes the mouse position. This time, however, it isn’t needed, so I added it to the mix. So now I had callback functions for mouse down, mouse up, and the command event. On the following page (top right) is the code. | I recreated my simple Checkbutton test GUI app in Page and was in the middle of doing the bindings when I realized that I had forgotten that the Checkbutton widget also has a command attribute that you can use to respond to the mouse events. The main reason that I don’t use it more is that you can’t pass the event object into the callback function, which many times is useful to have since it includes the mouse position. This time, however, it isn’t needed, so I added it to the mix. So now I had callback functions for mouse down, mouse up, and the command event. On the following page (top right) is the code. | ||
- | This allowed me to see what happened whenever the mouse got clicked in every way. I started under Linux, since I thought I knew what should be happening. When I ran the program, I got the following (next page, bottom right) in the terminal window… | + | This allowed me to see what happened whenever the mouse got clicked in every way. I started under Linux, since I thought I knew what should be happening. When I ran the program, I got the following (next page, bottom right) in the terminal window…** |
- | That was what I wanted to see. The mouse-down event came first, then the command callback was fired, and finally the mouse-up fired. Good. So, I bundled up my app and booted up the Windows machine. I copied the code to a folder and ran it under Python. The form came up correctly and I clicked the Checkbutton to set it to Checked. | + | J'ai décidé de revenir aux bases pour essayer de trouver une fois pour toute une façon de surveiller correctement l' |
+ | |||
+ | J'ai recréé mon appli de test de Checkbutton en interface graphique avec Page, et j' | ||
+ | |||
+ | Cela m'a permis de voir ce qui se passait à chaque clic sur la souris, quelle que soit la façon dont c' | ||
+ | |||
+ | **That was what I wanted to see. The mouse-down event came first, then the command callback was fired, and finally the mouse-up fired. Good. So, I bundled up my app and booted up the Windows machine. I copied the code to a folder and ran it under Python. The form came up correctly and I clicked the Checkbutton to set it to Checked. | ||
I fully expected to see pretty much the same thing, except that I wouldn’t see the correct state for the button just like I did before. Much to my surprise, this is what I got: | I fully expected to see pretty much the same thing, except that I wouldn’t see the correct state for the button just like I did before. Much to my surprise, this is what I got: | ||
+ | |||
+ | chkbtntest_support.on_ChkBtnClick | ||
+ | Unchecked | ||
+ | |||
+ | chkbtntest_support.on_ChkBtnRelease | ||
+ | Unchecked | ||
+ | |||
+ | chkbtntest_support.on_ChkBtnCommand | ||
+ | Checked** | ||
+ | |||
+ | C' | ||
+ | |||
+ | Je m' | ||
chkbtntest_support.on_ChkBtnClick | chkbtntest_support.on_ChkBtnClick | ||
Ligne 60: | Ligne 119: | ||
- | Under Windows, the mouse up event fires before the command event. AND the command event can query the state of the Checkbutton. Just to make sure, I clicked it again to uncheck it and sure enough I got this: | + | **Under Windows, the mouse up event fires before the command event. AND the command event can query the state of the Checkbutton. Just to make sure, I clicked it again to uncheck it and sure enough I got this: |
Ligne 80: | Ligne 139: | ||
Just goes to show, don’t give up if, the first hundred times, things don’t go the way you expect them to. | Just goes to show, don’t give up if, the first hundred times, things don’t go the way you expect them to. | ||
- | Until next time, have a GREAT month. | + | Until next time, have a GREAT month.** |
+ | |||
+ | Sous Windows, l' | ||
+ | |||
+ | chkbtntest_support.on_ChkBtnClick | ||
+ | Checked | ||
+ | |||
+ | chkbtntest_support.on_ChkBtnRelease | ||
+ | Checked | ||
+ | |||
+ | chkbtntest_support.on_ChkBtnCommand | ||
+ | Unchecked | ||
+ | |||
+ | Ainsi, je sais maintenant que, sous Windows, l' | ||
+ | |||
+ | Je n'ai aucune idée de ce que cela signifie pour quelqu' | ||
+ | |||
+ | J'ai l' | ||
+ | |||
+ | Cela montre bien qu'il faut pas abandonner si, les cent premières fois, les choses ne se passent pas comme vous y attendiez. | ||
+ | |||
+ | À la prochaine fois. Que votre mois soit GÉNIAL ! |
issue136/python.1536128049.txt.gz · Dernière modification : 2018/09/05 08:14 de d52fr