Skip to content
Snippets Groups Projects
Commit f6d0ae38 authored by Derrode Stéphane's avatar Derrode Stéphane :dromedary_camel:
Browse files

ajout sujet #4/tkinter

parent 0c2a8b46
No related branches found
No related tags found
No related merge requests found
......@@ -49,6 +49,8 @@ La réponse apparaît sous forme de 12 lignes. Ça vous rappelle des choses ? Si
### 1.2 Quelques requêtes Python (15 min.)
**Attention** Avant de lancer un requête sur la bdd avec python, il est fortement conseillé de fermer ``DB Browser for SQLite``, sinon vous pourriez soit avoir un plantage de votre programme python, soit détruire la bdd (auquel cas il vous suffirait de la télécharger à nouveau).
Nous allons maintenant chercher à reproduire la requête en utilisant Python et le package ``sqlite3``. C'est une librairie objet dont la [documentation](https://docs.python.org/3/library/sqlite3.html#module-sqlite3) fournit une description des classes et des méthodes disponibles. Suivez le guide...
Le squelette typique d'un tel programme s'écrit:
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="298px" height="183px" viewBox="-0.5 -0.5 298 183" content="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2020-10-01T11:54:44.123Z&quot; agent=&quot;5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36&quot; etag=&quot;epBQuWO_AHDW0usSiURE&quot; version=&quot;13.7.7&quot; type=&quot;device&quot;&gt;&lt;diagram name=&quot;Page-1&quot; id=&quot;c4acf3e9-155e-7222-9cf6-157b1a14988f&quot;&gt;7VjbctowEP0aHmGMjGzzyCWXziRtMuk0IW+yLdtqhEWFIJCvr4RlbOFwCRDStH1htEfWSjp7tFpUs3vD2QVHo+SahZjWgBXOana/BoDrOfJXAfMMgMDOgJiTMIOsArgjLzgDmzk6ISEeayyDBGNUkJEJBixNcSAMDHHOns3PIkZDAxihGFeAuwDRKnpPQpFkqAfcAr/EJE7ymZtOO+vxUfAUczZJ9XwpS3HWM0S5G73HcYJC9lyC7LOa3eOMiaw1nPUwVayajJ2v6V0umeNU7DLgW3d2Mej3O+DL9PJh0KH864DWQUsvTsxzLnAoqdEmpj57PiuA7mKrWHm0pMW4SFjMUkSvGBtJsCnBn1iIuQ4xmggmoYUbaU4xF0SyLqFEDKkegGdEPCiPDRdqc6AnUO3+rGzMcyMNOyrw0gwJGjIVAAWeE5r7HQvOnpbxbEmkSplmUe25BGgCLzAbYsHn8gOOKRJkasoFadXFy++WQ28YkVMASx8Q24YNmA3SJwTYlulkzCY8wHpcOYxvdyUQj7GouJKN0p4KaKGTt2gG/kGa+UsFA6BzHLlsdXQ8sbjn93HyeB+A5JrDyY34UXfH9WZ7o1gKNRyumLI8Urnqh7KxEEgD5mahkYWVi2Qs2RDaq7zC9lANUGubDEfaibdOqw24Ua1rhZfFPYNm3QDz6EZckQ5o33b82193rN7U8c7iuulD94Ok7Lb2k3Iz15J2ZOeX8ImkrFyq6aaITkwyVsR9hXy8kq8QJXEq24GMJ+YSyNNaR3cMSRhm2sdj8oL8hT+lhJHazmKDsFuD/Ve1sfHkqZnwzFivLqP0LEY9YkRej5IXs+2YQdSO9pWG9uKaA1gUjfH7hM7+R0NXtxpey3UPi1buCxgSaL9D8F5NVNVjVw1dkaZ9yoKnLEnrHNw2Ura15qYoXQ6Dct+am6IoWnevWQ9I6u6uSR3umNSfi785Tcc6ij4AWMkRDtwv0dveFkfHS/Svktj6L7jdqwjv4wRnW2ZBsHeRDL3Wyn+qU0suP7eG5hwqme/6shGrxvenHJJTLNGKNEtai6QCe4wyvuixIy/AQbAsWUs9vgdbcKNiKlfR2ivHNQ8v1AIpxT+v25LSkwqA66NvkP1mZp3tzD6yFHeiiASJeic6kOQoAq+THDq+I2vho5AsaV1VLHQrRDct65RMu9uZPsfpDSdpQEbq7e0zMO2ArTS33VOy7G1nuYfSqZz4M2SL5b/Bd08X0iweW7O8Xbxl22e/AQ==&lt;/diagram&gt;&lt;/mxfile&gt;"><defs/><g><path d="M 273.5 172 L 273.5 172 L 273.5 172" fill="none" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 273.5 172 L 273.5 172 L 273.5 172 L 273.5 172 Z" fill="#000000" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><path d="M 194 172 L 194 172 L 194 172" fill="none" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 194 172 L 194 172 L 194 172 L 194 172 Z" fill="#000000" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><path d="M 196.5 111.5 L 106.41 111.5" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 98.41 111.5 L 102.41 107.5 L 106.41 111.5 L 102.41 115.5 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 120px; margin-left: 111px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; ">1</div></div></div></foreignObject><text x="111" y="123" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">1</text></switch></g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 121px; margin-left: 187px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; ">1</div></div></div></foreignObject><text x="187" y="124" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">1</text></switch></g><path d="M 48.5 99 L 48.5 36.12" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 48.5 26.12 L 53.5 36.12 L 43.5 36.12 Z" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 246.5 99 L 246.5 36.12" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 246.5 26.12 L 251.5 36.12 L 241.5 36.12 Z" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="14" y="0" width="69" height="25" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 13px; margin-left: 49px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: nowrap; "><b>Tk</b></div></div></div></foreignObject><text x="49" y="16" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Tk</text></switch></g><rect x="196.5" y="99" width="100" height="25" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 112px; margin-left: 247px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: nowrap; "><b>ZoneAffichage</b></div></div></div></foreignObject><text x="247" y="115" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">ZoneAffichage</text></switch></g><rect x="0" y="99" width="97" height="25" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 112px; margin-left: 49px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: nowrap; "><b>FenPrincipale</b></div></div></div></foreignObject><text x="49" y="115" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">FenPrincipale</text></switch></g><rect x="212" y="0" width="69" height="25" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 13px; margin-left: 247px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: nowrap; "><b>Canvas</b></div></div></div></foreignObject><text x="247" y="16" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Canvas</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://desk.draw.io/support/solutions/articles/16000042487" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Viewer does not support full SVG 1.1</text></a></switch></svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="544px" height="183px" viewBox="-0.5 -0.5 544 183" content="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2020-10-01T12:24:19.841Z&quot; agent=&quot;5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36&quot; etag=&quot;7_P7bSVEtSraPxa-TKuH&quot; version=&quot;13.7.7&quot; type=&quot;device&quot;&gt;&lt;diagram name=&quot;Page-1&quot; id=&quot;c4acf3e9-155e-7222-9cf6-157b1a14988f&quot;&gt;7VpZc6M4EP41fpkqu7iPRx9JJluZmWQzu4nnDYM4NoC8Qr7y61cYySCD8Ykdb+bFhT5BC77+utXqckvuR/M7ZI39b9ABYUsSnHlLHrQkSTc08psCiwxQdCUDPBQ4GSTkwHPwDjJQZOgkcEBCsQzCEIY4GPOgDeMY2JjDLITgjL/NhaHDAWPLAyXg2bbCMvoSONjPUEPSc/wrCDyfrSxqZjYzsuw3D8FJTNeLYQyymchiZug3Jr7lwFkBkm9ach9BiLOraN4HYcoqz9jthtnVKyMQ410e+NGb3w0Hg650P/36OuyG6PswbEvUTwleMC6AQ6ihQxCO4OwmB3rLTwWpRYGMIMI+9GBshQ8QjgkoEvAfgPGCutiaYEigpRkynAKEA8I6gXwchfQBMA/wa2qxo6t0OKQLpNeDeXGwYIPY6aaOJ0MnsCKYOiAFb4OQ2U0wgm8rfyoEKVNGWUy/uQBQAu8AjABGC3IDAqGFgykvF4uqzlvdt3r0EQZkCUmgASLLakfNHqIRIskCbySBE2QD+lzRjfubwhbyAC6ZIheFb8qhpU720Yz6gTTzPxWMpGqnkctWQ6cTi3774vm/XmzJ/4bUySP+u60nbdGsFUuuhuMVU5RHTN76tThYCqSjsmGukeWIiSQhbGBqVZIPUY2UvtskGlMjxiatdtRatW4UXub3DJr3bIDcR/wQdCXzqTt6+vcZtkXq78yvdTfqF5Iyqw32lbLItEQNyWwTPpOUU5PpclMrnPBkrIn7wRqBtXxlhYEXk2ub+BMgArC01qUTUeA4mfZBErxbo6W9VAnj9HOWH6j2WuqgUhu1kZeuBObc+9Iyiq7C1SOc5+lTZGOWNd6J1NCh0qBWdP4B6LoJaMZ18id1XVvoGIquH+ctZkviJGA24LzKRFUOu7Lr8jQ9CqH9liVpmoNNLmULG3aKwuYwLM5t2CnyonX3mvWIpK7vmtTVHZP6LD/miJpwEn1I0lqO0NTDEr1sbDF0ukRfSaLyW3C7VxHG5QQnC3xBcHCRrBrK2pnq3JJjcctpTgsJ870RufDSi59vDCJLrNCSNAtac4kC+zCEaDkju4YNbHtVshZmRoaqqLWKKW1FG7ccnQ9elQqk4H9Wt/mFloqkbvY+R/bezGrbmf0FY9B13cD20z7RkSS7rlRNsqONNFILn4RkQuu6YlW9RLQoCOdkWt/O9C2IH1EQ28E47b1dA9OatJVmUz8ny8Z2lvtWPCULX0O2WJ0Gz58uHpDxM/r+4/3ent0/mX+9A+uPXrv6WNBwu6KZtsOBPZDG2hWVfCu71hnajnXGkTWFosh8vBtrJnYuYjV9zVBjjbdKYj9ss6Iu7D5Zr6KSinKrQuh0vnwG311Zs6Iun9XWQBBF11H7KGw3vkSNWUlvVTHfxNFc4s7mwq5bJnc2FxvaMit6QXVSvMTJXGUncSoclpH3PpibpYO53tjBvI7sunj+M01xsXcl5xlFFDlCL11wmxUENxHR+geOaPY3mA8d0gof0vqBIa2YawW2tlZZNRzQjOu6iL4Jw2CcXEc8q/K5+m1kmP9bKXNH/mcw+eY/&lt;/diagram&gt;&lt;/mxfile&gt;"><defs/><g><path d="M 273.5 172 L 273.5 172 L 273.5 172" fill="none" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 273.5 172 L 273.5 172 L 273.5 172 L 273.5 172 Z" fill="#000000" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><path d="M 194 172 L 194 172 L 194 172" fill="none" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 194 172 L 194 172 L 194 172 L 194 172 Z" fill="#000000" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><path d="M 196.5 111.5 L 106.41 111.5" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 98.41 111.5 L 102.41 107.5 L 106.41 111.5 L 102.41 115.5 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 120px; margin-left: 111px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; ">1</div></div></div></foreignObject><text x="111" y="123" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">1</text></switch></g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 121px; margin-left: 187px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; ">1</div></div></div></foreignObject><text x="187" y="124" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">1</text></switch></g><path d="M 48.5 99 L 48.5 36.12" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 48.5 26.12 L 53.5 36.12 L 43.5 36.12 Z" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 246.5 99 L 246.5 36.12" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 246.5 26.12 L 251.5 36.12 L 241.5 36.12 Z" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="14" y="0" width="69" height="25" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 13px; margin-left: 49px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: nowrap; "><b>Tk</b></div></div></div></foreignObject><text x="49" y="16" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Tk</text></switch></g><rect x="196.5" y="99" width="100" height="25" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 112px; margin-left: 247px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: nowrap; "><b>ZoneAffichage</b></div></div></div></foreignObject><text x="247" y="115" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">ZoneAffichage</text></switch></g><rect x="0" y="99" width="97" height="25" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 112px; margin-left: 49px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: nowrap; "><b>FenPrincipale</b></div></div></div></foreignObject><text x="49" y="115" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">FenPrincipale</text></switch></g><rect x="212" y="0" width="69" height="25" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 13px; margin-left: 247px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: nowrap; "><b>Canvas</b></div></div></div></foreignObject><text x="247" y="16" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Canvas</text></switch></g><path d="M 396 111.5 L 305.91 111.5" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 297.91 111.5 L 301.91 107.5 L 305.91 111.5 L 301.91 115.5 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 120px; margin-left: 311px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; ">1</div></div></div></foreignObject><text x="311" y="123" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">1</text></switch></g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 121px; margin-left: 387px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; ">0..*</div></div></div></foreignObject><text x="387" y="124" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">0..*</text></switch></g><rect x="396" y="99" width="100" height="25" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 112px; margin-left: 446px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: nowrap; "><b>Forme</b></div></div></div></foreignObject><text x="446" y="115" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Forme</text></switch></g><path d="M 383.5 25 L 415.97 89.08" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 420.49 98 L 411.51 91.34 L 420.43 86.82 Z" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="349" y="0" width="69" height="25" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 13px; margin-left: 384px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: nowrap; "><b>Rectangle</b></div></div></div></foreignObject><text x="384" y="16" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Rectangle</text></switch></g><path d="M 508.5 25 L 476.03 89.08" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 471.51 98 L 471.57 86.82 L 480.49 91.34 Z" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="474" y="0" width="69" height="25" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 13px; margin-left: 509px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: nowrap; "><b>Ellipse</b></div></div></div></foreignObject><text x="509" y="16" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Ellipse</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://desk.draw.io/support/solutions/articles/16000042487" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Viewer does not support full SVG 1.1</text></a></switch></svg>
\ No newline at end of file
seanceTk_4h/figures/interface.png

