{"id":455505,"date":"2025-04-11T09:03:23","date_gmt":"2025-04-11T09:03:23","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=455505"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=455505","title":{"rendered":"<span>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u0433\u0440\u0443\u0448\u0435\u0447\u043d\u044b\u0439 \u043e\u043a\u043e\u043d\u043d\u044b\u0439 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0432 \u0440\u0435\u0442\u0440\u043e-\u0441\u0442\u0438\u043b\u0435 Windows 3.x \u043d\u0430 Python<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/98a\/16d\/422\/98a16d422a9c69475d3207effcc65a02.png\" width=\"640\" height=\"480\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/98a\/16d\/422\/98a16d422a9c69475d3207effcc65a02.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/98a\/16d\/422\/98a16d422a9c69475d3207effcc65a02.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0417\u043d\u0430\u043a\u043e\u043c\u043e, \u043f\u0440\u0430\u0432\u0434\u0430? \u0414\u0430, \u0434\u0430 &#8212; \u044d\u0442\u043e &#171;\u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u0441\u0442\u043e\u043b&#187; Windows 3.1, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u044b\u0448\u043b\u0430 \u0432 1992 \u0433\u043e\u0434\u0443. \u0418 \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0432\u044b \u043d\u0435 \u0438\u0437 \u0442\u043e\u0433\u043e \u043f\u043e\u043a\u043e\u043b\u0435\u043d\u0438\u044f, \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u0441\u0432\u0435\u043b\u043e \u043e\u043b\u0434\u0441\u043a\u0443\u043b\u044b, \u0432\u044b, \u044f \u0434\u0443\u043c\u0430\u044e, \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u0445\u043e\u0442\u044c \u0440\u0430\u0437 \u0432 \u0436\u0438\u0437\u043d\u0438 \u0432\u0438\u0434\u0435\u043b\u0438 \u044d\u0442\u0443 \u041e\u0421 (\u0445\u043e\u0442\u044f \u0431\u044b \u043d\u0430 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0435) \u0438 \u043d\u0435 \u043e\u0441\u0442\u0430\u043b\u0438\u0441\u044c \u043a \u043d\u0435\u0439 \u0440\u0430\u0432\u043d\u043e\u0434\u0443\u0448\u043d\u044b.<\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u0435\u043d\u044c\u043a\u0438\u0439 <em>\u0438\u0433\u0440\u0443\u0448\u0435\u0447\u043d\u044b\u0439<\/em> \u043e\u043a\u043e\u043d\u043d\u044b\u0439 <em>\u043f\u0441\u0435\u0432\u0434\u043e<\/em>-\u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0432 \u0441\u0442\u0438\u043b\u0435 Windows 3.x. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c Python \u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 Tkinter. \u0412\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a:<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/16e\/322\/2b4\/16e3222b4d22b89ac2c618657951289d.png\" alt=\"\u0427\u0435\u043c-\u0442\u043e \u0441\u043c\u0430\u0445\u0438\u0432\u0430\u0435\u0442\" title=\"\u0427\u0435\u043c-\u0442\u043e \u0441\u043c\u0430\u0445\u0438\u0432\u0430\u0435\u0442\" width=\"1920\" height=\"1080\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/16e\/322\/2b4\/16e3222b4d22b89ac2c618657951289d.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/16e\/322\/2b4\/16e3222b4d22b89ac2c618657951289d.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0427\u0435\u043c-\u0442\u043e \u0441\u043c\u0430\u0445\u0438\u0432\u0430\u0435\u0442<\/figcaption><\/div>\n<\/figure>\n<p>\u0426\u0435\u043b\u044c\u044e \u0441\u0442\u0430\u0442\u044c\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u043f\u0438\u0438 3.x, \u0430 \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u043d\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0433\u043b\u0430\u0432\u043d\u043e\u0439 \u0444\u0438\u0447\u0438 Windows, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438 \u0434\u0430\u043b\u0430 \u0435\u0439 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 &#8212; \u043e\u043a\u043e\u0448\u0435\u043a. \u0421\u0442\u0438\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u0434 3.x, \u0440\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f.<\/p>\n<p>\u041d\u0443 \u0447\u0442\u043e \u0436\u0435, \u043f\u043e\u0435\u0445\u0430\u043b\u0438!<\/p>\n<hr\/>\n<h2>\u041a\u0430\u043a \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u043e<\/h2>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code> \u251c\u2500\u2500\u2500main.py \u2502 \u251c\u2500\u2500\u2500assets \u2502 \u2514\u2500\u2500\u2500sources     \u251c\u2500\u2500\u2500program     \u2502       calc.py     \u2502       notepad.py     \u2502       terminal.py     \u2502     \u2514\u2500\u2500\u2500window             manager.py             window.py<\/code><\/pre>\n<p>\u0423 \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 \u0442\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430 (main.py), \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0432\u0441\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443, \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 <code>Window <\/code>(sources\/window.py), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0437\u0430 \u043e\u043a\u043d\u0430 \u043d\u0430\u0448\u0435\u0439 \u043f\u0441\u0435\u0432\u0434\u043e-windows, \u0438 <code>WindowManager<\/code> (sources\/manager.py), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044d\u0442\u0438\u043c\u0438 \u043e\u043a\u043d\u0430\u043c\u0438 \u0431\u0443\u0434\u0435\u0442 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c.<\/p>\n<p>\u0412 \u043f\u0440\u0438\u0434\u0430\u0447\u0443 \u0443 \u043d\u0430\u0441 \u0438\u0434\u0435\u0442 \u0435\u0449\u0435 3 \u0434\u0435\u043c\u043a\u0438, \u043d\u043e \u043e\u043d\u0438 \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b \u0438 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0441 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u043e\u043c \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u0441\u0432\u044f\u0437\u0430\u043d\u044b (\u0432 \u0441\u043c\u044b\u0441\u043b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439). \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0438 \u0441\u0432\u043e\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f &#8212; \u0433\u043b\u0430\u0432\u043d\u043e\u0435, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0438 \u0431\u044b\u043b\u0438 \u043d\u0430 tkinter, \u0430 \u0438\u0445 \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043bc\u044f \u043e\u0442<code> tk.Frame<\/code><\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0415\u0441\u043b\u0438 \u0438\u0434\u0435\u044f \u043f\u043e\u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f \u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u0438, \u0442\u043e \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u043e\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0438\u0445\u043d\u0443\u0442\u044c pygame \u0432 \u0444\u0440\u0435\u0439\u043c tkinter<\/p>\n<\/div>\n<\/details>\n<h3>\u041f\u0430\u0440\u0430 \u0441\u043b\u043e\u0432 \u043e \u0441\u0442\u0438\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438<\/h3>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9c7\/0c4\/f5d\/9c70c4f5d83fcda52f35dd9a973de8ea.png\" alt=\"Windows 3.11 \u0432 DOSBox\" title=\"Windows 3.11 \u0432 DOSBox\" width=\"639\" height=\"480\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/9c7\/0c4\/f5d\/9c70c4f5d83fcda52f35dd9a973de8ea.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9c7\/0c4\/f5d\/9c70c4f5d83fcda52f35dd9a973de8ea.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Windows 3.11 \u0432 DOSBox<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u044f \u0441\u0442\u0430\u0440\u0430\u043b\u0441\u044f \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b (\u0441\u043c. \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443). \u0412 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0442\u0430\u043a\u0436\u0435, \u043a\u0430\u043a \u0432 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u0435, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0438\u043d\u0438\u0439 \u0446\u0432\u0435\u0442 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430, \u0440\u0430\u043c\u043a\u0430 \u0432\u043e\u043a\u0440\u0443\u0433 \u043e\u043a\u043d\u0430 \u0441 \u0443\u0433\u043e\u043b\u043a\u0430\u043c\u0438 \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u043c\u0435\u0440\u0430, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0442\u0430\u043a\u0438\u0435 \u0436\u0435 \u043a\u043d\u043e\u043f\u043a\u0438 \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0435. \u041d\u043e \u0443 \u043d\u0430\u0441 \u043d\u0435\u0442 \u043f\u043e\u043b\u043d\u043e\u0433\u043e \u0441\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f \u043e\u043a\u043e\u043d (\u043a\u043d\u043e\u043f\u043a\u0430 \u0441\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u043a\u043d\u043e \u043a \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c\u0443 \u0440\u0430\u0437\u043c\u0435\u0440\u0443), \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 Program Manager, \u0433\u0440\u0443\u043f\u043f\u044b \u0438 \u043c\u043d\u043e\u0433\u043e \u0447\u0435\u0433\u043e \u0435\u0449\u0451. \u041d\u043e \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0432\u0441\u0435-\u0442\u0430\u043a\u0438 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442.<\/p>\n<p>\u0418\u0442\u0430\u043a, \u043d\u0430\u0447\u043d\u0435\u043c.<\/p>\n<h2>\u041a\u043b\u0430\u0441\u0441 Window<\/h2>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u0442\u044c \u043a \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 \u043e\u043a\u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441:<\/p>\n<pre><code class=\"python\">from enum import IntFlag   class WindowFlags(IntFlag):     \"\"\"     Bitmap flags for window options.      'WN' means 'Window Not', so 'WN_DRAGABLE' means 'Window Not Dragable',     'WN_RESIZABLE' means 'Window Not Resizable', and so on.      \"\"\"     WN_CONTROLS = 1     WN_DRAGABLE = 2     WN_RESIZABLE = 4<\/code><\/pre>\n<p>\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043d\u0435\u0433\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u0438 \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043d\u0430\u0448\u0435\u0433\u043e \u043e\u043a\u043d\u0430:<\/p>\n<ul>\n<li>\n<p>WN_CONTROLS &#8212; \u0432\u044b\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u043a\u043d\u043e\u043f\u043a\u0438 \u0441\u0432\u0435\u0440\u043d\u0443\u0442\u044c\/\u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c<\/p>\n<\/li>\n<li>\n<p>WN_DRAGABLE &#8212; \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435 \u043e\u043a\u043d\u0430 \u0437\u0430 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a (\u043d\u043e \u0437\u0430 \u0443\u0433\u043b\u044b \u043f\u043e\u043a\u0430 \u0435\u0449\u0435 \u043c\u043e\u0436\u043d\u043e, \u044d\u0442\u043e \u0431\u0430\u0433)))<\/p>\n<\/li>\n<li>\n<p>WN_RESIZABLE &#8212; \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u0432 \u043e\u043a\u043d\u0430<\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0432\u044b \u0443\u0436\u0435 \u0434\u043e\u0433\u0430\u0434\u0430\u043b\u0438\u0441\u044c, \u0447\u0442\u043e \u044d\u0442\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0437\u0430\u0434\u0430\u044e\u0442\u0441\u044f \u0431\u0438\u0442\u043e\u0432\u044b\u043c\u0438 \u0444\u043b\u0430\u0433\u0430\u043c\u0438. \u0422\u0430\u043a \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0443\u0434\u043e\u0431\u043d\u0435\u0435 \u0438\u0445 \u0441\u043e\u0447\u0435\u0442\u0430\u0442\u044c \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c &#8212; \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043a\u0443\u0447\u0443 bool-\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445. \u041f\u043e\u0437\u0436\u0435 \u0432\u044b \u0443\u0432\u0438\u0434\u0438\u0442\u0435, \u043a\u0430\u043a \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c (\u0435\u0441\u043b\u0438, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0431\u0443\u0434\u0435\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0447\u0438\u0442\u0430\u0442\u044c \u043a\u043e\u0434)<\/p>\n<details class=\"spoiler\">\n<summary>\u0422\u0430\u0431\u043b\u0438\u0446\u0430 \u0444\u043b\u0430\u0433\u043e\u0432<\/summary>\n<div class=\"spoiler__content\">\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\"><strong>\u0424\u043b\u0430\u0433\u0438<\/strong><\/p>\n<\/th>\n<th>\n<p align=\"left\"><strong>\u0414\u0432\u043e\u0438\u0447\u043d\u043e\u0435<\/strong><\/p>\n<\/th>\n<th>\n<p align=\"left\"><strong>\u0414\u0435\u0441\u044f\u0442\u0438\u0447\u043d\u043e\u0435<\/strong><\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">WN_CONTROLS<\/p>\n<\/td>\n<td>\n<p align=\"left\">001<\/p>\n<\/td>\n<td>\n<p align=\"left\">1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">WN_DRAGABLE<\/p>\n<\/td>\n<td>\n<p align=\"left\">010<\/p>\n<\/td>\n<td>\n<p align=\"left\">2<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">WN_RESIZABLE<\/p>\n<\/td>\n<td>\n<p align=\"left\">100<\/p>\n<\/td>\n<td>\n<p align=\"left\">4<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<\/details>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u043e\u043a\u043d\u0443. \u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043a\u043b\u0430\u0441\u0441:<\/p>\n<pre><code class=\"python\">import tkinter as tk from PIL import Image, ImageTk  # WindowFlags here   class Window:     \"\"\"     A class representing a draggable, resizable window in the style of Windows 3.1.      The window includes a title bar with minimize, maximize and close buttons,     resizable corners, and a content area that can contain child windows.     \"\"\"      def __init__(self, parent, title, content, size, flags):         \"\"\"Initialize a new window.          Args:             parent: The parent widget (either the main frame or another window's content area)             title: The title of the window             content: The content widget to be placed inside the window             size: A tuple of (x, y, width, height) for the window's initial position and size             flags: Bitmap flags for window options         \"\"\"         self.parent = parent         self.title = title         self.content = content         self.size = size         self.flags = flags          # Initialize window state variables         self.is_resizing = False         self.is_maximized = False          # Store the previous size and position for restoration when un-maximizing         self.resize_offset_x = 0         self.resize_offset_y = 0          # Create a list to store child windows references         self.childs = []          self.create_window()         if self.content:             self.set_content(self.content)<\/code><\/pre>\n<p>\u041d\u0430\u0448\u0435 \u043e\u043a\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437:<\/p>\n<ul>\n<li>\n<p>\u0417\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430 \u0441 \u043a\u043d\u043e\u043f\u043a\u0430\u043c\u0438 (<code>self.title<\/code>)<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/583\/eb8\/913\/583eb891328c840e5fcd114c142918d3.png\" width=\"748\" height=\"49\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/583\/eb8\/913\/583eb891328c840e5fcd114c142918d3.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/583\/eb8\/913\/583eb891328c840e5fcd114c142918d3.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<\/li>\n<li>\n<p>\u0420\u0430\u043c\u043a\u0438 \u0432\u043e\u043a\u0440\u0443\u0433 \u043e\u043a\u043d\u0430 \u0441 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c\u0438 \u0443\u0433\u043b\u0430\u043c\u0438 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f (\u0432 init \u043d\u0435 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442, \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u0435\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e)<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/8e1\/b4f\/0c9\/8e1b4f0c9b79efb7c4606cf59afeedc6.png\" width=\"757\" height=\"457\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/8e1\/b4f\/0c9\/8e1b4f0c9b79efb7c4606cf59afeedc6.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/8e1\/b4f\/0c9\/8e1b4f0c9b79efb7c4606cf59afeedc6.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<\/li>\n<li>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e (<code>self.content<\/code>)<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b01\/f66\/9c9\/b01f669c9497e60e074f7d58228e7520.png\" width=\"753\" height=\"398\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/b01\/f66\/9c9\/b01f669c9497e60e074f7d58228e7520.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b01\/f66\/9c9\/b01f669c9497e60e074f7d58228e7520.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<\/li>\n<li>\n<p>\u0418 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043e\u043a\u043e\u043d (\u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e) (<code>self.childs<\/code>)<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/02e\/cf3\/127\/02ecf3127bf33fa0e1635ec181ebf79c.png\" width=\"831\" height=\"813\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/02e\/cf3\/127\/02ecf3127bf33fa0e1635ec181ebf79c.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/02e\/cf3\/127\/02ecf3127bf33fa0e1635ec181ebf79c.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<\/li>\n<\/ul>\n<p>\u041e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435, \u0434\u0443\u043c\u0430\u044e, \u0432 \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u044f\u0445 \u043d\u0435 \u043d\u0443\u0436\u0434\u0430\u0435\u0442\u0441\u044f. \u0418\u0434\u0451\u043c \u0434\u0430\u043b\u044c\u0448\u0435:<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">def create_window(self):         \"\"\" Create the window's visual elements and set up event bindings \"\"\"          # Unpack the size tuple         x, y, width, height = self.size          # Create the main window frame         self.window_frame = tk.LabelFrame(             self.parent,             relief=\"flat\",             padx=2,             pady=2,             background=\"#878A8D\",             highlightthickness=1,             highlightcolor=\"#000000\",             highlightbackground=\"#000000\"         )         self.window_frame.place(x=x, y=y, width=width, height=height)          # Add resizable corners if the window is resizable         if not self.flags &amp; WindowFlags.WN_RESIZABLE:             self.corner_A = tk.LabelFrame(                 self.window_frame,                 width=31,                 height=31,                 bg=\"#878A8D\",                 highlightthickness=1,                 highlightcolor=\"#000000\",                 highlightbackground=\"#000000\",                 relief=\"flat\"             )             self.corner_A.place(x=-5, y=-5)              self.corner_B = tk.LabelFrame(                 self.window_frame,                 width=31,                 height=31,                 bg=\"#878A8D\",                 highlightthickness=1,                 bd=1,                 highlightcolor=\"#000000\",                 highlightbackground=\"#000000\",                 relief=\"flat\"             )             self.corner_B.place(relx=1.0, x=5, y=-5, anchor='ne')              self.corner_C = tk.LabelFrame(                 self.window_frame,                 width=31,                 height=31,                 bg=\"#878A8D\",                 highlightthickness=1,                 bd=1,                 highlightcolor=\"#000000\",                 highlightbackground=\"#000000\",                 relief=\"flat\"             )             self.corner_C.place(relx=1.0, x=5, rely=1.0, y=5, anchor='se')              self.corner_D = tk.LabelFrame(                 self.window_frame,                 width=31,                 height=31,                 bg=\"#878A8D\",                 highlightthickness=1,                 bd=1,                 highlightcolor=\"#000000\",                 highlightbackground=\"#000000\",                 relief=\"flat\"             )             self.corner_D.place(rely=1.0, x=-5, y=5, anchor='sw')          # Create the title bar with a close button         self.title_bar = tk.Frame(             self.window_frame,             relief=\"raised\",             borderwidth=1,             background=\"#000000\",             highlightthickness=0,             highlightcolor=\"#FCFCFC\",             highlightbackground=\"#FCFCFC\"         )         self.title_bar.pack(fill=\"x\")          self.close_icon = ImageTk.PhotoImage(             Image.open(\".\/assets\/close_button.bmp\"))         self.close_button = tk.Button(             self.title_bar,             command=self.show_context_menu,             image=self.close_icon,             width=20,             height=20,             borderwidth=1,             relief=\"flat\",             anchor=\"center\",             bg=\"#C0C7C8\",             activebackground=\"#C0C7C8\",             fg=\"#000000\",             highlightthickness=1,             highlightcolor=\"#000000\",             highlightbackground=\"#000000\"         )         self.close_button.pack(side=\"left\")          self.title_label = tk.Label(             self.title_bar,             text=self.title,             font=(\"Arial\", 10, \"bold\"),             anchor=\"center\",             background=\"#000076\",             foreground=\"#FCFCFC\"         )         self.title_label.pack(side=\"left\", fill=\"both\", expand=True)          # Add maximize and minimize buttons if the window has controls         if not self.flags &amp; WindowFlags.WN_CONTROLS:             self.maximize_icon = ImageTk.PhotoImage(                 Image.open(\".\/assets\/maximize_button.bmp\"))             self.maximize_button = tk.Button(                 self.title_bar,                 command=self.maximize_window,                 image=self.maximize_icon,                 width=20,                 height=20,                 borderwidth=1,                 relief=\"raised\",                 anchor=\"center\",                 bg=\"#C0C7C8\",                 activebackground=\"#C0C7C8\",                 fg=\"#000000\",                 highlightthickness=1,                 highlightcolor=\"#000000\",                 highlightbackground=\"#000000\"             )             self.maximize_button.pack(side=\"right\")              self.shrink_icon = ImageTk.PhotoImage(                 Image.open(\".\/assets\/minimize_button.bmp\"))             self.shrink_button = tk.Button(                 self.title_bar,                 command=self.minimize_window,                 image=self.shrink_icon,                 width=20,                 height=20,                 borderwidth=1,                 relief=\"raised\",                 anchor=\"center\",                 bg=\"#C0C7C8\",                 activebackground=\"#C0C7C8\",                 fg=\"#000000\",                 highlightthickness=1,                 highlightcolor=\"#000000\",                 highlightbackground=\"#000000\"             )             self.shrink_button.pack(side=\"right\")          # Create the content area of the window         self.window_content = tk.Frame(             self.window_frame,             bg=\"#ffffff\",             highlightthickness=1,             highlightcolor=\"#000000\",             highlightbackground=\"#000000\"         )         self.window_content.pack(fill=\"both\", expand=True)          # Bind drag events if the window is draggable         if not self.flags &amp; WindowFlags.WN_DRAGABLE:             self.window_frame.bind(\"&lt;ButtonPress-1&gt;\", self.start_drag)             self.window_frame.bind(\"&lt;ButtonRelease-1&gt;\", self.stop_drag)             self.window_frame.bind(\"&lt;B1-Motion&gt;\", self.drag)              self.title_label.bind(\"&lt;ButtonPress-1&gt;\", self.start_drag)             self.title_label.bind(\"&lt;ButtonRelease-1&gt;\", self.stop_drag)             self.title_label.bind(\"&lt;B1-Motion&gt;\", self.drag)          # Bind resize events if the window is resizable         if not self.flags &amp; WindowFlags.WN_RESIZABLE:             self.corner_A.bind(\"&lt;ButtonPress-1&gt;\", self.start_resize)             self.corner_A.bind(\"&lt;ButtonRelease-1&gt;\", self.stop_resize)             self.corner_A.bind(\"&lt;B1-Motion&gt;\", self.resize)              self.corner_B.bind(\"&lt;ButtonPress-1&gt;\", self.start_resize)             self.corner_B.bind(\"&lt;ButtonRelease-1&gt;\", self.stop_resize)             self.corner_B.bind(\"&lt;B1-Motion&gt;\", self.resize)              self.corner_C.bind(\"&lt;ButtonPress-1&gt;\", self.start_resize)             self.corner_C.bind(\"&lt;ButtonRelease-1&gt;\", self.stop_resize)             self.corner_C.bind(\"&lt;B1-Motion&gt;\", self.resize)              self.corner_D.bind(\"&lt;ButtonPress-1&gt;\", self.start_resize)             self.corner_D.bind(\"&lt;ButtonRelease-1&gt;\", self.stop_resize)             self.corner_D.bind(\"&lt;B1-Motion&gt;\", self.resize)              self.window_frame.bind(\"&lt;ButtonPress-1&gt;\", self.start_resize)             self.window_frame.bind(\"&lt;ButtonRelease-1&gt;\", self.stop_resize)             self.window_frame.bind(\"&lt;B1-Motion&gt;\", self.resize)          # Track window size and position changes          self.window_frame.bind(             \"&lt;Configure&gt;\", self.track_window_size_and_position)         self.title_label.bind(             \"&lt;Configure&gt;\", self.track_window_size_and_position)          self.context_menu = tk.Menu(self.window_frame,                                     tearoff=0,                                     bg=\"#C0C0C0\",                                     fg=\"black\",                                     activebackground=\"#808080\",                                     activeforeground=\"white\",                                     font=(\"MS Sans Serif\", 8))          self.context_menu.add_command(label=\"Close\", command=self.close_window)         self.context_menu.add_command(             label=\"Minimize\", command=self.minimize_window)         self.context_menu.add_command(             label=\"Maximize\", command=self.maximize_window) <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u042d\u0442\u043e \u0441\u0430\u043c\u0430\u044f \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043a\u043b\u0430\u0441\u0441\u0430. \u041e\u043d\u043e \u0438 \u043f\u043e\u043d\u044f\u0442\u043d\u043e &#8212; \u0437\u0434\u0435\u0441\u044c \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0440\u0430\u043c\u043a\u0443 \u0432\u043e\u043a\u0440\u0443\u0433 \u043e\u043a\u043d\u0430, \u0443\u0433\u043b\u044b (\u0435\u0441\u043b\u0438 \u0440\u0430\u0437\u043c\u0435\u0440 \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c), \u043f\u0430\u043d\u0435\u043b\u044c \u043c\u0435\u043d\u044e \u0441 \u043a\u043d\u043e\u043f\u043a\u0430\u043c\u0438 \u0438 \u043f\u0440\u0438\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u043c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f. \u0412 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435 \u0432\u0441\u0451 \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0433\u043b\u0443\u0431\u043e\u043a\u043e \u0432\u043d\u0438\u043a\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c, \u043f\u043e\u0439\u0434\u0451\u043c \u0434\u0430\u043b\u044c\u0448\u0435.<\/p>\n<blockquote>\n<p>\u041a\u043e\u0433\u0434\u0430 \u044f \u043f\u0438\u0441\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u044e, \u044f \u0434\u0443\u043c\u0430\u043b, \u0440\u0430\u0441\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043b\u0438 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0432\u0441\u044e \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u044e \u043d\u0430\u0448\u0435\u0433\u043e &#171;\u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430 \u043e\u043a\u043e\u043d&#187;, \u0438 \u0440\u0435\u0448\u0438\u043b, \u0447\u0442\u043e \u043d\u0435 \u0441\u0442\u043e\u0438\u0442. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u044d\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u0442\u0440\u0443\u0434\u043e\u0451\u043c\u043a\u043e \u0438 \u043e\u0431\u044a\u0451\u043c\u043d\u043e, \u0441\u0442\u0430\u0442\u044c\u044f \u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0430\u0441\u044c \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0438 \u0441\u043a\u0443\u0447\u043d\u043e\u0439. \u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u044d\u0442\u043e \u043d\u0438\u043a\u043e\u043c\u0443 \u043e\u0441\u043e\u0431\u043e \u043d\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e. \u0415\u0441\u043b\u0438 \u0432\u044b \u043d\u043e\u0432\u0438\u0447\u043e\u043a \u0432 tkinter \u0432\u0430\u0441 \u044d\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u043f\u0443\u0442\u0430\u0435\u0442, \u0430 \u0435\u0441\u043b\u0438 \u0432\u044b \u0443\u0436\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0441 \u043d\u0438\u043c, \u0442\u043e \u0432\u044b \u0431\u0435\u0437 \u043e\u0441\u043e\u0431\u043e\u0433\u043e \u0442\u0440\u0443\u0434\u0430 \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u0442\u0435\u0441\u044c, \u043a\u0430\u043a \u0432\u0441\u0451 \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f.<\/p>\n<\/blockquote>\n<p>\u0410 \u0434\u0430\u043b\u044c\u0448\u0435 \u0443 \u043d\u0430\u0441:<\/p>\n<p>\u041c\u0435\u0442\u043e\u0434 <code>show_context_menu<\/code>. \u041e\u043d \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0432\u043e\u0442 \u0437\u0430 \u044d\u0442\u043e:<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/01f\/12c\/48a\/01f12c48a2a0185e00b7085eecafeb4c.png\" width=\"512\" height=\"302\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/01f\/12c\/48a\/01f12c48a2a0185e00b7085eecafeb4c.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/01f\/12c\/48a\/01f12c48a2a0185e00b7085eecafeb4c.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<pre><code class=\"python\">    def show_context_menu(self):         \"\"\"Show the context menu at the mouse position.\"\"\"                  # Get the position of the close button         x = self.close_button.winfo_rootx()         y = self.close_button.winfo_rooty() + self.close_button.winfo_height()          # Post the context menu at the position of the close button         self.context_menu.tk_popup(x, y)<\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c <code>close_window<\/code>. \u041e\u043d \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0430\u0435\u0442 \u043e\u043a\u043d\u043e \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 Close<\/p>\n<pre><code class=\"python\">def close_window(self):         \"\"\" Destroy the window and remove it from the display \"\"\"         self.window_frame.destroy()<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0443 \u043d\u0430\u0441 \u0438\u0434\u0435\u0442 \u0441\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435 (minimize) \u0438 \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435 (maximaize) \u043e\u043a\u043d\u0430. \u041f\u043e\u043a\u0430 \u044d\u0442\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e \u0442\u0430\u043a: \u043a\u043d\u043e\u043f\u043a\u0430 &#171;\u0421\u0432\u0435\u0440\u043d\u0443\u0442\u044c&#187; \u0441\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442 \u043e\u043a\u043d\u043e \u043a \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c\u0443 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044e, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043e\u043d\u043e \u0431\u044b\u043b\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u043e, \u043d\u043e \u043d\u0435 \u0441\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e, \u043a\u043d\u043e\u043f\u043a\u0430 &#171;\u0420\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c&#187; \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442 \u043e\u043a\u043d\u043e \u043d\u0430 \u0432\u0435\u0441\u044c \u044d\u043a\u0440\u0430\u043d.<\/p>\n<pre><code class=\"python\">    def maximize_window(self):         \"\"\"         Maximize the window to fill the entire parent widget          Stores the previous size and position for restoration when un-maximizing         \"\"\"          # If the window is already maximized, do nothing         if self.is_maximized:             return          # Store the current size and position for restoration         x = self.window_frame.winfo_x()         y = self.window_frame.winfo_y()          width = self.window_frame.winfo_width()         height = self.window_frame.winfo_height()          self.previous_size_and_position = (x, y, width, height)          # Get parent dimensions         parent_width = self.parent.winfo_width()         parent_height = self.parent.winfo_height()          # Maximize the window to fill the parent widget         self.window_frame.place(             x=-6, y=-6, width=parent_width + 12, height=parent_height + 13)         self.is_maximized = True          # Update all maximized child windows to fit new size         for child in self.childs:             if child.is_maximized:                 content_width = self.window_content.winfo_width()                 content_height = self.window_content.winfo_height()                 child.window_frame.place(                     x=-6, y=-6, width=content_width + 12, height=content_height + 13)      def minimize_window(self):         \"\"\" Restore the window to its previous size and position if maximized \"\"\"          # If the window is not minimized, do nothing         if self.is_maximized:             # Restore to previous size and position             x, y, width, height = self.previous_size_and_position             self.window_frame.place(x=x, y=y, width=width, height=height)             self.is_maximized = False              # Update all child windows that are maximized             for child in self.childs:                 if child.is_maximized:                     child.maximize_window() <\/code><\/pre>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043f\u0443\u043d\u043a\u0442\u043e\u043c \u0443 \u043d\u0430\u0441 \u0438\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u043e\u043a\u043d\u0430:<\/p>\n<pre><code class=\"python\">    def start_drag(self, event):         \"\"\" Begin window dragging operation \"\"\"          # Bring the window to the front         self.lift(event)          # Store initial mouse position and window position         self.drag_start_x = event.x_root         self.drag_start_y = event.y_root         self.window_start_x = self.window_frame.winfo_x()         self.window_start_y = self.window_frame.winfo_y()          # Prevent conflict with resize operations         self.is_dragging = True      def stop_drag(self, event: tk.Event):         \"\"\" End window dragging operation \"\"\"         self.is_dragging = False         self.drag_start_x = None         self.drag_start_y = None      def drag(self, event: tk.Event):         \"\"\" Handle window movement during drag operation \"\"\"          # Prevent dragging if the window is not being dragged         if not hasattr(self, 'is_dragging') or not self.is_dragging or self.is_maximized:             return          # Calculate the displacement from the start position         deltax = event.x_root - self.drag_start_x         deltay = event.y_root - self.drag_start_y          # Update window position based on initial position plus displacement         new_x = self.window_start_x + deltax         new_y = self.window_start_y + deltay          self.window_frame.place(x=new_x, y=new_y) <\/code><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u043a\u043e\u0440\u044f\u0432\u0435\u043d\u044c\u043a\u043e (\u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e <code>if not hasattr(self, 'is_dragging') or not self.is_dragging or self.is_maximized<\/code>), \u043d\u0443 \u0434\u0430 \u043b\u0430\u0434\u043d\u043e. \u041e\u0441\u043e\u0431\u043e \u0445\u043e\u0447\u0443 \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e <code>start_drag<\/code> \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0435\u0449\u0435 \u0438 \u0437\u0430 \u0444\u043e\u043a\u0443\u0441 \u043d\u0430 \u043e\u043a\u043d\u0435: \u043a\u043e\u0433\u0434\u0430 \u0432\u044b \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u0442\u0435 \u043d\u0430 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a, \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 drag \u0438 <code>self.lift<\/code> \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u0442 \u043e\u043a\u043d\u043e \u0432\u0432\u0435\u0440\u0445.  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438\u0448\u0435\u043b \u0447\u0435\u0440\u0435\u0434 \u0440\u0435\u0441\u0430\u0439\u0437\u0438\u043d\u0433\u0430:<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">    def start_resize(self, event):         \"\"\" Begin window resizing operation \"\"\"         self.lift(event)          # Prevent conflict with drag operations         if hasattr(self, 'is_dragging'):             self.is_dragging = False          corner = event.widget          # Store initial window geometry         self.resize_start_x = event.x_root         self.resize_start_y = event.y_root         self.window_start_width = self.window_frame.winfo_width()         self.window_start_height = self.window_frame.winfo_height()         self.window_start_x = self.window_frame.winfo_x()         self.window_start_y = self.window_frame.winfo_y()          # Determine which corner was clicked and set the cursor accordingly         if corner == self.corner_A:             cursor = \"top_left_corner\"             handle_x = self.window_frame.winfo_width() - 1             handle_y = self.window_frame.winfo_height() - 1         elif corner == self.corner_B:             cursor = \"top_right_corner\"             handle_x = 0             handle_y = self.window_frame.winfo_height() - 1         elif corner == self.corner_C:             cursor = \"bottom_right_corner\"             handle_x = 0             handle_y = 0         elif corner == self.corner_D:             cursor = \"bottom_left_corner\"             handle_x = self.window_frame.winfo_width() - 1             handle_y = 0         else:             cursor = \"bottom_left_corner\"             handle_x = self.window_frame.winfo_width() - 1             handle_y = 0          # Store the handle position relative to the window and the root window         handle_pos_x_root = handle_x + self.window_frame.winfo_rootx()         handle_pos_y_root = handle_y + self.window_frame.winfo_rooty()          # Store the handle position relative to the window         self.handle_pos_x = handle_x         self.handle_pos_y = handle_y          # Store the handle position relative to the root window         self.handle_pos_x_root = handle_pos_x_root         self.handle_pos_y_root = handle_pos_y_root          # Set the cursor and start resizing         self.cursor = cursor         self.window_frame.config(cursor=cursor)         self.is_resizing = True          # Store the initial mouse position for resizing         self.resize_offset_x = event.x         self.resize_offset_y = event.y      def stop_resize(self, event: tk.Event):         \"\"\"         End window resizing operation          Args:             event: The mouse event that triggered the end of resizing         \"\"\"         if hasattr(self, 'is_resizing') and self.is_resizing:             # Only stop resizing if we are already resizing (to prevent stopping a resize that never started)             # This can happen if you release the mouse button while not resizing (which can happen accidentally while dragging fast)             # If we don't prevent that we will end up with an inconsistent state that will make the window flicker and behave erratically while dragging or resizing             self.window_frame.config(cursor=\"\")             self.is_resizing = False      def resize(self, event: tk.Event):         \"\"\"Handle window resizing during resize operation.          Args:             event: The mouse motion event          Updates window dimensions while maintaining minimum size constraints.         \"\"\"         self.lift(event)         if not self.is_resizing:             return          # Calculate the displacement from the start position         deltax = event.x_root - self.resize_start_x         deltay = event.y_root - self.resize_start_y          # Calculate new dimensions based on which corner is being dragged         if self.handle_pos_x == 0:             # Left corners             new_width = max(200, self.window_start_width + deltax)             new_x = self.window_start_x         else:             # Right corners             new_width = max(200, self.window_start_width - deltax)             new_x = self.window_start_x + deltax          if self.handle_pos_y == 0:             # Bottom corners             new_height = max(150, self.window_start_height + deltay)             new_y = self.window_start_y         else:             # Top corners             new_height = max(150, self.window_start_height - deltay)             new_y = self.window_start_y + deltay          # Update window geometry in a single operation         self.window_frame.place(             x=new_x, y=new_y, width=new_width, height=new_height) <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u042d\u0442\u0430 \u0441\u0430\u043c\u0430\u044f \u0441\u043b\u043e\u0436\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0438 \u043a\u043b\u0430\u0441\u0441\u0430. \u0415\u0441\u043b\u0438 \u043a\u043e\u0440\u043e\u0442\u043a\u043e, \u0442\u043e \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u0430\u043a:<\/p>\n<ol>\n<li>\n<p>\u041f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043d\u0430 \u0443\u0433\u043e\u043b, \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0443\u0433\u043e\u043b (A, B, C, D) <\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u0442\u0435\u043c \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u043c \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u044b<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0443\u0433\u043b\u0430 \u0437\u0430\u0434\u0430\u0435\u043c &#171;\u044f\u043a\u043e\u0440\u043d\u0443\u044e \u0442\u043e\u0447\u043a\u0443&#187;. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u043b\u0435\u0432\u043e\u0433\u043e \u0432\u0435\u0440\u0445\u043d\u0435\u0433\u043e \u0443\u0433\u043b\u0430 (A) \u044d\u0442\u043e <code>handle_x = \u0448\u0438\u0440\u0438\u043d\u0430 \u043e\u043a\u043d\u0430 - 1 <\/code><\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u0442\u0435\u043c \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0434\u0435\u043b\u044c\u0442\u0443 \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043d\u043e\u0432\u0443\u044e \u0448\u0438\u0440\u0438\u043d\u0443 \u0438 \u043f\u043e\u0437\u0438\u0446\u0438\u044e.<\/p>\n<p>\u0423\u0441\u043b\u043e\u0432\u043d\u043e \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432 \u0432\u0438\u0434\u0435 \u0442\u0430\u043a\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\"><strong>\u0423\u0433\u043e\u043b<\/strong><\/p>\n<\/th>\n<th>\n<p align=\"left\"><strong>handle_x<\/strong><\/p>\n<\/th>\n<th>\n<p align=\"left\"><strong>handle_y<\/strong><\/p>\n<\/th>\n<th>\n<p align=\"left\"><strong>\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432<\/strong><\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041b\u0435\u0432\u044b\u0439 \u0432\u0435\u0440\u0445<\/p>\n<\/td>\n<td>\n<p align=\"left\">width-1<\/p>\n<\/td>\n<td>\n<p align=\"left\">height-1<\/p>\n<\/td>\n<td>\n<p align=\"left\">width+, height+, x+, y+<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041f\u0440\u0430\u0432\u044b\u0439 \u0432\u0435\u0440\u0445<\/p>\n<\/td>\n<td>\n<p align=\"left\">0<\/p>\n<\/td>\n<td>\n<p align=\"left\">height-1<\/p>\n<\/td>\n<td>\n<p align=\"left\">width-, height+, y+<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041f\u0440\u0430\u0432\u044b\u0439 \u043d\u0438\u0437<\/p>\n<\/td>\n<td>\n<p align=\"left\">0<\/p>\n<\/td>\n<td>\n<p align=\"left\">0<\/p>\n<\/td>\n<td>\n<p align=\"left\">width-, height-<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041b\u0435\u0432\u044b\u0439 \u043d\u0438\u0437<\/p>\n<\/td>\n<td>\n<p align=\"left\">width-1<\/p>\n<\/td>\n<td>\n<p align=\"left\">0<\/p>\n<\/td>\n<td>\n<p align=\"left\">width+, height-, x+<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/li>\n<\/ol>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0438\u0434\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 <code>track_window_size_and_position,<\/code>\u00a0\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0434\u0432\u0435 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438:<\/p>\n<ul>\n<li>\n<p>\u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0438 \u0440\u0430\u0437\u043c\u0435\u0440 \u043e\u043a\u043d\u0430, \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u043e\u043d\u043e \u043d\u0435 \u043c\u0430\u043a\u0441\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u043e\u043a\u043d\u0430 \u0438\u0437 \u043c\u0430\u043a\u0441\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e\/\u043c\u0438\u043d\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u044b<\/p>\n<\/li>\n<li>\n<p>\u0421\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043e\u043a\u043e\u043d (\u0435\u0441\u043b\u0438 \u043e\u043a\u043d\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u043e\u043a\u043d\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u044b\u043b\u0438 \u043c\u0430\u043a\u0441\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u044b, \u043e\u043d\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e\u0434\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u043f\u043e\u0434 \u043d\u043e\u0432\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438)<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"python\">    def track_window_size_and_position(self, event: tk.Event):         \"\"\"Store window geometry for restore operations.          Args:             event: The Configure event containing new geometry          Used to remember window size\/position before maximize\/minimize.         \"\"\"         # Track changes in the window's size and position to remember its size before it was maximized or shrinked         # This is used to restore the window to its previous size when it is un-maximized or un-shrinked         x = event.x         y = event.y          width = event.width         height = event.height          if not hasattr(self, 'is_maximized') or not (self.is_maximized):             self.previous_size_and_position = (x, y, width, height)          # Update maximized child windows when parent size changes         if hasattr(self, 'childs'):             for child in self.childs:                 if hasattr(child, 'is_maximized') and child.is_maximized:                     # Get parent content area dimensions                     content_width = self.window_content.winfo_width()                     content_height = self.window_content.winfo_height()                     # Update child window size to match new parent content area                     child.window_frame.place(x=-6, y=-6,                                              width=content_width + 12,                                              height=content_height + 13)<\/code><\/pre>\n<p>\u041d\u0443 \u0438 \u043e\u0441\u0442\u0430\u0432\u0448\u0430\u044f\u0441\u044f \u0447\u0430\u0441\u0442\u044c:<\/p>\n<pre><code class=\"python\">    def lift(self, event: tk.Event):         \"\"\"         Raise window above other windows in z-order.          Args:             - event: The event that triggered the raise operation         \"\"\"          self.window_frame.lift()      def create_child(self, title, content, size, flags):         \"\"\"Create a new window as a child of this window's content area.          Returns:             Window: The newly created child window         \"\"\"         child_window = Window(self.window_content, title, content,                               size, flags)  # Create a new Window instance as a child         # Add the child window to the list of windows         self.childs.append(child_window)         return child_window      def set_content(self, content):         \"\"\"         Set the content widget inside the window and ensure it adapts to the window size.          Arguments:             - content: The content widget to be placed inside the window (Must be a class, not an instance)         \"\"\"          # We need to destroy the existing content widget before adding a new one         # content must be a class, not an instance         self.content = content(self.window_content)         # then we can place the widget inside the window         self.content.pack(fill=\"both\", expand=True) <\/code><\/pre>\n<p>\u041c\u0435\u0442\u043e\u0434 <code>lift<\/code> &#171;\u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u0442&#187; \u043e\u043a\u043d\u043e \u0432\u0432\u0435\u0440\u0445<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/938\/941\/d3a\/938941d3a0c4550413925dd738ad5f12.png\" width=\"1438\" height=\"765\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/938\/941\/d3a\/938941d3a0c4550413925dd738ad5f12.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/938\/941\/d3a\/938941d3a0c4550413925dd738ad5f12.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/784\/ac4\/464\/784ac4464fe1bab5547f12d44c8bdd94.png\" width=\"1294\" height=\"751\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/784\/ac4\/464\/784ac4464fe1bab5547f12d44c8bdd94.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/784\/ac4\/464\/784ac4464fe1bab5547f12d44c8bdd94.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<div class=\"floating-image\">\n<p>\u041c\u0435\u0442\u043e\u0434 <code>create_child<\/code> \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u043e\u043a\u043d\u0430<\/p>\n<\/div>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9c3\/0a5\/fdf\/9c30a5fdf960aacb2baf0c526b5b85b2.png\" width=\"831\" height=\"813\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/9c3\/0a5\/fdf\/9c30a5fdf960aacb2baf0c526b5b85b2.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9c3\/0a5\/fdf\/9c30a5fdf960aacb2baf0c526b5b85b2.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041d\u0443 \u0438 \u043d\u0430\u043a\u043e\u043d\u0435\u0446, \u043c\u0435\u0442\u043e\u0434 <code>set_content<\/code> \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043e\u043a\u043d\u0430 (\u0434\u043e\u0447\u0435\u0440\u043d\u0435\u0435 \u043e\u0442 <code>tk.Frame)<\/code><\/p>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u043a\u043b\u0430\u0441\u0441 <code>Window<\/code> \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f. \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043d\u0430\u0448\u0435\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0430!<\/p>\n<h2>\u041a\u043b\u0430\u0441\u0441 WindowManager<\/h2>\n<p>\u042d\u0442\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043a\u043b\u0430\u0441\u0441 \u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0433\u043e \u0432 \u043d\u0435\u043c \u043d\u0435\u0442:<\/p>\n<pre><code class=\"python\">import tkinter as tk from .window import Window   class WindowManager:     \"\"\"Main window manager class that handles the desktop environment.      Provides the main application window and manages creation of child windows.     \"\"\"      def __init__(self, root):         \"\"\"Initialize the window manager.          Args:             root: The root Tkinter window         \"\"\"         self.root = root         self.root.title(\"Window Manager\")         self.root.attributes(\"-fullscreen\", True)         self.windows = []          self.root.config(cursor=\"@.\/assets\/cursor_a.cur\")          self.main_frame = tk.Frame(self.root, bg=\"#29A97E\")         self.main_frame.pack(fill=\"both\", expand=True)      def create_window(self, title=\"Window\", content=None, size=(50, 50, 210, 200), flags=0):         \"\"\"         Create a new top-level window          Args:             title: The title of the window             content: The content widget to be placed inside the window             size: A tuple of (x, y, width, height) for the window's initial position and size             flags: Bitmap flags for window options          Returns:             Window: The newly created window         \"\"\"          window = Window(self.main_frame, title, content, size, flags)         self.windows.append(window)          return window      def create_child(self, parent: Window, title=\"Window\", content=None, size=(50, 50, 210, 200), flags=0):         \"\"\"         Create a new child window inside the given parent window          Args:             parent: The parent Window instance          Returns:             Window: The newly created child window         \"\"\"          child = parent.create_child(             title, content=content, size=size, flags=flags)         self.windows.append(child)          return child <\/code><\/pre>\n<p>\u041f\u0435\u0440\u0432\u044b\u043c \u0434\u0435\u043b\u043e\u043c \u043c\u044b \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u043d\u0430\u0448\u0435 \u043e\u043a\u043d\u043e \u043d\u0430 \u0432\u0435\u0441\u044c \u044d\u043a\u0440\u0430\u043d, \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u043e\u043b\u0434\u0441\u043a\u0443\u043b\u044c\u043d\u044b\u0439 \u043a\u0443\u0440\u0441\u043e\u0440 \u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043e\u043a\u043d\u043e \u0444\u0440\u0435\u0439\u043c\u043e\u043c \u0437\u0435\u043b\u0435\u043d\u043e\u0433\u043e \u0446\u0432\u0435\u0442\u0430.<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u043d\u0430 Linux, \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043a\u0443\u0440\u0441\u043e\u0440\u0430 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0432\u044b\u043f\u0438\u043b\u0438\u0442\u044c &#8212; \u0444\u0430\u0439\u043b\u044b .cur \u0442\u0430\u043c \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442\u0441\u044f<\/p>\n<\/div>\n<\/details>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0438\u0434\u0443\u0442 \u043c\u0435\u0442\u043e\u0434\u044b <code>create_window<\/code> \u0438 <code>create_child<\/code>. \u041e\u043d\u0438 \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0442 \u0437\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043e\u043a\u043d\u0430 \u0438 \u0434\u043e\u0447\u0435\u0440\u043d\u0435\u0433\u043e \u043e\u043a\u043d\u0430 \u0434\u043b\u044f \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e.<\/p>\n<p>\u0412\u0441\u0451! \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432 <code>main.py<\/code> \u0434\u043e\u0431\u0430\u0432\u0438\u043c:<\/p>\n<pre><code class=\"python\">import tkinter as tk from sources.window.manager import WindowManager   def main():     root = tk.Tk()      app = WindowManager(root)      app.create_window(title=\"Notepad\", content=None,                       size=(800, 50, 200, 300))      root.mainloop()   if __name__ == \"__main__\":     main() <\/code><\/pre>\n<p>\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0432 \u044d\u0442\u043e, \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 (\u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043a\u0443\u0440\u0441\u043e\u0440\u0430 \u0441\u044a\u0435\u0445\u0430\u043b\u043e, \u043d\u043e \u044d\u0442\u043e \u0431\u0430\u0433 \u0437\u0430\u043f\u0438\u0441\u0438):<\/p>\n<div class=\"embed_link\">\n<div class=\"embed__thumb\" style=\"background-image: url(&quot;undefined&quot;);\"><\/div>\n<div class=\"embed__caption\">\n<div class=\"embed__caption-title\"><span>Window Manager 2025-04-08 19-29-32.mp4<\/span><\/div>\n<p><a href=\"https:\/\/drive.google.com\/file\/d\/1Jg8KzLUFjBVtMqQuYETwd96OQlYykDQT\/view?usp=sharing&amp;usp=embed_facebook\" target=\"_blank\" rel=\"noopener noreferrer nofollow\" class=\"embed__caption-host\">drive.google.com<\/a><\/div>\n<\/div>\n<h2>\u0414\u0435\u043c\u043a\u0438<\/h2>\n<p>\u0427\u0442\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0430\u0448 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u043f\u043e\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0435\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0442\u0440\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043a\u0438. \u0423 \u043d\u0438\u0445 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 (\u043a\u0440\u043e\u043c\u0435, \u0440\u0430\u0437\u0432\u0435 \u0442\u043e\u043b\u044c\u043a\u043e, \u043a\u0430\u043b\u044c\u043a\u0443\u043b\u044f\u0442\u043e\u0440\u0430) \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u043d\u043e \u043d\u0430 \u043d\u0438\u0445 \u0445\u043e\u0440\u043e\u0448\u043e \u0432\u0438\u0434\u043d\u044b \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043d\u0430\u0448\u0435\u0439 \u0438\u0433\u0440\u0443\u0448\u043a\u0438. \u0418\u0442\u0430\u043a:<\/p>\n<h4>\u041a\u0430\u043b\u044c\u043a\u0443\u043b\u044f\u0442\u043e\u0440 (\/sources\/program\/calc.py)<\/h4>\n<pre><code class=\"python\">import tkinter as tk   class Calculator(tk.Frame):     def __init__(self, master=None):         super().__init__(master)         self.master = master         self.pack()         self.create_widgets()         self.expression = \"\"      def create_widgets(self):         self.display = tk.Entry(self, font=(             'Arial', 18), borderwidth=2, relief=\"sunken\")         self.display.grid(row=0, column=0, columnspan=4, sticky=\"nsew\")          buttons = [             '7', '8', '9', '\/',             '4', '5', '6', '*',             '1', '2', '3', '-',             '0', '.', '=', '+'         ]          row_val = 1         col_val = 0          for button in buttons:             tk.Button(self, text=button, font=('Arial', 18), command=lambda b=button: self.button_click(                 b)).grid(row=row_val, column=col_val, sticky=\"nsew\")             col_val += 1             if col_val &gt; 3:                 col_val = 0                 row_val += 1          for i in range(1, 5):             self.grid_rowconfigure(i, weight=1)         for j in range(4):             self.grid_columnconfigure(j, weight=1)      def button_click(self, char):         if char == '=':             try:                 result = str(eval(self.expression))                 self.display.delete(0, tk.END)                 self.display.insert(tk.END, result)                 self.expression = result             except Exception as e:                 self.display.delete(0, tk.END)                 self.display.insert(tk.END, \"\u041e\u0448\u0438\u0431\u043a\u0430\")                 self.expression = \"\"         else:             self.expression += str(char)             self.display.insert(tk.END, char) <\/code><\/pre>\n<h4>\u0411\u043b\u043e\u043a\u043d\u043e\u0442 (\/sources\/program\/notepad.py)<\/h4>\n<pre><code class=\"python\">import tkinter as tk from tkinter import scrolledtext  class Notepad(tk.Frame):     def __init__(self, parent=None):         super().__init__(parent)         self.text_area = scrolledtext.ScrolledText(self, wrap=tk.WORD, width=40, height=10, font=(\"Fixedsys\", 12))         self.text_area.pack(fill=\"both\", expand=True) <\/code><\/pre>\n<h4>\u0422\u0435\u0440\u043c\u0438\u043d\u0430\u043b (\/sources\/program\/terminal.py)<\/h4>\n<p>\u0412 Windows 3.1, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u043d\u0435 \u0431\u044b\u043b\u043e \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0430, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u043b \u043f\u043e\u0432\u0435\u0440\u0445 dos, \u043d\u043e \u044f \u0440\u0435\u0448\u0438\u043b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0433\u043e \u0434\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0435\u0439 \u044d\u0444\u0444\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u0438))<\/p>\n<pre><code class=\"python\">import tkinter as tk from tkinter import scrolledtext  class Terminal(tk.Frame):      def __init__(self, parent=None):         super().__init__(parent)         self.text_area = scrolledtext.ScrolledText(             self, wrap=tk.WORD,             width=80,             height=25,             font=(\"Fixedsys\", 10),             bg=\"black\",             fg=\"white\",             insertbackground=\"white\",             blockcursor=True         )         self.text_area.pack(fill=\"both\", expand=True)         self.text_area.bind(\"&lt;Return&gt;\", self.execute_command)         self.text_area.config(insertofftime=500, insertontime=500)  # Blinking cursor         self.text_area.focus_set()  # Set focus to the text area      def execute_command(self, event):         command = self.text_area.get(\"insert linestart\", \"insert lineend\")         self.text_area.insert(tk.END, f\"\\nExecuted: {exec(command)}\\n\") <\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c <code>main.py<\/code><\/p>\n<pre><code class=\"python\">import tkinter as tk from sources.window.manager import WindowManager from sources.window.window import WindowFlags from sources.program.notepad import Notepad from sources.program.terminal import Terminal from sources.program.calc import Calculator   def main():     root = tk.Tk()      app = WindowManager(root)       app.create_window(title=\"Notepad\", content=Notepad,                       size=(800, 50, 200, 300), flags=WindowFlags.WN_DRAGABLE)     app.create_child(app.windows[0], title=\"Notepad\", content=Notepad,)     app.create_window(title=\"Terminal\", content=Terminal,                       size=(275, 50, 500, 300), flags=WindowFlags.WN_CONTROLS)     app.create_window(title=\"Calculator\", content=Calculator,                       size=(50, 200, 500, 300), flags=WindowFlags.WN_RESIZABLE)      root.mainloop()   if __name__ == \"__main__\":     main() <\/code><\/pre>\n<p>\u0413\u043e\u0442\u043e\u0432\u043e!<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3bd\/cc4\/5c3\/3bdcc45c37863f0df677e90c2483f0f4.png\" alt=\"\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\" title=\"\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\" width=\"1920\" height=\"1080\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/3bd\/cc4\/5c3\/3bdcc45c37863f0df677e90c2483f0f4.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3bd\/cc4\/5c3\/3bdcc45c37863f0df677e90c2483f0f4.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442<\/figcaption><\/div>\n<\/figure>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u0432\u0441\u0435. \u041d\u0430\u0434\u0435\u044e\u0441\u044c \u0438\u0434\u0435\u044f \u0432\u0430\u043c \u043f\u043e\u043d\u0440\u0430\u0432\u0438\u043b\u0430\u0441\u044c, \u0430 \u043e\u0431\u0438\u043b\u0438\u0435 \u043a\u043e\u0434\u0430 \u043d\u0435 \u0443\u0442\u043e\u043c\u0438\u043b\u043e) \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, \u044d\u0442\u0430 \u0438\u0433\u0440\u0443\u0448\u043a\u0430 \u043d\u0435 \u043d\u0435\u0441\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u043e\u0439 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043f\u043e\u043b\u044c\u0437\u044b (\u043a\u0440\u043e\u043c\u0435 \u043e\u0431\u0443\u0447\u0430\u044e\u0449\u0435\u0439, \u043a\u043e\u043d\u0435\u0447\u043d\u043e), \u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u044d\u0442\u0438\u043c \u043a\u043e\u0434\u043e\u043c \u043c\u043d\u0435 \u043f\u0440\u0438\u043d\u0435\u0441\u043b\u0430 \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0443\u0434\u043e\u0432\u043e\u043b\u044c\u0441\u0442\u0432\u0438\u0435, \u0432\u0435\u0434\u044c \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u0440\u0438\u044f\u0442\u043d\u043e \u0441\u0430\u043c\u043e\u043c\u0443 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e, \u0447\u0435\u043c \u0440\u0430\u043d\u044c\u0448\u0435 \u0441\u0430\u043c \u0432\u043e\u0441\u0445\u0438\u0449\u0430\u043b\u0441\u044f \ud83d\ude42<\/p>\n<p>\u0412\u0435\u0441\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0447\u0430\u0442\u044c \u043d\u0430 \u043c\u043e\u0435\u043c GitHub: <a href=\"https:\/\/github.com\/GVCoder09\/TkWindowsManager\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/GVCoder09\/TkWindowsManager<\/a><\/p>\n<p>\u0421\u043f\u0430\u0441\u0438\u0431\u043e, \u0447\u0442\u043e \u0443\u0434\u0435\u043b\u0438\u043b\u0438 \u0432\u0440\u0435\u043c\u044f \u043d\u0430 \u043c\u043e\u044e \u0441\u0442\u0430\u0442\u044c\u044e (\u0438\u043b\u0438 \u0445\u043e\u0442\u044f \u0431\u044b \u043d\u0430 \u0441\u043a\u0440\u043e\u043b\u043b\u0438\u043d\u0433 \u0434\u043e \u0435\u0435 \u043a\u043e\u043d\u0446\u0430)!<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><\/p>\n<div class=\"tm-article-poll-container\"><!--[--><\/p>\n<div class=\"tm-article-poll tm-article-poll_variant-bordered\">\n<div class=\"tm-notice tm-notice_positive tm-article-poll__notice\"><!----><\/p>\n<div class=\"tm-notice__inner\"><!----><\/p>\n<div class=\"tm-notice__content\" data-test-id=\"notice-content\"><!--[--><span>\u0422\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u043c\u043e\u0433\u0443\u0442 \u0443\u0447\u0430\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0432 \u043e\u043f\u0440\u043e\u0441\u0435. <a rel=\"nofollow\" href=\"\/kek\/v1\/auth\/habrahabr\/?back=\/ru\/articles\/898484\/&#038;hl=ru\">\u0412\u043e\u0439\u0434\u0438\u0442\u0435<\/a>, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430.<\/span><!--]--><\/div>\n<\/div>\n<\/div>\n<p><!--[--><\/p>\n<div class=\"tm-article-poll__header\">\u041d\u0443 \u0438 (\u043d\u0435)\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043e\u043f\u0440\u043e\u0441\u0438\u043a) \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0438\u0437 \u043a\u0430\u043a\u043e\u0439 Windows \u0443 \u0432\u0430\u0441 \u0441\u0430\u043c\u044b\u0439 \u043b\u044e\u0431\u0438\u043c\u044b\u0439?<\/div>\n<div class=\"tm-article-poll__answers\"><!--[--><\/p>\n<div class=\"tm-article-poll__answer\">\n<div class=\"tm-article-poll__answer-data\"><span class=\"tm-article-poll__answer-percent\">0% <\/span><span class=\"tm-article-poll__answer-label\">Windows 1.0<\/span><span class=\"tm-article-poll__answer-votes\">0<\/span><\/div>\n<div class=\"tm-article-poll__answer-bar\">\n<div class=\"tm-article-poll__answer-progress\" style=\"width: 0%\"><\/div>\n<\/div>\n<\/div>\n<div class=\"tm-article-poll__answer\">\n<div class=\"tm-article-poll__answer-data\"><span class=\"tm-article-poll__answer-percent\">3.08% <\/span><span class=\"tm-article-poll__answer-label\">Windows 2.0<\/span><span class=\"tm-article-poll__answer-votes\">2<\/span><\/div>\n<div class=\"tm-article-poll__answer-bar\">\n<div class=\"tm-article-poll__answer-progress\" style=\"width: 3.08%\"><\/div>\n<\/div>\n<\/div>\n<div class=\"tm-article-poll__answer\">\n<div class=\"tm-article-poll__answer-data\"><span class=\"tm-article-poll__answer-percent\">6.15% <\/span><span class=\"tm-article-poll__answer-label\">Windows 3.x (NT 3.x)<\/span><span class=\"tm-article-poll__answer-votes\">4<\/span><\/div>\n<div class=\"tm-article-poll__answer-bar\">\n<div class=\"tm-article-poll__answer-progress\" style=\"width: 6.15%\"><\/div>\n<\/div>\n<\/div>\n<div class=\"tm-article-poll__answer\">\n<div class=\"tm-article-poll__answer-data\"><span class=\"tm-article-poll__answer-percent\">1.54% <\/span><span class=\"tm-article-poll__answer-label\">Windows 95<\/span><span class=\"tm-article-poll__answer-votes\">1<\/span><\/div>\n<div class=\"tm-article-poll__answer-bar\">\n<div class=\"tm-article-poll__answer-progress\" style=\"width: 1.54%\"><\/div>\n<\/div>\n<\/div>\n<div class=\"tm-article-poll__answer\">\n<div class=\"tm-article-poll__answer-data\"><span class=\"tm-article-poll__answer-percent\">9.23% <\/span><span class=\"tm-article-poll__answer-label\">Windows 98<\/span><span class=\"tm-article-poll__answer-votes\">6<\/span><\/div>\n<div class=\"tm-article-poll__answer-bar\">\n<div class=\"tm-article-poll__answer-progress\" style=\"width: 9.23%\"><\/div>\n<\/div>\n<\/div>\n<div class=\"tm-article-poll__answer\">\n<div class=\"tm-article-poll__answer-data\"><span class=\"tm-article-poll__answer-percent\">10.77% <\/span><span class=\"tm-article-poll__answer-label\">Windows 2000<\/span><span class=\"tm-article-poll__answer-votes\">7<\/span><\/div>\n<div class=\"tm-article-poll__answer-bar\">\n<div class=\"tm-article-poll__answer-progress\" style=\"width: 10.77%\"><\/div>\n<\/div>\n<\/div>\n<div class=\"tm-article-poll__answer\">\n<div class=\"tm-article-poll__answer-data\"><span class=\"tm-article-poll__answer-percent\">20% <\/span><span class=\"tm-article-poll__answer-label\">Windows XP<\/span><span class=\"tm-article-poll__answer-votes\">13<\/span><\/div>\n<div class=\"tm-article-poll__answer-bar\">\n<div class=\"tm-article-poll__answer-progress\" style=\"width: 20%\"><\/div>\n<\/div>\n<\/div>\n<div class=\"tm-article-poll__answer\">\n<div class=\"tm-article-poll__answer-data\"><span class=\"tm-article-poll__answer-percent\">0% <\/span><span class=\"tm-article-poll__answer-label\">Windows Vista<\/span><span class=\"tm-article-poll__answer-votes\">0<\/span><\/div>\n<div class=\"tm-article-poll__answer-bar\">\n<div class=\"tm-article-poll__answer-progress\" style=\"width: 0%\"><\/div>\n<\/div>\n<\/div>\n<div class=\"tm-article-poll__answer\">\n<div class=\"tm-article-poll__answer-data\"><span class=\"tm-article-poll__answer-percent\">4.62% <\/span><span class=\"tm-article-poll__answer-label\">Windows XP (\u0441\u043e\u0440\u0440\u0438, \u043b\u0438\u0448\u043d\u0435\u0435, \u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0443\u0436\u0435 \u043d\u0435 \u043c\u043e\u0433\u0443)<\/span><span class=\"tm-article-poll__answer-votes\">3<\/span><\/div>\n<div class=\"tm-article-poll__answer-bar\">\n<div class=\"tm-article-poll__answer-progress\" style=\"width: 4.62%\"><\/div>\n<\/div>\n<\/div>\n<div class=\"tm-article-poll__answer\">\n<div class=\"tm-article-poll__answer-data\"><span class=\"tm-article-poll__answer-percent tm-article-poll__answer-percent_winning\">21.54% <\/span><span class=\"tm-article-poll__answer-label\">Windows 7<\/span><span class=\"tm-article-poll__answer-votes\">14<\/span><\/div>\n<div class=\"tm-article-poll__answer-bar\">\n<div class=\"tm-article-poll__answer-progress tm-article-poll__answer-progress_winning\" style=\"width: 21.54%\"><\/div>\n<\/div>\n<\/div>\n<div class=\"tm-article-poll__answer\">\n<div class=\"tm-article-poll__answer-data\"><span class=\"tm-article-poll__answer-percent\">0% <\/span><span class=\"tm-article-poll__answer-label\">Windows 8<\/span><span class=\"tm-article-poll__answer-votes\">0<\/span><\/div>\n<div class=\"tm-article-poll__answer-bar\">\n<div class=\"tm-article-poll__answer-progress\" style=\"width: 0%\"><\/div>\n<\/div>\n<\/div>\n<div class=\"tm-article-poll__answer\">\n<div class=\"tm-article-poll__answer-data\"><span class=\"tm-article-poll__answer-percent\">12.31% <\/span><span class=\"tm-article-poll__answer-label\">Windows 10<\/span><span class=\"tm-article-poll__answer-votes\">8<\/span><\/div>\n<div class=\"tm-article-poll__answer-bar\">\n<div class=\"tm-article-poll__answer-progress\" style=\"width: 12.31%\"><\/div>\n<\/div>\n<\/div>\n<div class=\"tm-article-poll__answer\">\n<div class=\"tm-article-poll__answer-data\"><span class=\"tm-article-poll__answer-percent\">6.15% <\/span><span class=\"tm-article-poll__answer-label\">Windows 11<\/span><span class=\"tm-article-poll__answer-votes\">4<\/span><\/div>\n<div class=\"tm-article-poll__answer-bar\">\n<div class=\"tm-article-poll__answer-progress\" style=\"width: 6.15%\"><\/div>\n<\/div>\n<\/div>\n<div class=\"tm-article-poll__answer\">\n<div class=\"tm-article-poll__answer-data\"><span class=\"tm-article-poll__answer-percent\">4.62% <\/span><span class=\"tm-article-poll__answer-label\">\u041d\u0435-\u043d\u0430-\u0432\u0438-\u0436\u0443!<\/span><span class=\"tm-article-poll__answer-votes\">3<\/span><\/div>\n<div class=\"tm-article-poll__answer-bar\">\n<div class=\"tm-article-poll__answer-progress\" style=\"width: 4.62%\"><\/div>\n<\/div>\n<\/div>\n<p><!--]--><\/div>\n<div class=\"tm-article-poll__stats\"> \u041f\u0440\u043e\u0433\u043e\u043b\u043e\u0441\u043e\u0432\u0430\u043b\u0438 65 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439.   \u0412\u043e\u0437\u0434\u0435\u0440\u0436\u0430\u043b\u0438\u0441\u044c 7 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439. <\/div>\n<p><!--]--><\/div>\n<p><!--]--><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/898484\/\"> https:\/\/habr.com\/ru\/articles\/898484\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><\/figure>\n<p>\u0417\u043d\u0430\u043a\u043e\u043c\u043e, \u043f\u0440\u0430\u0432\u0434\u0430? \u0414\u0430, \u0434\u0430 &#8212; \u044d\u0442\u043e &#171;\u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u0441\u0442\u043e\u043b&#187; Windows 3.1, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u044b\u0448\u043b\u0430 \u0432 1992 \u0433\u043e\u0434\u0443. \u0418 \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0432\u044b \u043d\u0435 \u0438\u0437 \u0442\u043e\u0433\u043e \u043f\u043e\u043a\u043e\u043b\u0435\u043d\u0438\u044f, \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u0441\u0432\u0435\u043b\u043e \u043e\u043b\u0434\u0441\u043a\u0443\u043b\u044b, \u0432\u044b, \u044f \u0434\u0443\u043c\u0430\u044e, \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u0445\u043e\u0442\u044c \u0440\u0430\u0437 \u0432 \u0436\u0438\u0437\u043d\u0438 \u0432\u0438\u0434\u0435\u043b\u0438 \u044d\u0442\u0443 \u041e\u0421 (\u0445\u043e\u0442\u044f \u0431\u044b \u043d\u0430 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0435) \u0438 \u043d\u0435 \u043e\u0441\u0442\u0430\u043b\u0438\u0441\u044c \u043a \u043d\u0435\u0439 \u0440\u0430\u0432\u043d\u043e\u0434\u0443\u0448\u043d\u044b.<\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u0435\u043d\u044c\u043a\u0438\u0439 <em>\u0438\u0433\u0440\u0443\u0448\u0435\u0447\u043d\u044b\u0439<\/em> \u043e\u043a\u043e\u043d\u043d\u044b\u0439 <em>\u043f\u0441\u0435\u0432\u0434\u043e<\/em>-\u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0432 \u0441\u0442\u0438\u043b\u0435 Windows 3.x. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c Python \u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 Tkinter. \u0412\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a:<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0427\u0435\u043c-\u0442\u043e \u0441\u043c\u0430\u0445\u0438\u0432\u0430\u0435\u0442<\/figcaption><\/div>\n<\/figure>\n<p>\u0426\u0435\u043b\u044c\u044e \u0441\u0442\u0430\u0442\u044c\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u043f\u0438\u0438 3.x, \u0430 \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u043d\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0433\u043b\u0430\u0432\u043d\u043e\u0439 \u0444\u0438\u0447\u0438 Windows, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438 \u0434\u0430\u043b\u0430 \u0435\u0439 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 &#8212; \u043e\u043a\u043e\u0448\u0435\u043a. \u0421\u0442\u0438\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u0434 3.x, \u0440\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f.<\/p>\n<p>\u041d\u0443 \u0447\u0442\u043e \u0436\u0435, \u043f\u043e\u0435\u0445\u0430\u043b\u0438!<\/p>\n<hr\/>\n<h2>\u041a\u0430\u043a \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u043e<\/h2>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code> \u251c\u2500\u2500\u2500main.py \u2502 \u251c\u2500\u2500\u2500assets \u2502 \u2514\u2500\u2500\u2500sources     \u251c\u2500\u2500\u2500program     \u2502       calc.py     \u2502       notepad.py     \u2502       terminal.py     \u2502     \u2514\u2500\u2500\u2500window             manager.py             window.py<\/code><\/pre>\n<p>\u0423 \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 \u0442\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430 (main.py), \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0432\u0441\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443, \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 <code>Window <\/code>(sources\/window.py), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0437\u0430 \u043e\u043a\u043d\u0430 \u043d\u0430\u0448\u0435\u0439 \u043f\u0441\u0435\u0432\u0434\u043e-windows, \u0438 <code>WindowManager<\/code> (sources\/manager.py), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044d\u0442\u0438\u043c\u0438 \u043e\u043a\u043d\u0430\u043c\u0438 \u0431\u0443\u0434\u0435\u0442 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c.<\/p>\n<p>\u0412 \u043f\u0440\u0438\u0434\u0430\u0447\u0443 \u0443 \u043d\u0430\u0441 \u0438\u0434\u0435\u0442 \u0435\u0449\u0435 3 \u0434\u0435\u043c\u043a\u0438, \u043d\u043e \u043e\u043d\u0438 \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b \u0438 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0441 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u043e\u043c \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u0441\u0432\u044f\u0437\u0430\u043d\u044b (\u0432 \u0441\u043c\u044b\u0441\u043b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439). \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0438 \u0441\u0432\u043e\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f &#8212; \u0433\u043b\u0430\u0432\u043d\u043e\u0435, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0438 \u0431\u044b\u043b\u0438 \u043d\u0430 tkinter, \u0430 \u0438\u0445 \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043bc\u044f \u043e\u0442<code> tk.Frame<\/code><\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0415\u0441\u043b\u0438 \u0438\u0434\u0435\u044f \u043f\u043e\u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f \u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u0438, \u0442\u043e \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u043e\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0438\u0445\u043d\u0443\u0442\u044c pygame \u0432 \u0444\u0440\u0435\u0439\u043c tkinter<\/p>\n<\/div>\n<\/details>\n<h3>\u041f\u0430\u0440\u0430 \u0441\u043b\u043e\u0432 \u043e \u0441\u0442\u0438\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438<\/h3>\n<figure class=\"full-width\">\n<div><figcaption>Windows 3.11 \u0432 DOSBox<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u044f \u0441\u0442\u0430\u0440\u0430\u043b\u0441\u044f \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b (\u0441\u043c. \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443). \u0412 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0442\u0430\u043a\u0436\u0435, \u043a\u0430\u043a \u0432 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u0435, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0438\u043d\u0438\u0439 \u0446\u0432\u0435\u0442 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430, \u0440\u0430\u043c\u043a\u0430 \u0432\u043e\u043a\u0440\u0443\u0433 \u043e\u043a\u043d\u0430 \u0441 \u0443\u0433\u043e\u043b\u043a\u0430\u043c\u0438 \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u043c\u0435\u0440\u0430, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0442\u0430\u043a\u0438\u0435 \u0436\u0435 \u043a\u043d\u043e\u043f\u043a\u0438 \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0435. \u041d\u043e \u0443 \u043d\u0430\u0441 \u043d\u0435\u0442 \u043f\u043e\u043b\u043d\u043e\u0433\u043e \u0441\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f \u043e\u043a\u043e\u043d (\u043a\u043d\u043e\u043f\u043a\u0430 \u0441\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u043a\u043d\u043e \u043a \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c\u0443 \u0440\u0430\u0437\u043c\u0435\u0440\u0443), \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 Program Manager, \u0433\u0440\u0443\u043f\u043f\u044b \u0438 \u043c\u043d\u043e\u0433\u043e \u0447\u0435\u0433\u043e \u0435\u0449\u0451. \u041d\u043e \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0432\u0441\u0435-\u0442\u0430\u043a\u0438 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442.<\/p>\n<p>\u0418\u0442\u0430\u043a, \u043d\u0430\u0447\u043d\u0435\u043c.<\/p>\n<h2>\u041a\u043b\u0430\u0441\u0441 Window<\/h2>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u0442\u044c \u043a \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 \u043e\u043a\u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441:<\/p>\n<pre><code class=\"python\">from enum import IntFlag   class WindowFlags(IntFlag):     \"\"\"     Bitmap flags for window options.      'WN' means 'Window Not', so 'WN_DRAGABLE' means 'Window Not Dragable',     'WN_RESIZABLE' means 'Window Not Resizable', and so on.      \"\"\"     WN_CONTROLS = 1     WN_DRAGABLE = 2     WN_RESIZABLE = 4<\/code><\/pre>\n<p>\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043d\u0435\u0433\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u0438 \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043d\u0430\u0448\u0435\u0433\u043e \u043e\u043a\u043d\u0430:<\/p>\n<ul>\n<li>\n<p>WN_CONTROLS &#8212; \u0432\u044b\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u043a\u043d\u043e\u043f\u043a\u0438 \u0441\u0432\u0435\u0440\u043d\u0443\u0442\u044c\/\u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c<\/p>\n<\/li>\n<li>\n<p>WN_DRAGABLE &#8212; \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435 \u043e\u043a\u043d\u0430 \u0437\u0430 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a (\u043d\u043e \u0437\u0430 \u0443\u0433\u043b\u044b \u043f\u043e\u043a\u0430 \u0435\u0449\u0435 \u043c\u043e\u0436\u043d\u043e, \u044d\u0442\u043e \u0431\u0430\u0433)))<\/p>\n<\/li>\n<li>\n<p>WN_RESIZABLE &#8212; \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u0432 \u043e\u043a\u043d\u0430<\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0432\u044b \u0443\u0436\u0435 \u0434\u043e\u0433\u0430\u0434\u0430\u043b\u0438\u0441\u044c, \u0447\u0442\u043e \u044d\u0442\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0437\u0430\u0434\u0430\u044e\u0442\u0441\u044f \u0431\u0438\u0442\u043e\u0432\u044b\u043c\u0438 \u0444\u043b\u0430\u0433\u0430\u043c\u0438. \u0422\u0430\u043a \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0443\u0434\u043e\u0431\u043d\u0435\u0435 \u0438\u0445 \u0441\u043e\u0447\u0435\u0442\u0430\u0442\u044c \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c &#8212; \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043a\u0443\u0447\u0443 bool-\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445. \u041f\u043e\u0437\u0436\u0435 \u0432\u044b \u0443\u0432\u0438\u0434\u0438\u0442\u0435, \u043a\u0430\u043a \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c (\u0435\u0441\u043b\u0438, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0431\u0443\u0434\u0435\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0447\u0438\u0442\u0430\u0442\u044c \u043a\u043e\u0434)<\/p>\n<details class=\"spoiler\">\n<summary>\u0422\u0430\u0431\u043b\u0438\u0446\u0430 \u0444\u043b\u0430\u0433\u043e\u0432<\/summary>\n<div class=\"spoiler__content\">\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\"><strong>\u0424\u043b\u0430\u0433\u0438<\/strong><\/p>\n<\/th>\n<th>\n<p align=\"left\"><strong>\u0414\u0432\u043e\u0438\u0447\u043d\u043e\u0435<\/strong><\/p>\n<\/th>\n<th>\n<p align=\"left\"><strong>\u0414\u0435\u0441\u044f\u0442\u0438\u0447\u043d\u043e\u0435<\/strong><\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">WN_CONTROLS<\/p>\n<\/td>\n<td>\n<p align=\"left\">001<\/p>\n<\/td>\n<td>\n<p align=\"left\">1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">WN_DRAGABLE<\/p>\n<\/td>\n<td>\n<p align=\"left\">010<\/p>\n<\/td>\n<td>\n<p align=\"left\">2<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">WN_RESIZABLE<\/p>\n<\/td>\n<td>\n<p align=\"left\">100<\/p>\n<\/td>\n<td>\n<p align=\"left\">4<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<\/details>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u043e\u043a\u043d\u0443. \u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043a\u043b\u0430\u0441\u0441:<\/p>\n<pre><code class=\"python\">import tkinter as tk from PIL import Image, ImageTk  # WindowFlags here   class Window:     \"\"\"     A class representing a draggable, resizable window in the style of Windows 3.1.      The window includes a title bar with minimize, maximize and close buttons,     resizable corners, and a content area that can contain child windows.     \"\"\"      def __init__(self, parent, title, content, size, flags):         \"\"\"Initialize a new window.          Args:             parent: The parent widget (either the main frame or another window's content area)             title: The title of the window             content: The content widget to be placed inside the window             size: A tuple of (x, y, width, height) for the window's initial position and size             flags: Bitmap flags for window options         \"\"\"         self.parent = parent         self.title = title         self.content = content         self.size = size         self.flags = flags          # Initialize window state variables         self.is_resizing = False         self.is_maximized = False          # Store the previous size and position for restoration when un-maximizing         self.resize_offset_x = 0         self.resize_offset_y = 0          # Create a list to store child windows references         self.childs = []          self.create_window()         if self.content:             self.set_content(self.content)<\/code><\/pre>\n<p>\u041d\u0430\u0448\u0435 \u043e\u043a\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437:<\/p>\n<ul>\n<li>\n<p>\u0417\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430 \u0441 \u043a\u043d\u043e\u043f\u043a\u0430\u043c\u0438 (<code>self.title<\/code>)<\/p>\n<figure class=\"full-width\"><\/figure>\n<\/li>\n<li>\n<p>\u0420\u0430\u043c\u043a\u0438 \u0432\u043e\u043a\u0440\u0443\u0433 \u043e\u043a\u043d\u0430 \u0441 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c\u0438 \u0443\u0433\u043b\u0430\u043c\u0438 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f (\u0432 init \u043d\u0435 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442, \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u0435\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e)<\/p>\n<figure class=\"full-width\"><\/figure>\n<\/li>\n<li>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e (<code>self.content<\/code>)<\/p>\n<figure class=\"full-width\"><\/figure>\n<\/li>\n<li>\n<p>\u0418 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043e\u043a\u043e\u043d (\u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e) (<code>self.childs<\/code>)<\/p>\n<figure class=\"full-width\"><\/figure>\n<\/li>\n<\/ul>\n<p>\u041e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435, \u0434\u0443\u043c\u0430\u044e, \u0432 \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u044f\u0445 \u043d\u0435 \u043d\u0443\u0436\u0434\u0430\u0435\u0442\u0441\u044f. \u0418\u0434\u0451\u043c \u0434\u0430\u043b\u044c\u0448\u0435:<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">def create_window(self):         \"\"\" Create the window's visual elements and set up event bindings \"\"\"          # Unpack the size tuple         x, y, width, height = self.size          # Create the main window frame         self.window_frame = tk.LabelFrame(             self.parent,             relief=\"flat\",             padx=2,             pady=2,             background=\"#878A8D\",             highlightthickness=1,             highlightcolor=\"#000000\",             highlightbackground=\"#000000\"         )         self.window_frame.place(x=x, y=y, width=width, height=height)          # Add resizable corners if the window is resizable         if not self.flags &amp; WindowFlags.WN_RESIZABLE:             self.corner_A = tk.LabelFrame(                 self.window_frame,                 width=31,                 height=31,                 bg=\"#878A8D\",                 highlightthickness=1,                 highlightcolor=\"#000000\",                 highlightbackground=\"#000000\",                 relief=\"flat\"             )             self.corner_A.place(x=-5, y=-5)              self.corner_B = tk.LabelFrame(                 self.window_frame,                 width=31,                 height=31,                 bg=\"#878A8D\",                 highlightthickness=1,                 bd=1,                 highlightcolor=\"#000000\",                 highlightbackground=\"#000000\",                 relief=\"flat\"             )             self.corner_B.place(relx=1.0, x=5, y=-5, anchor='ne')              self.corner_C = tk.LabelFrame(                 self.window_frame,                 width=31,                 height=31,                 bg=\"#878A8D\",                 highlightthickness=1,                 bd=1,                 highlightcolor=\"#000000\",                 highlightbackground=\"#000000\",                 relief=\"flat\"             )             self.corner_C.place(relx=1.0, x=5, rely=1.0, y=5, anchor='se')              self.corner_D = tk.LabelFrame(                 self.window_frame,                 width=31,                 height=31,                 bg=\"#878A8D\",                 highlightthickness=1,                 bd=1,                 highlightcolor=\"#000000\",                 highlightbackground=\"#000000\",                 relief=\"flat\"             )             self.corner_D.place(rely=1.0, x=-5, y=5, anchor='sw')          # Create the title bar with a close button         self.title_bar = tk.Frame(             self.window_frame,             relief=\"raised\",             borderwidth=1,             background=\"#000000\",             highlightthickness=0,             highlightcolor=\"#FCFCFC\",             highlightbackground=\"#FCFCFC\"         )         self.title_bar.pack(fill=\"x\")          self.close_icon = ImageTk.PhotoImage(             Image.open(\".\/assets\/close_button.bmp\"))         self.close_button = tk.Button(             self.title_bar,             command=self.show_context_menu,             image=self.close_icon,             width=20,             height=20,             borderwidth=1,             relief=\"flat\",             anchor=\"center\",             bg=\"#C0C7C8\",             activebackground=\"#C0C7C8\",             fg=\"#000000\",             highlightthickness=1,             highlightcolor=\"#000000\",             highlightbackground=\"#000000\"         )         self.close_button.pack(side=\"left\")          self.title_label = tk.Label(             self.title_bar,             text=self.title,             font=(\"Arial\", 10, \"bold\"),             anchor=\"center\",             background=\"#000076\",             foreground=\"#FCFCFC\"         )         self.title_label.pack(side=\"left\", fill=\"both\", expand=True)          # Add maximize and minimize buttons if the window has controls         if not self.flags &amp; WindowFlags.WN_CONTROLS:             self.maximize_icon = ImageTk.PhotoImage(                 Image.open(\".\/assets\/maximize_button.bmp\"))             self.maximize_button = tk.Button(                 self.title_bar,                 command=self.maximize_window,                 image=self.maximize_icon,                 width=20,                 height=20,                 borderwidth=1,                 relief=\"raised\",                 anchor=\"center\",                 bg=\"#C0C7C8\",                 activebackground=\"#C0C7C8\",                 fg=\"#000000\",                 highlightthickness=1,                 highlightcolor=\"#000000\",                 highlightbackground=\"#000000\"             )             self.maximize_button.pack(side=\"right\")              self.shrink_icon = ImageTk.PhotoImage(                 Image.open(\".\/assets\/minimize_button.bmp\"))             self.shrink_button = tk.Button(                 self.title_bar,                 command=self.minimize_window,                 image=self.shrink_icon,                 width=20,                 height=20,                 borderwidth=1,                 relief=\"raised\",                 anchor=\"center\",                 bg=\"#C0C7C8\",                 activebackground=\"#C0C7C8\",                 fg=\"#000000\",                 highlightthickness=1,                 highlightcolor=\"#000000\",     <\/code><\/pre>\n<\/div>\n<\/details>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-455505","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/455505","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=455505"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/455505\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=455505"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=455505"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=455505"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}