8.7 KiB

class Forme:
def __init__(self, canevas, x, y):
self.__canevas = canevas
self._item = None
self.x = x
self.y = y
def effacer(self):
self.__canevas.delete(self._item)
def deplacement(self, dx, dy):
self.__canevas.move(self._item, dx, dy)
self.x += dx
self.y += dy
class Rectangle(Forme):
def __init__(self, canevas, x, y, l, h, couleur):
Forme.__init__(self, canevas, x, y)
self._item = canevas.create_rectangle(x, y, x+l, y+h, fill=couleur)
self.__l = l
self.__h = h
def __str__(self):
return f"Rectangle d'origine {self.x},{self.y} et de dimensions {self.__l}x{self.__h}"
def get_dim(self):
return self.__l, self.__h
def set_dim(self, l, h):
self.__l = l
self.__h = h
def contient_point(self, x, y):
return self.x <= x <= self.x + self.__l and \
self.y <= y <= self.y + self.__h
def redimension_par_points(self, x0, y0, x1, y1):
self.x = min(x0, x1)
self.y = min(y0, y1)
self.__l = abs(x0 - x1)
self.__h = abs(y0 - y1)
class Ellipse(Forme):
def __init__(self, canevas, x, y, rx, ry, couleur):
Forme.__init__(self, canevas, x, y)
self._item = canevas.create_oval(x-rx, y-ry, x+rx, y+ry, fill=couleur)
self.__rx = rx
self.__ry = ry
def __str__(self):
return f"Ellipse de centre {self.x},{self.y} et de rayons {self.__rx}x{self.__ry}"
def get_dim(self):
return self.__rx, self.__ry
def set_dim(self, rx, ry):
self.__rx = rx
self.__ry = ry
def contient_point(self, x, y):
return ((x - self.x) / self.__rx) ** 2 + ((y - self.y) / self.__ry) ** 2 <= 1
def redimension_par_points(self, x0, y0, x1, y1):
self.x = (x0 + x1) // 2
self.y = (y0 + y1) // 2
self.__rx = abs(x0 - x1) / 2
self.__ry = abs(y0 - y1) / 2
**Sommaire**
[[_TOC_]]
# BE #4 : Application de dessin vectoriel
L'objectif de ce TD est d'apprendre à manipuler quelques composants du module Python _Tkinter_ permettant de créer des interfaces graphiques. Vous allez créer une application simple de dessin vectoriel, qui permettra de tracer à la souris les formes définies dans le BE #2.
## Quelques éléments de Tkinter (45 min.)
Le module _Tkinter_ (_"Tk interface"_) permet de créer des interfaces graphiques. Il contient de nombreux composants graphiques (ou _widgets_), tels que les boutons (classe __Button__), les cases à cocher (classe __CheckButton__), les étiquettes (classe __Label__), les zones d'entrée de texte (classe __Entry__), les menus (classe __Menu__), ou les zones de dessin (classe __Canvas__).
Durant ce BE, nous vous recommandons de conserver la [documentation de _Tkinter_](http://effbot.org/tkinterbook/) ouverte dans un onglet. Elle contient des exemples de code qui vous seront utiles pour utiliser chacun des _widgets_.
Voici un premier exemple de code _Tkinter_ :
```python
import random
from tkinter import *
def tirage():
nb = random.randint(1, 100)
texteResultat.set('Nombre : ' + str(nb))
if __name__ == '__main__':
# création de l'arbre de scène
racine = Tk() # Appel à une méthode de classe (et non un constructeur, cf slide cours #2)
racine.title('Tirage aléatoire')
racine.geometry('300x100+400+400')
# Les widgets de la scène
boutonLancer = Button(racine, text='Tirage')
boutonLancer.pack(side=LEFT, padx=5, pady=5)
texteResultat = StringVar()
labelResultat = Label(racine, textvariable=texteResultat)
labelResultat.pack(side=LEFT, padx=5, pady=5)
boutonQuitter = Button(racine, text='Quitter')
boutonQuitter.pack(side=LEFT, padx=5, pady=5)
# association des commandes aux widgets
boutonLancer.config(command=tirage) # appel dit callback (pas de parenthèses)
boutonQuitter.config(command=racine.quit) # idem
racine.mainloop() # affichage de l'interface jusqu'à quit
```
__Exercice 1 -__ Copiez le code suivant dans un fichier appelé *Exo1.py* et exécutez-le pour observer le résultat.
__Attention, utilisateurs de Mac__ : l'association _Spyder_+_Tkinter_ ne fonctionne pas bien sous Mac! Lorsque vous quitterez l'interface (par le biais du bouton _quitter_), la fenêtre va se bloquer (_freeze_). Deux solutions:
- soit vous forcez l'application à s’arrêter à chaque fois (utilisez le menu contextuel sur l'icône de l'application concernée dans la barre d'outils);
- soit vous exécutez votre programme en ligne de commande. Pour cela, ouvrez un terminal dans le répertoire de travail (clic-droit dessus → Nouveau terminal au dossier). Puis lancer la commande : `python3 Exo1.py`. Vous devriez pouvoir quitter l'application sans difficulté. N'oubliez pas de sauvegarder votre fichier sous _Spyder_ avant toute exécution!
Prenez le temps d'étudier cet exemple, et répondez aux questions suivantes :
* Combien d'éléments contient l'arbre de scène ?
* Que se passe-t-il lorsqu'on clique sur le bouton ?
* Comment peut-on inverser les positions des deux boutons ?
* Comment peut-on augmenter l'espace à gauche et à droite du label ?
* Comment peut-on colorier le texte du label en rouge ?
## Squelette de l'application de dessin (45 min.)
On souhaite obtenir l'interface ci-dessous, dans laquelle les utilisateurs sélectionneront le type de forme à dessiner avec les boutons, et créeront une forme en cliquant dans la zone située sous la barre d'outils (_widget_ __Canvas__ de _Tkinter_). On a donné une couleur grise au fond de la fenêtre pour vous aider à déterminer les widgets présents.
<center><img src="figures/interface.png" style="width:60%"/></center>
__Exercice 2 -__ Dessinez l'arbre de scène correspondant à cette capture d'écran.
Une pratique courante dans les interfaces graphiques est de créer des classes qui _remplacent_ des nœuds de l'arbre de scène, et d'y mettre le code de l'application. Ces classes héritent des classes de _Tkinter_ (pour pouvoir les remplacer dans l'arbre), et nous leur ajouterons des attributs et méthodes spécifiques à leurs responsabilités dans l'application de dessin. Nous allons ainsi introduire deux classes :
* la classe __ZoneAffichage__, qui hérite de __Canvas__ et gère toutes les opérations de dessin spécifiques à votre application.
* la classe __FenPrincipale__, qui hérite de __Tk__ et gère l'initialisation de l'arbre de scène et des _callbacks_ des widgets.
Voici le diagramme UML correspondant :
<center><img src="figures/Fenetre_ZoneAffichage_1.svg" style="width:50%"/></center>
__Exercice 3 -__ Complétez le code ci-dessous avec l'initialisation de votre arbre de scène. Vous utiliserez une instance de __ZoneAffichage__ à la place de __Canvas__. À ce stade, on ne vous demande pas de programmer les actions, uniquement de mettre en place le design de l'interface. Vous trouverez des exemples d'utilisation de chacun des widgets dans la documentation référencée plus haut.
```python
from tkinter import *
class ZoneAffichage(Canvas):
def __init__(self, parent, largeur, hauteur):
Canvas.__init__(self, parent, width=largeur, height=hauteur)
class FenPrincipale(Tk):
def __init__(self):
Tk.__init__(self)
# L'initialisation de l'arbre de scène se fait ici
if __name__ == "__main__":
fen = FenPrincipale()
fen.mainloop()
```
## Dessin de formes dans le canevas (60 min.)
Vous trouverez dans le dossier de ce BE le fichier [formes.py](formes.py) développé durant le BE #2. Nous avons agrémenté les classes __Rectangle__ et __Ellipse__ pour qu'elles reçoivent un canevas en argument et se dessinent dessus lors de leur initialisation. Téléchargez ce fichier dans votre répertoire de travail.
Les classes seront intégrées selon le diagramme UML suivant :
<center><img src="figures/Fenetre_ZoneAffichage_2.svg" style="width:90%"/></center>
__Exercice 4 -__ Créez une méthode `ajout_forme(..., x, y)` dans __ZoneAffichage__ qui crée un __Rectangle__ dont le centre sera donné par les 2 arguments _x_ et _y_, de largeur 10 et de hauteur 20. N'oubliez pas de stocker ce rectangle dans __ZoneAffichage__ !
__Exercice 5 -__ À l'aide de la méthode `bind` vue en cours, reliez les clics de souris sur le canevas (évènements `<ButtonRelease-1>`) à la méthode `ajout_forme`. Attention, pour utiliser une méthode comme fonction de _callback_, il faut la précéder de `self.`.
__Exercice 6 -__ Ajoutez un attribut à __ZoneAffichage__ qui stocke le type de forme actuellement sélectionné, et associez les boutons Rectangle/Ellipse au type de forme qui est dessiné lorsqu'on clique dans le canevas.
## Quelques opérations de dessin supplémentaires (90 min.)
Nous allons à présent intégrer quelques commandes simples dans l'application de dessin :
* Lorsqu'on clique sur une forme en maintenant la touche CTRL enfoncée, elle doit être effacée du canevas.
* Lorsqu'on déplace la souris avec le bouton enfoncé sur une forme, on déplace la forme en même temps que la souris.
* Lorsqu'on clique sur le bouton _Couleur_, un sélecteur de couleur apparaît pour choisir la couleur de l'outil de dessin.
__Exercice 7 -__ Implémentez l'effacement des formes avec CTRL-clic (événement `<Control-ButtonRelease-1>`). Vous pourrez faire appel aux méthodes `contient_point(...)` des classes __Rectangle__ et __Ellipse__ pour déterminer si la position de la souris au moment de l’événement est dans le périmètre d'une forme donnée, ainsi qu'à la méthode `effacer(...)` de la classe __Forme__.
__Exercice 8 -__ À l'aide du module _colorchooser_ de _Tkinter_ (```from tkinter import colorchooser```), liez les clics sur le bouton Couleur à l'affichage d'un sélecteur de couleur, et utilisez la couleur renvoyée pour tous les ajouts de formes suivants.
__Exercice 9 -__ À l'aide des types d’événements `<Button-1>`, `<B1-Motion>` et `<ButtonRelease-1>`, implémentez la translation des formes lors des actions d'appui-déplacement de la souris. Comment faire pour qu'elles n'interfèrent pas avec la création de nouvelles formes ?
## Exercices bonus
Il n'y a pas d'ordre prédéfini pour ces trois exercices supplémentaires, choisissez celui dont la fonctionnalité vous semble la plus intéressante.
__Bonus 1 -__ Durant le BE #2 vous avez conçu un troisième type de forme. Il est temps de l'intégrer à votre application de dessin ! Inspirez-vous du code du fichier _formes.py_ de ce BE pour adapter la classe que vous aviez développée. Vous trouverez également les instructions de dessin dans la documentation de Tkinter sur __Canvas__.
__Bonus 2 -__ Maintenant que votre programme de dessin vectoriel est fonctionnel, il devrait être possible d'exporter chaque image produite dans un fichier. On utilise pour cela le format SVG, qui est un fichier texte contenant des instructions de dessin. Il suffit d'écrire `<svg width=600 height=400 xmlns=http://www.w3.org/2000/svg>` au début du fichier, `</svg>` à la fin, et d'insérer des balises [`rect`](https://developer.mozilla.org/fr/docs/Web/SVG/Element/rect) et [`ellipse`](https://developer.mozilla.org/fr/docs/Web/SVG/Element/ellipse) entre les deux. C'est à vous !
__Bonus 3 -__ Dans tout programme de dessin respectable, on doit pouvoir dessiner des formes de tailles arbitraires (pas prédéfinies). À l'aide des types d’événements `<Button-1>`, `<B1-Motion>` et `<ButtonRelease-1>`, faites qu'un mouvement de souris avec le bouton enfoncé dessine une forme en tirant ses coins (lorsqu'il ne déplace pas une forme existante). Vous utiliserez les méthodes `redimension_par_points` des classes __Rectangle__ et __Ellipse__.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment