{"id":389268,"date":"2024-06-29T08:29:14","date_gmt":"2024-06-29T08:29:14","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=389268"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=389268","title":{"rendered":"<span>Python GUI. \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 KivyMD. \u0428\u0430\u0431\u043b\u043e\u043d MVC, parallax \u044d\u0444\u0444\u0435\u043a\u0442 \u0438 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044f \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u0441\u043b\u0430\u0439\u0434\u043e\u0432<\/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<p>\u041f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e \u0432\u0430\u0441, \u0434\u043e\u0440\u043e\u0433\u0438\u0435 \u043b\u044e\u0431\u0438\u0442\u0435\u043b\u0438 \u0438 \u0437\u043d\u0430\u0442\u043e\u043a\u0438 <em>Python<\/em>! \u041f\u0440\u043e\u0448\u043b\u043e \u043f\u043e\u043b \u0433\u043e\u0434\u0430 \u0441 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u043c\u043e\u0435\u0439 <a href=\"https:\/\/habr.com\/ru\/post\/546684\/\" rel=\"noopener noreferrer nofollow\">\u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 <\/a>\u043d\u0430 \u0425\u0430\u0431\u0440\u0435. \u0411\u044b\u043b \u043f\u043e\u0433\u0440\u0443\u0436\u0435\u043d \u0432 \u043f\u0443\u0447\u0438\u043d\u0443 \u043e\u0431\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u0441\u0442\u0432 \u0438 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u044b. \u041d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u0441\u0435\u0433\u043e\u0434\u043d\u044f\u0448\u043d\u0435\u0439, \u0441\u0442\u0430\u0442\u044c\u0438 \u0431\u0443\u0434\u0443\u0442 \u0432\u044b\u0445\u043e\u0434\u0438\u0442\u044c \u0441 \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u043d\u043e\u0441\u0442\u044c\u044e \u0440\u0430\u0437 \u0432 \u043c\u0435\u0441\u044f\u0446. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438 \u0430\u043d\u0438\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u0434\u043b\u044f \u0441\u043b\u0430\u0439\u0434\u043e\u0432 \u0430 \u0442\u0430\u043a\u0436\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c parallax \u044d\u0444\u0444\u0435\u043a\u0442 \u0434\u043b\u044f \u0444\u043e\u043d\u043e\u0432\u043e\u0433\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 <em>Kivy<\/em> \u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 <em>KivyMD<\/em>. \u0414\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u043d\u0435\u0437\u043d\u0430\u043a\u043e\u043c \u043d\u0438 \u0441 \u043f\u0435\u0440\u0432\u044b\u043c \u043d\u0438 \u0441\u043e \u0432\u0442\u043e\u0440\u043e\u0439, \u0432\u043a\u0440\u0430\u0442\u0446\u0435 \u043d\u0430\u043f\u043e\u043c\u043d\u044e:<\/p>\n<figure class=\"float\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b54\/c69\/2ef\/b54c692efa1a97a6a3fb77d07f4893a1.png\" width=\"128\" height=\"128\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b54\/c69\/2ef\/b54c692efa1a97a6a3fb77d07f4893a1.png\"\/><figcaption><\/figcaption><\/figure>\n<p><a href=\"https:\/\/github.com\/kivy\/kivy\" rel=\"noopener noreferrer nofollow\">Kivy<\/a> &#8212; \u043a\u0440\u043e\u0441\u0441\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u044b\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c <em>Python\/Cython<\/em>. \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0432\u0432\u043e\u0434\u0430: <em>WM_Touch, WM_Pen, Mac OS X Trackpad Magic Mouse, Mtdev, Linux Kernel HID, TUIO<\/em>&#8230;<\/p>\n<figure class=\"float\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f3f\/ae4\/3bf\/f3fae43bf2c0bc97140ed83ac4fe7300.png\" width=\"128\" height=\"128\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f3f\/ae4\/3bf\/f3fae43bf2c0bc97140ed83ac4fe7300.png\"\/><figcaption><\/figcaption><\/figure>\n<p><a href=\"https:\/\/github.com\/kivymd\/KivyMD\" rel=\"noopener noreferrer nofollow\">KivyMD<\/a> &#8212; \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0430\u044f \u043d\u0430\u0431\u043e\u0440 \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432 \u0432 \u0441\u0442\u0438\u043b\u0435 <em>Google Material Design<\/em>, \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u043c <em>Kivy<\/em>. \u0412\u043d\u0435 \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u044b Kivy \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f. \u0422\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 &#8212; \u0431\u0435\u0442\u0430.<\/p>\n<h2>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439<\/h2>\n<pre><code class=\"bash\">pip install \"kivy[base] @ https:\/\/github.com\/kivy\/kivy\/archive\/master.zip\" pip install https:\/\/github.com\/kivymd\/KivyMD\/archive\/master.zip<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0432\u0430\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a <em>Kivy<\/em> \u043c\u0430\u0441\u0442\u0435\u0440 \u0432\u0435\u0440\u0441\u0438\u0438, \u0430 \u0432\u0442\u043e\u0440\u0430\u044f &#8212; \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 <em>KivyMD<\/em> \u0442\u0430\u043a\u0436\u0435 \u043c\u0430\u0441\u0442\u0435\u0440 \u0432\u0435\u0440\u0441\u0438\u0438. \u0412\u0441\u0435. \u041c\u043e\u0436\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. \u041d\u043e \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043e\u0439 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 <em>PizzaAppConcept<\/em>, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c. \u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0435, \u0432\u0441\u0435\u0433\u043e \u043e\u0434\u0438\u043d \u044d\u043a\u0440\u0430\u043d, \u043d\u043e \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044f \u043b\u044e\u0431\u043b\u044e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u044e \u0432 \u043b\u044e\u0431\u043e\u043c \u0441\u0432\u043e\u0435\u043c \u043a\u043e\u0434\u0435, \u044f \u0440\u0435\u0448\u0438\u043b, \u0447\u0442\u043e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0430 \u043d\u0430 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0435 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/Model-View-Controller\" rel=\"noopener noreferrer nofollow\">MVC<\/a>, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u043e \u043c\u043e\u0435\u043c\u0443 \u0441\u0443\u0431\u044a\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u043c\u0443 \u043c\u043d\u0435\u043d\u0438\u044e \u044d\u0442\u043e\u0442 \u0448\u0430\u0431\u043b\u043e\u043d \u043a\u0430\u043a \u043d\u0435\u043b\u044c\u0437\u044f \u043b\u0443\u0447\u0448\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u0440\u044f\u0434\u043a\u0430 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435. \u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 <em>MVC<\/em> \u044f \u043d\u0435 \u0431\u0443\u0434\u0443 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u0437\u0434\u0435\u0441\u044c. \u0414\u0435\u0442\u0430\u043b\u0438 \u0440\u0430\u0441\u043a\u0440\u043e\u044e\u0442\u0441\u044f \u0441\u0430\u043c\u0438 \u0441\u043e\u0431\u043e\u0439 \u043f\u043e \u0445\u043e\u0434\u0443 \u0443\u0433\u043b\u0443\u0431\u043b\u0435\u043d\u0438\u044f \u0432 \u0441\u0435\u0433\u043e\u0434\u043d\u044f\u0448\u043d\u0438\u0439 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b.<\/p>\n<h2>\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 MVC<\/h2>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ea9\/39f\/e86\/ea939fe868077a38d890810f07d68aad.png\" width=\"696\" height=\"301\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ea9\/39f\/e86\/ea939fe868077a38d890810f07d68aad.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041f\u0440\u043e\u0435\u043a\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/bbf\/1b9\/0cf\/bbf1b90cf27ba8b453278ba091fa3cdb.png\" width=\"772\" height=\"145\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/bbf\/1b9\/0cf\/bbf1b90cf27ba8b453278ba091fa3cdb.png\"\/><figcaption><\/figcaption><\/figure>\n<ul>\n<li>\n<p><strong>assets<\/strong> &#8212; \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0448\u0440\u0438\u0444\u0442\u044b \u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/p>\n<\/li>\n<li>\n<p><strong>Controller<\/strong> &#8212; \u043c\u043e\u0434\u0443\u043b\u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u0432<\/p>\n<\/li>\n<li>\n<p><strong>Model<\/strong> &#8212; \u043c\u043e\u0434\u0443\u043b\u0438 \u043c\u043e\u0434\u0435\u043b\u0435\u0439<\/p>\n<\/li>\n<li>\n<p><strong>Utility<\/strong> &#8212; \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043c\u043e\u0434\u0443\u043b\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/p>\n<\/li>\n<li>\n<p><strong>View<\/strong> &#8212; \u043f\u0430\u043a\u0435\u0442\u044b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0439<\/p>\n<\/li>\n<\/ul>\n<p>\u0420\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0438\u043c\u0435\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b17\/65a\/db3\/b1765adb36edb920a5747d2062fac6c2.png\" width=\"775\" height=\"585\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b17\/65a\/db3\/b1765adb36edb920a5747d2062fac6c2.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043c\u043e\u0434\u0443\u043b\u0438 \u043c\u043e\u0434\u0435\u043b\u0438, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u0438\u043c\u0435\u044e\u0442 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0435 \u0438\u043c\u0435\u043d\u0430.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e5d\/2a1\/a6e\/e5d2a1a6ec3aa053ecb1398e40c6b95b.png\" width=\"702\" height=\"344\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e5d\/2a1\/a6e\/e5d2a1a6ec3aa053ecb1398e40c6b95b.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u042d\u0442\u043e \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u043e \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435, \u0435\u0441\u043b\u0438 \u043f\u0440\u043e\u0435\u043a\u0442 \u0431\u043e\u043b\u044c\u0448\u043e\u0439. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u043c\u043e\u0435\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0448\u0435\u0441\u0442\u043d\u0430\u0434\u0446\u0430\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0436\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0439 \u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u0432.<\/p>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u0442\u044c \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u044d\u043a\u0440\u0430\u043d\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441-\u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u0435\u043b\u044c. \u042d\u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0443\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d \u043a\u0430\u0436\u0434\u044b\u043c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c. \u041a\u043b\u0430\u0441\u0441-\u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u0435\u043b\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 <em>model_is_changed<\/em> &#8212; \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437, \u043a\u043e\u0433\u0434\u0430 \u0438\u0437\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043a\u043b\u0430\u0441\u0441\u0430\u0445 \u043c\u043e\u0434\u0435\u043b\u0435\u0439, \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0441\u0438\u0433\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044e \u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u0435\u0434\u0448\u0438\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u0445.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/195\/f7c\/9e6\/195f7c9e6989817036335ead394703ee.png\" width=\"663\" height=\"163\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/195\/f7c\/9e6\/195f7c9e6989817036335ead394703ee.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041a\u043b\u0430\u0441\u0441-\u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0434\u0443\u043b\u044f <em>observer.py<\/em>:<\/p>\n<pre><code class=\"python\"># Of course, \"very flexible Python\" allows you to do without an abstract # superclass at all or use the clever exception `NotImplementedError`. In my # opinion, this can negatively affect the architecture of the application. # I would like to point out that using Kivy, one could use the on-signaling # model. In this case, when the state changes, the model will send a signal # that can be received by all attached observers. This approach seems less # universal - you may want to use a different library in the future.   class Observer:     \"\"\"Abstract superclass for all observers.\"\"\"      def model_is_changed(self):         \"\"\"         The method that will be called on the observer when the model changes.         \"\"\"<\/code><\/pre>\n<p>\u041a\u0430\u043a \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445 \u043a \u043a\u043b\u0430\u0441\u0441\u0443 <em>Observer<\/em>, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/kivy.org\/doc\/stable\/api-kivy.properties.html\" rel=\"noopener noreferrer nofollow\"><em>properties<\/em><\/a> \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a <em>NumericProperty, StringProperty, DictProperty<\/em> \u0438 \u0434\u0440. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u0440\u0430\u0432\u043d\u0438\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 <em>Python<\/em> \u0438 <em>Kivy<\/em>:<\/p>\n<p><strong>Python<\/strong>:<\/p>\n<pre><code class=\"python\">class MyClass:     def __init__(self, a=1.0):         super().__init__()         self.a = a<\/code><\/pre>\n<p><strong>Kivy<\/strong>:<\/p>\n<pre><code class=\"python\">class MyClass:     a = NumericProperty(1.0)<\/code><\/pre>\n<p><em>Properties<\/em> \u0432 <em>Kivy<\/em> \u0443\u0434\u043e\u0431\u043d\u0435\u0435. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0432 properties <em>Kivy<\/em> \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u0440\u044f\u0434 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434\u043e\u0432, \u0442\u0430\u043a\u0438\u0445, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u0430\u043a <em>on_<\/em> \u043c\u0435\u0442\u043e\u0434\u044b:<\/p>\n<pre><code class=\"python\">class MyClass:     a = NumericProperty(1)      def on_a(self, instance_my_class, new_a_value):         \"\"\"         The method called as soon as a new value has been set for the         'a' attribute.         \"\"\"          print(\"My property a changed to\", new_a_value)<\/code><\/pre>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u0438\u043c, \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <em>properties<\/em> \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a <em>Kivy<\/em>, \u0434\u043b\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u043a\u043b\u0430\u0441\u0441\u0430, \u0447\u0442\u043e, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0449\u0435, \u0447\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u0430\u044f \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f. \u041d\u043e \u0432 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0432\u0435\u0441\u044c \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0442\u043e\u0447\u0435\u043d \u043f\u043e\u0434 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a <em>Kivy<\/em> \u0438 \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c, \u0435\u0441\u043b\u0438 \u0432\u044b \u0437\u0430\u0445\u043e\u0442\u0438\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u043e\u0439 <em>GUI<\/em> \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u0441\u0435 \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u0434 \u043d\u043e\u0432\u044b\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a &#8212; \u0438 \u043c\u043e\u0434\u0435\u043b\u0438, \u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u044b. \u0414\u0430\u043d\u043d\u0430\u044f \u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430 \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0447\u0442\u043e \u0432\u0430\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435, \u043c\u043e\u0434\u0435\u043b\u044c \u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u044b \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u0435\u043b\u044f, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430\u0448\u0435\u0433\u043e \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u044d\u043a\u0440\u0430\u043d\u0430 \u0441\u043e \u0441\u043b\u0430\u0439\u0434\u0430\u043c\u0438 \u0441\u043e\u0440\u0442\u043e\u0432 \u043f\u0438\u0446\u0446\u044b. \u0412 \u043f\u0430\u043a\u0435\u0442\u0435 <em>View<\/em> \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u043e\u0432\u044b\u0439 \u043f\u0430\u043a\u0435\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441 \u0438\u043c\u0435\u043d\u0435\u043c <em>SliderMenuScreen<\/em>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u043c \u043c\u043e\u0434\u0443\u043b\u044c <em>slider_menu_screen.py<\/em> \u0441 \u043a\u043b\u0430\u0441\u0441\u043e\u043c \u043d\u0430\u0448\u0435\u0433\u043e \u044d\u043a\u0440\u0430\u043d\u0430:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/fb5\/b7c\/d26\/fb5b7cd262c5e9a11117ebd6b51c2505.png\" width=\"772\" height=\"203\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/fb5\/b7c\/d26\/fb5b7cd262c5e9a11117ebd6b51c2505.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041a\u043b\u0430\u0441\u0441 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f <em>SliderMenuScreenView<\/em> \u043c\u043e\u0434\u0443\u043b\u044f <em>slider_menu_screen.py<\/em>:<\/p>\n<pre><code class=\"python\">from kivy.properties import ObjectProperty  from kivymd.uix.screen import MDScreen  from Utility.observer import Observer   class SliderMenuScreenView(MDScreen, Observer):     \"\"\"     A class that implements a visual representation of the model data     :class:`~Model.slider_menu_screen.SliderMenuScreenModel`.      Implements a screen with slides of pizza varieties.     \"\"\"      controller = ObjectProperty()     \"\"\"     Controller object -     :class:`~Controller.slider_menu_screen.SliderMenuScreenController`.      :attr:`controller` is an :class:`~kivy.properties.ObjectProperty`     and defaults to `None`.     \"\"\"      model = ObjectProperty()     \"\"\"     Model object - :class:`~Model.slider_menu_screen.SliderMenuScreenModel`.      :attr:`model` is an :class:`~kivy.properties.ObjectProperty`     and defaults to `None`.     \"\"\"      manager_screens = ObjectProperty()     \"\"\"     Screen manager object - :class:`~kivy.uix.screenmanager.ScreenManager`.      :attr:`manager_screens` is an :class:`~kivy.properties.ObjectProperty`     and defaults to `None`.     \"\"\"      def __init__(self, **kw):         super().__init__(**kw)         self.model.add_observer(self)      def model_is_changed(self):         \"\"\"         The method that will be called on the observer when the model changes.         \"\"\"<\/code><\/pre>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u043c\u0435\u0442\u044c \u0442\u0440\u0438 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u043e\u043b\u044f:<\/p>\n<ul>\n<li>\n<p><strong>controller<\/strong> &#8212; \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430<\/p>\n<\/li>\n<li>\n<p><strong>model<\/strong> &#8212; \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 \u043c\u043e\u0434\u0435\u043b\u0438<\/p>\n<\/li>\n<li>\n<p><strong>manager_screens<\/strong> &#8212; \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 <em>kivy.uix.screenmanager.ScreenManager<\/em> (\u044d\u043a\u0440\u0430\u043d\u043d\u044b\u0439 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u044d\u043a\u0440\u0430\u043d\u043e\u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f)<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u0435\u043b\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0430\u043c\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434 <em>model_is_changed<\/em> \u0434\u043b\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043c\u043e\u0434\u0435\u043b\u0438. \u0422\u0430\u043a\u0436\u0435 \u043a\u043b\u0430\u0441\u0441 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f <em>SliderMenuScreenView<\/em> \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u0442\u0441\u044f \u043e\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 <em>kivymd.uix.screen.MDScreen<\/em>: \u043b\u044e\u0431\u043e\u0439 \u044d\u043a\u0440\u0430\u043d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 <em>ScreenManager<\/em> \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0443\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d \u043e\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 <em>MDScreen<\/em>.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f <em>SliderMenuScreenView<\/em>:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9e2\/93d\/edf\/9e293dedf237b2888576f19e08f04bdb.png\" width=\"772\" height=\"160\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/9e2\/93d\/edf\/9e293dedf237b2888576f19e08f04bdb.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041a\u043b\u0430\u0441\u0441 \u043c\u043e\u0434\u0435\u043b\u0438 <em>SliderMenuScreenModel<\/em>:<\/p>\n<pre><code class=\"python\"># The model implements the observer pattern. This means that the class must # support adding, removing, and alerting observers. In this case, the model is # completely independent of controllers and views. It is important that all # registered observers implement a specific method that will be called by the # model when they are notified (in this case, it is the `model_is_changed` # method). For this, observers must be descendants of an abstract class, # inheriting which, the `model_is_changed` method must be overridden.   class SliderMenuScreenModel:     \"\"\"Implements screen logic for pizza variety slides.\"\"\"      def __init__(self):         # List of observer classes. In our case, this will be the         # `View.SliderMenuScreen.slider_menu_screen.py` class.         # See `__init__` method of the above class.         self._observers = []      def notify_observers(self):         \"\"\"         The method that will be called on the observer when the model changes.         \"\"\"          for observer in self._observers:             observer.model_is_changed()      def add_observer(self, observer):         self._observers.append(observer)      def remove_observer(self, observer):         self._observers.remove(observer)<\/code><\/pre>\n<p>\u041c\u043e\u0434\u0435\u043b\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0442\u0440\u0438 \u043c\u0435\u0442\u043e\u0434\u0430: \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435\/\u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435\/\u043e\u043f\u043e\u0432\u0435\u0449\u0435\u043d\u0438\u0435 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u0435\u043b\u0435\u0439. \u041f\u043e\u043a\u0430 \u043d\u0430\u0448\u0430 \u043c\u043e\u0434\u0435\u043b\u044c \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0445. \u041f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/96d\/c93\/c65\/96dc93c65ff5330cee7e78c33235c411.png\" width=\"772\" height=\"160\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/96d\/c93\/c65\/96dc93c65ff5330cee7e78c33235c411.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041a\u043b\u0430\u0441\u0441 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 <em>SliderMenuScreenController<\/em>:<\/p>\n<pre><code class=\"python\">from View.SliderMenuScreen.slider_menu_screen import SliderMenuScreenView   class SliderMenuScreenController:     \"\"\"     The `SliderMenuScreenController` class represents a controller     implementation. Coordinates work of the view with the model.      The controller implements the strategy pattern. The controller connects     to the view to control its actions.     \"\"\"      def __init__(self, model):         self.model = model  # Model.slider_menu_screen.SliderMenuScreenModel         self.view = SliderMenuScreenView(controller=self, model=self.model)      def get_view(self) -> SliderMenuScreenView:         return self.view<\/code><\/pre>\n<p>\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442 \u0432\u0441\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0442 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435: \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u0432\u0432\u043e\u0434, \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0438 \u0442.\u0434. \u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u044f \u044d\u0442\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f, \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u043c\u043e\u0434\u0435\u043b\u0438 \u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0438\u0440\u0443\u044f \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043b\u043e\u0433\u0438\u043a\u0443 \u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c. \u0412 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u043a\u043b\u0430\u0441\u0441\u0430 <em>SliderMenuScreenController<\/em> \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u044d\u0442\u043e\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 <em>get_view<\/em>. \u041f\u043e\u043a\u0430 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0432 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0435 \u043c\u044b \u043d\u0435 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u043c. \u041d\u0430 \u044d\u0442\u043e\u043c \u043c\u044b \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043c \u0441 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u043c <em>MVC<\/em>. \u0414\u0432\u0438\u0433\u0430\u0435\u043c\u0441\u044f \u0434\u0430\u043b\u044c\u0448\u0435&#8230;<\/p>\n<h2>\u0422\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430 \u0432 \u043f\u0440\u0438\u043e\u0436\u0435\u043d\u0438\u0435<\/h2>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/565\/097\/a00\/565097a009b8bf1b6f4155d1b51a309f.png\" width=\"663\" height=\"143\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/565\/097\/a00\/565097a009b8bf1b6f4155d1b51a309f.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0421 \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 <em>Kivy<\/em> \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041d\u043e \u043f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u043d\u0430\u0447\u0430\u0442\u044c \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u043c\u043e\u0434\u0443\u043b\u044c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c <em>screens.py<\/em> \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <em>View<\/em>:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/cb0\/163\/829\/cb0163829a5257d5b3993a67af863401.png\" width=\"651\" height=\"165\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/cb0\/163\/829\/cb0163829a5257d5b3993a67af863401.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u042d\u0442\u043e\u0442 \u043c\u043e\u0434\u0443\u043b\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u043b\u043e\u0432\u0430\u0440\u044c \u0441 \u043a\u043b\u0430\u0441\u0441\u0430\u043c\u0438 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u0432. \u0412 \u0442\u043e\u0447\u043a\u0435 \u0432\u0445\u043e\u0434\u0430 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 &#8212; \u0432 \u043c\u043e\u0434\u0443\u043b\u0435 <em>main.py<\/em> &#8212; \u0432 \u0446\u0438\u043a\u043b\u0435 \u043c\u044b \u043f\u0440\u043e\u0439\u0434\u0435\u043c\u0441\u044f \u043f\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c \u044d\u0442\u043e\u0433\u043e \u0441\u043b\u043e\u0432\u0430\u0440\u044f, \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u043f\u0435\u0440\u0435\u0434\u0430\u0434\u0438\u043c \u0438\u043c \u043d\u0443\u0436\u043d\u044b\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b, \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u044d\u043a\u0440\u0430\u043d\u043e\u0432, \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0438\u0445 \u0432 \u044d\u043a\u0440\u0430\u043d\u043d\u044b\u0439 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u043c \u044d\u0442\u043e\u0442 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435. \u042d\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u0443\u0434\u043e\u0431\u043d\u043e, \u043a\u043e\u0433\u0434\u0430 \u043d\u0430\u043c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0449\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u043a\u0440\u0430\u043d\u043e\u0432 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \u041c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0442\u043a\u0440\u043e\u0435\u043c \u043c\u043e\u0434\u0443\u043b\u044c <em>screens.py<\/em> \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u0443\u0436\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u0432 \u0441\u043b\u043e\u0432\u0430\u0440\u044c.<\/p>\n<p>\u041c\u043e\u0434\u0443\u043b\u044c <em>screens.py<\/em>:<\/p>\n<pre><code class=\"python\"># The screens dictionary contains the objects of the models and controllers # of the screens of the application.  from Model.slider_menu_screen import SliderMenuScreenModel from Controller.slider_menu_screen import SliderMenuScreenController  screens = {     # name screen     \"slider menu screen\": {         \"model\": SliderMenuScreenModel,  # class of model         \"controller\": SliderMenuScreenController,  # class of controller     }, }<\/code><\/pre>\n<p>\u041a\u043b\u044e\u0447\u0438 \u0441\u043b\u043e\u0432\u0430\u0440\u044f <em>screens<\/em> &#8212; \u044d\u0442\u043e \u0438\u043c\u0435\u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u043e\u0432 \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u044d\u0442\u0438 \u044d\u043a\u0440\u0430\u043d\u044b \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0442\u044c, \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044f \u0432 \u044d\u043a\u0440\u0430\u043d\u043d\u043e\u043c \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0435 \u0438\u043c\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u044d\u043a\u0440\u0430\u043d\u0430, \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f &#8212; \u0441\u043b\u043e\u0432\u0430\u0440\u044c \u0442\u0438\u043f\u0430 <em>&#8216;model\/controller&#8217;: &#8216;Model class\/Controller class&#8217;.<\/em><\/p>\n<p>\u0422\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 &#8212; \u043c\u043e\u0434\u0443\u043b\u044c <em>main.py<\/em>:<\/p>\n<pre><code class=\"python\">\"\"\" The entry point to the application.  The application uses the MVC template. Adhering to the principles of clean architecture means ensuring that your application is easy to test, maintain, and modernize.  You can read more about this template at the links below:  https:\/\/github.com\/HeaTTheatR\/LoginAppMVC https:\/\/en.wikipedia.org\/wiki\/Model\u2013view\u2013controller \"\"\"  from kivy.uix.screenmanager import ScreenManager from kivy.config import Config  Config.set(\"graphics\", \"height\", \"799\") Config.set(\"graphics\", \"width\", \"450\")  from kivymd.app import MDApp  from View.screens import screens   class PizzaAppConcept(MDApp):     def __init__(self, **kwargs):         super().__init__(**kwargs)         self.load_all_kv_files(self.directory)         # This is the screen manager that will contain all the screens of your         # application.         self.manager_screens = ScreenManager()      def build(self):         \"\"\"         Initializes the application; it will be called only once.         If this method returns a widget (tree), it will be used as the root         widget and added to the window.          :return:             None or a root :class:`~kivy.uix.widget.Widget` instance             if no self.root exists.         \"\"\"          self.theme_cls.primary_palette = \"DeepOrange\"         self.generate_application_screens()         return self.manager_screens      def generate_application_screens(self):         \"\"\"         Creating and adding screens to the screen manager.         You should not change this cycle unnecessarily. He is self-sufficient.          If you need to add any screen, open the `View.screens.py` module and         see how new screens are added according to the given application         architecture.         \"\"\"          for i, name_screen in enumerate(screens.keys()):             model = screens[name_screen][\"model\"]()             controller = screens[name_screen][\"controller\"](model)             view = controller.get_view()             view.manager_screens = self.manager_screens             view.name = name_screen             self.manager_screens.add_widget(view)   PizzaAppConcept().run()<\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u043c\u0435\u043d\u044f\u0442\u044c &#8212; \u044d\u0442\u043e \u0448\u0430\u0431\u043b\u043e\u043d. \u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 Kivy \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 \u043a\u043b\u0430\u0441\u0441\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d \u043e\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 <em>kivy.app.App<\/em> \u0438\u043b\u0438 \u043e\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 <em>kivymd.app.MDApp<\/em> \u0435\u0441\u043b\u0438 \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 <em>KivyMD<\/em>. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e \u043a\u043b\u0430\u0441\u0441 <em>PizzaAppConcept<\/em>. \u0414\u0430\u043d\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0434\u043e\u043b\u0436\u0435\u043d \u0432 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <em>build<\/em> (\u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u043b\u044e\u0431\u043e\u0439 \u0432\u0438\u0434\u0436\u0435\u0442 <em>Kivy\/KivyMD<\/em> (\u0435\u0441\u0442\u044c \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u043f\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u0432\u0438\u0434\u0436\u0435\u0442\u0430 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f, \u043d\u043e \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u044d\u0442\u043e \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c).  \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0432\u0438\u0434\u0436\u0435\u0442 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430 \u044d\u043a\u0440\u0430\u043d\u043e\u0432 &#8212; <em>kivy.uix.screenmanager.ScreenManager.<\/em><\/p>\n<p>\u041f\u0440\u043e\u0439\u0434\u0435\u043c\u0441\u044f \u043f\u043e \u043b\u043e\u0433\u0438\u043a\u0435 \u043a\u043b\u0430\u0441\u0441\u0430 <em>PizzaAppConcept<\/em> \u0442\u0430\u043a, \u043a\u0430\u043a \u043e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u043e\u043c <em>Python<\/em>:<\/p>\n<ol>\n<li>\n<p>\u0412 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u043a\u043b\u0430\u0441\u0441\u0430 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0432\u0441\u0435 <em>*kv<\/em> (\u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 <em>GUI<\/em> \u043d\u0430 <em>DSL<\/em> \u044f\u0437\u044b\u043a\u0435 <a href=\"https:\/\/kivy.org\/doc\/stable\/guide\/lang.html\" rel=\"noopener noreferrer nofollow\">KV Language<\/a>) \u0444\u0430\u0439\u043b\u044b \u0438\u0437 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430 \u044d\u043a\u0440\u0430\u043d\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u0412 \u043c\u0435\u0442\u043e\u0434\u0435 <em>build<\/em> \u0432\u044b\u0437\u043e\u0432\u0435\u043c \u043c\u0435\u0442\u043e\u0434 <em>generate_application_screens<\/em>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u044b \u0432\u0441\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u043b\u043e\u0432\u0430\u0440\u044f screen \u0438\u0437 \u043c\u043e\u0434\u0443\u043b\u044f <em>View.screens.py,<\/em> \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b \u0432 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u044d\u043a\u0440\u0430\u043d\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u041c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u044d\u043a\u0440\u0430\u043d\u043e\u0432 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d \u0438\u0437 \u043c\u0435\u0442\u043e\u0434\u0430 <em>build.<\/em><\/p>\n<\/li>\n<\/ol>\n<p>\u0412\u043e\u0442 \u0442\u0435\u043f\u0435\u0440\u044c \u0443\u0436 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 <em>python<\/em> <em>main.py,<\/em> \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u043f\u0443\u0441\u0442\u043e\u0439 \u044d\u043a\u0440\u0430\u043d \u0438 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0433\u043b\u0430\u0432\u043d\u043e\u043c\u0443 &#8212; \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u044d\u043a\u0440\u0430\u043d\u0430 \u0441\u043e \u0441\u043b\u0430\u0439\u0434\u0430\u043c\u0438 \u0441\u043e\u0440\u0442\u043e\u0432 \u043f\u0438\u0446\u0446\u044b:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/8e2\/0db\/640\/8e20db640a2baf64f9a30a8fad3ebd82.gif\" width=\"446\" height=\"744\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/8e2\/0db\/640\/8e20db640a2baf64f9a30a8fad3ebd82.gif\"\/><figcaption><\/figcaption><\/figure>\n<h2>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u044d\u043a\u0440\u0430\u043d\u0430 \u0441\u043b\u0430\u0439\u0434\u043e\u0432<\/h2>\n<p>\u041a\u0430\u043a \u0432\u044b \u043f\u043e\u043c\u043d\u0438\u0442\u0435, \u0443 \u043d\u0430\u0441 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u043a\u043b\u0430\u0441\u0441 <em>SliderMenuScreenView<\/em>. \u041d\u043e \u043f\u043e\u043a\u0430 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0443\u0441\u0442\u043e\u0439 \u044d\u043a\u0440\u0430\u043d, \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a \u043e\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 <em>MDScreen<\/em>. \u041f\u043e\u0440\u0430 \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0432 \u043d\u0435\u043c \u0432\u0438\u0434\u0436\u0435\u0442\u044b. \u0414\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441\u043b\u0430\u0439\u0434\u043e\u0432 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441 <em>kivymd.uix.carousel.MDCarousel.<\/em> \u0412\u0435\u0441\u044c <em>UI<\/em> \u0431\u0443\u0434\u0435\u0442 \u043e\u043f\u0438\u0441\u0430\u043d \u0432 <em>*kv<\/em> \u0444\u0430\u0439\u043b\u0430\u0445, \u0432 <em>Python<\/em> \u043c\u043e\u0434\u0443\u043b\u044f\u0445 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043b\u0438\u0448\u044c \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c (\u0435\u0441\u043b\u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f) \u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432. \u0422\u043e \u0435\u0441\u0442\u044c, \u0432 Kivy \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432 \u0442\u0430\u043a\u0436\u0435 \u043e\u0442\u0434\u0435\u043b\u0435\u043d\u043e \u043e\u0442 \u043b\u043e\u0433\u0438\u043a\u0438 \u043a\u0430\u043a \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0442 \u043c\u043e\u0434\u0435\u043b\u0438 \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0435 <em>MVC<\/em>. <\/p>\n<p>\u0420\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u043c \u0432 \u043f\u0430\u043a\u0435\u0442\u0435 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b <em>slider_menu_screen.kv:<\/em><\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/62f\/cae\/1f2\/62fcae1f2461018f56bd52c627c9b692.png\" width=\"749\" height=\"259\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/62f\/cae\/1f2\/62fcae1f2461018f56bd52c627c9b692.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043c\u043e\u0434\u0443\u043b\u044c \u0441 \u043a\u043b\u0430\u0441\u0441\u043e\u043c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438 <em>kv<\/em> \u0444\u0430\u0439\u043b \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c <em>GUI<\/em> \u043d\u043e\u0441\u044f\u0442 \u0438\u0434\u0435\u043d\u0442\u0438\u0447\u043d\u044b\u0435 \u0438\u043c\u0435\u043d\u0430. \u042d\u0442\u043e \u043d\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043d\u043e \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u0442\u043e\u043d. \u0422\u0430\u043a\u0436\u0435 \u0432 \u043c\u043e\u0434\u0443\u043b\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u043e\u043b\u0436\u0435\u043d \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u043a\u043b\u0430\u0441\u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u043a\u0430\u043a \u0438 \u0432 \u0444\u0430\u0439\u043b\u0435 <em>kv<\/em> \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043a\u043b\u0430\u0441\u0441\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f. \u042d\u0442\u043e \u0442\u0430\u043a\u0436\u0435 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u043e\u043c, \u043d\u043e \u0437\u0430\u043c\u0435\u0442\u043d\u043e \u043e\u0431\u043b\u0435\u0433\u0447\u0438\u0442 \u0432\u0430\u043c \u0436\u0438\u0437\u043d\u044c, \u043a\u043e\u0433\u0434\u0430 \u0432\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430\u0447\u043d\u0435\u0442 \u0440\u0430\u0441\u0442\u0438.<\/p>\n<p>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 <em>GUI<\/em> \u043a\u043b\u0430\u0441\u0441\u0430 <em>SliderMenuScreenView<\/em> \u0432 \u0444\u0430\u0439\u043b\u0435 <em>slider_menu_screen.kv:<\/em><\/p>\n<pre><code class=\"yaml\">MDCarousel:     id: carousel <\/code><\/pre>\n<p>\u0410 \u0432\u043e\u0442 \u0437\u0434\u0435\u0441\u044c \u0443\u0436\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e  \u0434\u043e\u043b\u0436\u043d\u043e \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0442\u044c \u0441 \u0438\u043c\u0435\u043d\u0435\u043c \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e <em>Python<\/em> \u043a\u043b\u0430\u0441\u0441\u0430 \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0443 \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 <em>KV Language<\/em> \u0438 \u044d\u0442\u043e &#8212; \u043f\u0440\u0430\u0432\u0438\u043b\u043e. \u0412 <em>kv<\/em> \u0444\u0430\u0439\u043b\u0430\u0445 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c <em>Kivy\/KivyMD<\/em> \u0432\u0438\u0434\u0436\u0435\u0442\u044b, \u043e\u043d\u0438 \u0443\u0436\u0435 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0448 \u044d\u043a\u0440\u0430\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432\u0438\u0434\u0436\u0435\u0442 <em>MDCarousel<\/em>, \u043d\u043e \u0432\u0441\u0435 \u0435\u0449\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u0443\u0441\u0442\u044b\u043c, \u0435\u0441\u043b\u0438 \u043c\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0442\u0430\u043a \u043a\u0430\u043a <em>MDCarousel<\/em> \u043f\u043e\u043a\u0430 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432. \u0414\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0432 <em>MDCarousel<\/em> \u0442\u0440\u0438 \u043a\u043d\u043e\u043f\u043a\u0438:<\/p>\n<pre><code class=\"yaml\">MDCarousel:     id: carousel      MDRaisedButton:         text: \"SLIDE 1\"         pos_hint: {\"center_x\": .5, \"center_y\": .5}      MDRaisedButton:         text: \"SLIDE 2\"         pos_hint: {\"center_x\": .5, \"center_y\": .5}      MDRaisedButton:         text: \"SLIDE 3\"         pos_hint: {\"center_x\": .5, \"center_y\": .5} <\/code><\/pre>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5ad\/d79\/120\/5add79120d1dc1070b1a1a06790c5179.gif\" width=\"432\" height=\"270\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5ad\/d79\/120\/5add79120d1dc1070b1a1a06790c5179.gif\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041e\u0442\u043b\u0438\u0447\u043d\u043e! \u0412\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043e\u0431 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0435 \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f. \u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043f\u0430\u043a\u0435\u0442 <em>SliderMenuScreen<\/em>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u0444\u0430\u0439\u043b <em>kv<\/em> \u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c <em>GUI<\/em> \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 <em>KV Language<\/em>:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/304\/5d5\/cb5\/3045d5cb500fcaf3c136bafeecdc80ba.png\" width=\"772\" height=\"261\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/304\/5d5\/cb5\/3045d5cb500fcaf3c136bafeecdc80ba.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u043b\u0430\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f \u043a \u0432\u0438\u0434\u0436\u0435\u0442\u0435 <em>MDCarousel<\/em>. \u0414\u043b\u044f \u044d\u0442\u0438\u0445 \u0446\u0435\u043b\u0435\u0439 \u044f \u0441\u043e\u0437\u0434\u0430\u044e \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u043f\u0430\u043a\u0435\u0442\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0430\u043a\u0435\u0442 \u0441 \u0438\u043c\u0435\u043d\u0435\u043c <em>components<\/em> \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u0432\u0441\u0435 \u0432\u0438\u0434\u0436\u0435\u0442\u044b, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u0435\u0441\u044f \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u043c \u044d\u043a\u0440\u0430\u043d\u0435:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c02\/d4b\/887\/c02d4b8874bf9f77d9fd91a27021f687.png\" width=\"772\" height=\"303\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c02\/d4b\/887\/c02d4b8874bf9f77d9fd91a27021f687.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u043f\u0430\u043a\u0435\u0442\u043e\u043c \u0441 \u0431\u0430\u0437\u043e\u0432\u044b\u043c <em>Python<\/em> \u043a\u043b\u0430\u0441\u0441\u043e\u043c \u0438 \u0435\u0433\u043e <em>kv<\/em> \u043f\u0440\u0430\u0432\u0438\u043b\u043e\u043c. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <em>card<\/em>:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1cc\/270\/2ff\/1cc2702fffd1e06a3d1a8d2d33fbb78e.png\" width=\"772\" height=\"382\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/1cc\/270\/2ff\/1cc2702fffd1e06a3d1a8d2d33fbb78e.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u0431\u0430\u0437\u043e\u0432\u044b\u0445 <em>Python<\/em> \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0432 \u043c\u043e\u0434\u0443\u043b\u0435 <em>card.py. <\/em>\u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0441\u043b\u0430\u0439\u0434 \u043d\u0430<em> <\/em>\u043e\u0441\u043d\u043e\u0432\u0435 \u0432\u0438\u0434\u0436\u0435\u0442\u0430 <em>MDCard<\/em>:<\/p>\n<pre><code class=\"python\">from kivymd.uix.card import MDCard   class PizzaCard(MDCard):     \"\"\"The class implements the slide card.\"\"\"<\/code><\/pre>\n<p>\u041e\u043f\u0438\u0448\u0435\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0438 <em>PizzaCard <\/em>\u0432 \u043f\u0440\u0430\u0432\u0438\u043b\u0435 <em>kv<\/em> \u0444\u0430\u0439\u043b\u0430 <em>card.kv<\/em>:<\/p>\n<pre><code class=\"yaml\">&lt;PizzaCard>     size_hint: .9, .95     pos_hint: {\"center_x\": .5, \"center_y\": .5}     radius: 20     elevation: 24<\/code><\/pre>\n<p>\u041c\u044b \u0434\u0430\u043b\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0438: \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0430 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u0434\u043b\u044f \u0448\u0438\u0440\u0438\u043d\u044b \u0438 \u0432\u044b\u0441\u043e\u0442\u044b (\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043e\u0442 0 \u0434\u043e 1, \u0447\u0442\u043e \u044d\u043a\u0432\u0438\u0432\u0430\u043b\u0435\u043d\u0442\u043d\u043e 0-100%), \u043f\u043e\u0437\u0438\u0446\u0438\u044f \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0438 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435 (\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043e\u0442 0 \u0434\u043e 1, \u0447\u0442\u043e \u044d\u043a\u0432\u0438\u0432\u0430\u043b\u0435\u043d\u0442\u043d\u043e 0-100%), \u0440\u0430\u0434\u0438\u0443\u0441 \u043e\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u0438\u044f \u0443\u0433\u043e\u043b\u043e\u0432 \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0442\u0435\u043d\u0438 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0438. \u0422\u0435\u043f\u0435\u0440\u044c, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0443 \u043d\u0430\u0441 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435, \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u0431\u0443\u0434\u0435\u0442 \u043d\u0435 \u043e\u0434\u043d\u0430, \u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u0440\u0442\u043e\u0447\u0435\u043a, \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0438\u0445 \u0432 <em>Python<\/em> \u043a\u043e\u0434\u0435 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0432 \u0432\u0438\u0434\u0436\u0435\u0442 <em>MDCarousel<\/em>. \u041e\u0442\u043a\u0440\u043e\u0435\u043c \u043a\u043b\u0430\u0441\u0441 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f <em>View.SliderMenuScreen.slider_menu_screen.<\/em>SliderMenuScreenView \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0434\u0432\u0430 \u043c\u0435\u0442\u043e\u0434\u0430:<\/p>\n<pre><code class=\"python\">from View.SliderMenuScreen.components import PizzaCard   class SliderMenuScreenView(MDScreen, Observer):     def on_enter(self):         self.ids.carousel.clear_widgets()         self.generate_and_added_slides_to_carousel()      def generate_and_added_slides_to_carousel(self):         for i in range(3):             card = PizzaCard()             self.ids.carousel.add_widget(card)<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e\u0441\u0442\u0438 \u0432\u0441\u0435, \u0447\u0442\u043e \u043c\u044b \u0440\u0430\u043d\u0435\u0435 \u0443\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u043b\u0438 \u0432 \u044d\u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441, \u044f \u043d\u0435 \u0431\u0443\u0434\u0443 \u0434\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0437 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0432 \u043f\u0440\u0438\u043c\u0435\u0440. \u042d\u0442\u043e \u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0442 \u0438 \u043c\u0435\u0441\u0442\u043e \u0438 \u0441\u0440\u0430\u0437\u0443 \u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438\/\u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0438 \u0432 \u043a\u043b\u0430\u0441\u0441\u0435. \u0414\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u043c\u044b (\u0442\u043e\u0447\u043d\u0435\u0435, \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b\u0438) \u043c\u0435\u0442\u043e\u0434 <em>on_enter, <\/em>\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u044d\u043a\u0440\u0430\u043d \u0441\u0442\u0430\u043d\u0435\u0442 \u0432\u0438\u0434\u0435\u043d \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e. \u0412 \u044d\u0442\u043e\u043c \u043c\u0435\u0442\u043e\u0434\u0435 \u043c\u044b \u0447\u0435\u0440\u0435\u0437 <em>id <\/em>\u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043e\u0431\u044a\u0435\u043a\u0442 \u0432\u0438\u0434\u0436\u0435\u0442\u0430 <em>MDCarousel<\/em>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443 \u043d\u0430\u0441 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 <em>kv<\/em> \u0444\u0430\u0439\u043b\u0435, \u043e\u0447\u0438\u0441\u0442\u0438\u043b\u0438 <em>MDCarousel <\/em> \u043e\u0442 \u0432\u0441\u0435\u0445 \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432 \u0438 \u0432\u044b\u0437\u0432\u0430\u043b\u0438 \u043c\u0435\u0442\u043e\u0434 <em>generate_and_added_slides_to_carousel<\/em> \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043b\u0430\u0439\u0434\u043e\u0432 \u0432 <em>MDCarousel. \u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043f\u0440\u0438 \u043f\u0443\u0441\u0442\u044b\u0445 \u0441\u043b\u0430\u0439\u0434\u0430:<\/em><\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/89e\/f3c\/5ad\/89ef3c5ad641316c3c13ef288b8aeb2e.gif\" width=\"448\" height=\"744\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/89e\/f3c\/5ad\/89ef3c5ad641316c3c13ef288b8aeb2e.gif\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0432 \u0441\u043b\u0430\u0439\u0434, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c <em>json<\/em> \u0444\u0430\u0439\u043b \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f\u043c\u0438 \u0441\u043e\u0440\u0442\u043e\u0432 \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0439 \u043f\u0438\u0446\u0446\u044b:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ce2\/ddf\/a3c\/ce2ddfa3c49e45096419c683f73609f6.png\" width=\"733\" height=\"223\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ce2\/ddf\/a3c\/ce2ddfa3c49e45096419c683f73609f6.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0424\u0430\u0439\u043b <em>pizza-description.json<\/em>:<\/p>\n<pre><code class=\"json\">{   \"Mexican\":       [           \"Olive oil, bacon, pepperoni sausages, red onion, cherry tomatoes, mozzarella cheese, chicken fillet, barbecue sauce, minced beef, pickled hot peppers\",           \"$3.50\"       ],   \"Contandino\":       [           \"Eggplant, green onion, tomato, parmesan cheese, mozzarella cheese, chicken fillet, zucchini\",           \"$4.75\"       ],   \"Munich\":       [           \"Olive oil, salami, hunting sausages, pepperoni sausages, homemade sausages, red onion, parsley, mozzarella cheese, sweet and sour sauce\",           \"$2.99\"       ] }<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0444\u0430\u0439\u043b <em>pizza-description.json <\/em>\u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u0445\u0440\u0430\u043d\u0438\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043c\u044b \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0435\u043c \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043d\u0430\u0448\u0435\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u0438 \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0438\u043c\u0438 \u0432 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0438.<\/p>\n<p><em>Model.slider_menu_screen.SliderMenuScreenModel:<\/em><\/p>\n<pre><code class=\"python\">import json from pathlib import Path  BASE_DIR = Path(__file__).resolve().parent.parent DATA_DIR = BASE_DIR.joinpath(\"assets\", \"data\")   class SliderMenuScreenModel:     def __init__(self):         self.pizza_description = {}         path_to_pizza_description = DATA_DIR.joinpath(             DATA_DIR, \"pizza-description.json\"         )         if path_to_pizza_description.exists():             with open(path_to_pizza_description) as json_file:                 self.pizza_description = json.loads(json_file.read())         self._observers = []<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u043b\u0430\u0439\u0434\u044b \u0441 \u0431\u043e\u043b\u0435\u0435 \u043c\u0435\u043d\u0435\u0435 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u0441\u043b\u0430\u0439\u0434 \u043f\u0435\u0440\u0432\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 &#8212; \u0444\u043e\u043d\u043e\u0432\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 <em>View.SliderMenuScreen.components.card.card.PizzaCard <\/em>\u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u043b\u0435 (<em>path_to_bg_image<\/em>), \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 &#8212; \u043f\u0443\u0442\u044c \u043a \u0444\u043e\u043d\u043e\u0432\u043e\u043c\u0443 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044e \u0441\u043b\u0430\u0439\u0434\u0430:<\/p>\n<pre><code class=\"python\">from kivy.properties import StringProperty  from kivymd.uix.card import MDCard   class PizzaCard(MDCard):     path_to_bg_image = StringProperty()<\/code><\/pre>\n<p>&#8230; \u0438 \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0432\u0438\u0434\u0436\u0435\u0442 \u0444\u043e\u043d\u043e\u0432\u043e\u0433\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u0435 \u0432 <em>kv<\/em> \u0444\u0430\u0439\u043b\u0435.<\/p>\n<p><em>View\/SliderMenuScreen\/components\/card\/card.kv:<\/em><\/p>\n<pre><code class=\"yaml\">&lt;PizzaCard>     size_hint: .9, .95     pos_hint: {\"center_x\": .5, \"center_y\": .5}     radius: 20     elevation: 24      MDRelativeLayout:          FitImage:             id: image_bg             source: root.path_to_bg_image             size_hint: None, .8             width: root.width             y: root.height - self.height<\/code><\/pre>\n<p>\u0412 \u043f\u0440\u0430\u0432\u0438\u043b\u0435 <em>PizzaCard<\/em> \u0444\u043e\u043d\u043e\u0432\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0435 \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u043c <em>FitImage<\/em>, \u043a\u0430\u043a \u0438 \u0432\u0441\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0432\u0438\u0434\u0436\u0435\u0442\u044b, \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f \u0432 \u043c\u0430\u043a\u0435\u0442\u0435 <em>MDRelativeLayout<\/em>. \u042d\u0442\u043e\u0442 \u043c\u0430\u043a\u0435\u0442 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u0442\u044c \u0432\u0438\u0434\u0436\u0435\u0442\u044b \u043e\u0434\u0438\u043d \u043d\u0430\u0434 \u0434\u0440\u0443\u0433\u0438\u043c \u0438, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0432 \u0441\u043b\u0430\u0439\u0434\u0435 \u0443 \u043d\u0430\u0441 \u043d\u0430\u0434 \u0444\u043e\u043d\u043e\u0432\u044b\u043c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c \u0435\u0449\u0435 \u0431\u0443\u0434\u0443\u0442 &#171;\u043b\u0435\u0442\u0430\u0442\u044c&#187; \u043c\u0435\u0442\u043a\u0438 \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u043f\u0438\u0446\u0446\u044b, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441\u0430\u043c\u043e\u0439 \u043f\u0438\u0446\u0446\u044b, \u0442\u043e \u043c\u0430\u043a\u0435\u0442 <em>MDRelativeLayout \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0438. <\/em>\u0412\u0438\u0434\u0436\u0435\u0442 \u0436\u0435 FitImage \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0431\u0435\u0437 \u0438\u0441\u043a\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u043f\u043e\u0440\u0446\u0438\u0439 \u0432 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440.<\/p>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u0443\u0436\u0435 \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u0430\u0442\u044c \u0446\u0438\u043a\u043b \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u043b\u0430\u0439\u0434\u043e\u0432 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u043e\u0434\u0435\u043b\u0438 \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 <em>generate_and_added_slides_to_carousel <\/em>\u0432 \u043a\u043b\u0430\u0441\u0441\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"python\">import os   class SliderMenuScreenView(MDScreen, Observer):     def generate_and_added_slides_to_carousel(self):         for pizza_name in self.model.pizza_description.keys():             card = PizzaCard(                 path_to_bg_image=os.path.join(                     \"assets\", \"images\", f\"{pizza_name}-bg.png\"                 )             )             self.ids.carousel.add_widget(card)<\/code><\/pre>\n<p>\u042f \u043d\u0430\u043c\u0435\u0440\u0435\u043d\u043d\u043e \u0434\u0430\u043b \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u043c \u0438\u043c\u0435\u043d\u0430 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0439 \u0441\u043e\u0440\u0442\u043e\u0432 \u043f\u0438\u0446\u0446\u044b \u0438\u0437 \u0444\u0430\u043b\u0430 <em>pizza-description.json, <\/em>\u0447\u0442\u043e\u0431\u044b \u0432 \u043a\u043e\u0434\u0435 \u043e\u0441\u043e\u0431\u043e \u043d\u0435 \u043f\u0430\u0440\u0438\u0442\u0441\u044f \u0441 \u043f\u0443\u0442\u044f\u043c\u0438 \u043a \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u043c:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/149\/afe\/c60\/149afec60ec39cf68e1a16855f633820.png\" width=\"729\" height=\"223\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/149\/afe\/c60\/149afec60ec39cf68e1a16855f633820.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441\u043b\u0430\u0439\u0434\u044b \u0432\u044b\u0433\u043b\u044f\u0434\u044f\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/15a\/b17\/55c\/15ab1755c5666a15441e2a41f36b21df.gif\" width=\"446\" height=\"738\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/15a\/b17\/55c\/15ab1755c5666a15441e2a41f36b21df.gif\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041a\u0430\u043a \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c <em>parallax<\/em> \u044d\u0444\u0444\u0435\u043a\u0442 \u043a \u0444\u043e\u043d\u043e\u0432\u043e\u043c\u0443 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044e \u0441\u043b\u0430\u0439\u0434\u0430? \u041a\u0430\u043a\u043e\u0433\u043e-\u0442\u043e \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0433\u043e <em>API<\/em> \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0438 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a <em>Kivy<\/em>, \u043d\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 <em>KivyMD<\/em> \u043f\u043e\u043a\u0430 \u043d\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 (<em>ParallaxContainer<\/em> \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0430 <em>MDCarousel<\/em> \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 <em>KivyMD<\/em> \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 \u0441\u0442\u0430\u0434\u0438\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438). \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0432\u0441\u0435 \u0441\u0430\u043c\u0438. \u041f\u043b\u0430\u043d \u0442\u0430\u043a\u043e\u0439:<\/p>\n<ol>\n<li>\n<p>\u0423\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u044c \u0448\u0438\u0440\u0438\u043d\u0443 \u0444\u043e\u043d\u043e\u0432\u043e\u0433\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u044f parallax \u0441\u0434\u0432\u0438\u0433\u0430<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u043a \u043a\u043b\u0430\u0441\u0441\u0443 <em>PizzaCard <\/em>\u0442\u0440\u0430\u0444\u0430\u0440\u0435\u0442<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0441\u043b\u0430\u0439\u0434\u043e\u0432<\/p>\n<p>\u25a1 \u043b\u043e\u043a\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0441\u043b\u0430\u0439\u0434\u043e\u0432<\/p>\n<p>\u25a1 \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c <em>offset<\/em> \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441\u043b\u0430\u0439\u0434\u0430 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0448\u0438\u0440\u0438\u043d\u044b \u044d\u043a\u0440\u0430\u043d\u0430<\/p>\n<p>\u25a1 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\/\u0434\u0435\u043a\u0440\u0435\u043c\u0435\u043d\u0442 <em>offset<\/em> \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0448\u0438\u0440\u0438\u043d\u044b \u0444\u043e\u043d\u043e\u0432\u043e\u0433\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f <\/p>\n<\/li>\n<\/ol>\n<p>\u0412\u0438\u0434\u0436\u0435\u0442 <em>MDCarousel<\/em>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u044b \u043d\u0430\u0448\u0438 \u0441\u043b\u0430\u0439\u0434\u044b, \u0438\u043c\u0435\u0435\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 <em>on_slide_progress<\/em>, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u043e\u0435 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0440\u0438 \u0441\u0432\u0430\u0439\u043f\u0435 \u0441\u043b\u0430\u0439\u0434\u043e\u0432. \u0414\u043b\u044f \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043d\u0430\u0437\u043d\u0430\u0447\u0438\u0442\u044c \u044d\u0442\u043e\u043c\u0443 \u0441\u043e\u0431\u044b\u0442\u0438\u044e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0434\u0432\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430: \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 <em>MDCarousel \u0438 offset \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u043b\u0430\u0439\u0434\u0430<\/em>. \u041a\u0430\u043a \u043c\u044b \u043f\u043e\u043c\u043d\u0438\u043c, \u0432\u0441\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0432 \u043d\u0430\u0448\u0435\u043c \u043c\u0438\u043d\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043a\u043b\u0430\u0441\u0441 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u0443\u0436\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0432 \u043a\u043b\u0430\u0441\u0441 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 <em>Controller.slider_menu_screen.SliderMenuScreenController:<\/em><\/p>\n<pre><code class=\"python\">class SliderMenuScreenController:     def on_slide_progress(self, instance_carousel, offset_value):         \"\"\"         Called when the user swipes on the screen (the moment the slides move).         \"\"\"          self.view.do_animation_card_content(instance_carousel, offset_value)<\/code><\/pre>\n<p>\u0410\u0442\u0440\u0438\u0431\u0443\u0442 <em>self.view<\/em>, \u043a\u0430\u043a \u0432\u044b \u0443\u0436\u0435 \u043f\u043e\u043d\u044f\u043b\u0438, \u044d\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f. \u0422\u0435\u043f\u0435\u0440\u044c \u0432 \u043f\u0440\u0430\u0432\u0438\u043b\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f <em>SliderMenuScreen<\/em> \u0432 \u0444\u0430\u0439\u043b\u0435 <em>View.SliderMenuScreen.slider_menu_screen.kv<\/em>  \u043f\u0440\u0438\u0441\u0432\u043e\u0438\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u044e <em>on_slide_progress <\/em>\u043c\u0435\u0442\u043e\u0434 <em>on_slide_progress, <\/em>\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430:<\/p>\n<pre><code class=\"yaml\">&lt;SliderMenuScreenView>      MDCarousel:         id: carousel         on_slide_progress: root.controller.on_slide_progress(*args)<\/code><\/pre>\n<p>\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 <em>root<\/em> \u0432 <em>kv<\/em> \u0444\u0430\u0439\u043b\u0430\u0445 \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u0441\u044b\u043b\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u0432\u043e\u0439 \u0431\u0430\u0437\u043e\u0432\u044b\u0439 <em>Python<\/em> \u043a\u043b\u0430\u0441\u0441. \u0417\u0434\u0435\u0441\u044c \u0431\u0430\u0437\u043e\u0432\u044b\u0439 <em>Python<\/em> \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u0430 <em>SliderMenuScreenView<\/em> \u044d\u0442\u043e <em>View.SliderMenuScreen.slider_menu_screen.SliderMenuScreenView<\/em>. \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u044d\u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441 \u043d\u043e\u0432\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 <em>do_animation_card_content, <\/em>\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0438\u0437 \u043a\u043b\u0430\u0441\u0441\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u0438 \u0434\u0432\u0430 \u043d\u043e\u0432\u044b\u0439 \u043f\u043e\u043b\u044f &#8212; <em>parallax_step (<\/em>\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u0434\u0432\u0438\u0433\u0430 \u0444\u043e\u043d\u043e\u0432\u043e\u0433\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0441\u043b\u0430\u0439\u0434\u0430<em>) <\/em>\u0438 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043b\u0430\u0439\u0434\u0430 &#8212; <em>_cursor_pos_x<\/em>. \u0422\u0430\u043a\u0436\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u043c\u0435\u0442\u043e\u0434 <em>get_direction_swipe, <\/em>\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0443 \u0441 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u0441\u0432\u0430\u0439\u043f\u0430 \u0441\u043b\u0430\u0439\u0434\u0430 (&#171;left\/right&#187;):<\/p>\n<pre><code class=\"python\">class SliderMenuScreenView(MDScreen, Observer):     # The value to shift the background image for the slide.     parallax_step = NumericProperty(50)      _cursor_pos_x = 0      def on_slide_progress(self, instance_carousel, offset_value):         \"\"\"         Called when the user swipes on the screen (the moment the slides move).         \"\"\"      def get_direction_swipe(self, offset_value):         if self._cursor_pos_x > offset_value:             direction = \"left\"         else:             direction = \"right\"         return direction<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0435\u0434\u0430\u0434\u0438\u043c \u043a\u043b\u0430\u0441\u0441\u0443 \u0441\u043b\u0430\u0439\u0434\u0430 \u043e\u0431\u044a\u0435\u043a\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0438\u043c\u0435\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0443 <em>parallax_step <\/em>\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0443 <em>MDCarousel <\/em>\u0432 \u043f\u0440\u0430\u0432\u0438\u043b\u0435 <em>PizzaCard <\/em>\u0432 \u0444\u0430\u0439\u043b\u0435 <em>View.SliderMenuScreen.components.card.card.kv:<\/em><\/p>\n<pre><code class=\"yaml\">&lt;PizzaCard>     size_hint: .9, .95     pos_hint: {\"center_x\": .5, \"center_y\": .5}     radius: 20     elevation: 24      MDRelativeLayout:          FitImage:             id: image_bg             source: root.path_to_bg_image             size_hint: None, .8             x: -root.view.parallax_step             y: root.height - self.height             width:                 root.width + \\                 root.view.parallax_step * len(root.view.ids.carousel.slides)<\/code><\/pre>\n<p>\u0418\u0437 \u043d\u043e\u0432\u043e\u0433\u043e: \u043c\u044b \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u043b\u0438 \u0448\u0438\u0440\u0438\u043d\u0443 \u0444\u043e\u043d\u043e\u0432\u043e\u0433\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441\u043b\u0430\u0439\u0434\u0430 (\u0443\u043c\u043d\u043e\u0436\u0438\u043b\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u0434\u0432\u0438\u0433\u0430 \u0444\u043e\u043d\u043e\u0432\u043e\u0433\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043b\u0430\u0439\u0434\u043e\u0432) \u0438 \u0441\u0434\u0432\u0438\u043d\u0443\u043b\u0438 \u0444\u043e\u043d\u043e\u0432\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 50 \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439 \u0432\u043b\u0435\u0432\u043e (\u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <em>parallax_step<\/em>):<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/826\/1f2\/743\/8261f274308b444c0f08818bdc225e5e.png\" width=\"447\" height=\"582\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/826\/1f2\/743\/8261f274308b444c0f08818bdc225e5e.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432 \u0431\u0430\u0437\u043e\u0432\u043e\u043c <em>Python<\/em> \u043a\u043b\u0430\u0441\u0441\u0435 <em>PizzaCard<\/em> \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u043e\u043b\u0435 <em>view<\/em> &#8212; \u043e\u0431\u044a\u0435\u043a\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u044d\u043a\u0440\u0430\u043d\u0430 <em>SliderMenuScreenView<\/em>:<\/p>\n<pre><code class=\"python\">from kivy.properties import ObjectProperty   class PizzaCard(MDCard):     # View.SliderMenuScreen.slider_menu_screen.SliderMenuScreenView class     view = ObjectProperty()<\/code><\/pre>\n<p>\u041f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0441\u043b\u0430\u0439\u0434\u043e\u0432 \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 <em>generate_and_added_slides_to_carousel<\/em> \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f <em>SliderMenuScreenView<\/em> \u043f\u0435\u0440\u0435\u0434\u0430\u043c \u043a\u043b\u0430\u0441\u0441\u0443 <em>PizzaCard <\/em>\u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442<em> view:<\/em><\/p>\n<pre><code class=\"python\">class SliderMenuScreenView(MDScreen, Observer):     def generate_and_added_slides_to_carousel(self):         for pizza_name in self.model.pizza_description.keys():             card = PizzaCard(                 path_to_bg_image=os.path.join(                     \"assets\", \"images\", f\"{pizza_name}-bg.png\"                 ),                 view=self,             )             self.ids.carousel.add_widget(card)<\/code><\/pre>\n<p>\u0423\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a\u043e\u0434 \u0432 \u043c\u0435\u0442\u043e\u0434 <em>do_animation_card_content<\/em> \u043a\u043b\u0430\u0441\u0441\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f <em>SliderMenuScreenView, <\/em>\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c <em>parallax<\/em> \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u043c:<\/p>\n<pre><code class=\"python\">class SliderMenuScreenView(MDScreen, Observer):     def do_animation_card_content(self, instance_carousel, offset_value):         direction = self.get_direction_swipe(offset_value)         self._cursor_pos_x = offset_value         offset_value = max(min(abs(offset_value) \/ Window.width, 1), 0)          for instance_slide in [             instance_carousel.current_slide,             instance_carousel.next_slide,             instance_carousel.previous_slide         ]:             if instance_slide:                 if direction == \"left\":                     instance_slide.ids.image_bg.x -= offset_value                 elif direction == \"right\":                     instance_slide.ids.image_bg.x += offset_value<\/code><\/pre>\n<p>\u0412\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0432\u0430\u0439\u043f\u0430, <em>offset_value<\/em> \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u0434\u0432\u0438\u0433\u0430 \u0441\u043b\u0430\u0439\u0434\u0430 (\u043e\u0442 0 \u0434\u043e 1) \u0438, \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0432\u0430\u0439\u043f\u0430 \u0434\u0435\u043b\u0430\u0435\u043c \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\/\u0434\u0435\u043a\u0440\u0435\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0444\u043e\u043d\u043e\u0432\u043e\u0433\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u043e \u043e\u0441\u0438 <em>x <\/em>\u043f\u0440\u043e\u0445\u043e\u0434\u044f \u0432 \u0446\u0438\u043a\u043b\u0435 \u043f\u043e \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c\u0443\/\u0442\u0435\u043a\u0443\u0449\u0435\u043c\u0443\/\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u0441\u043b\u0430\u0439\u0434\u0430\u043c. \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u043d\u0435 \u043e\u0447\u0435\u043d\u044c:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/41a\/3ae\/8db\/41a3ae8dbca200fce5808d2bb1397174.gif\" width=\"444\" height=\"746\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/41a\/3ae\/8db\/41a3ae8dbca200fce5808d2bb1397174.gif\"\/><figcaption><\/figcaption><\/figure>\n<p>\u042d\u0442\u043e \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043d\u0430\u043c \u0435\u0449\u0435 \u043d\u0443\u0436\u043d\u043e \u0443\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u0442\u0440\u0430\u0444\u0430\u0440\u0435\u0442\u0430 (<em>kivymd.uix.templates.StencilWidget<\/em>) \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0430 <em>PizzaCard:<\/em><\/p>\n<pre><code class=\"python\">from kivymd.uix.templates import StencilWidget   class PizzaCard(MDCard, StencilWidget):     [...]<\/code><\/pre>\n<p>\u0423\u0436\u0435 \u043b\u0443\u0447\u0448\u0435:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ebc\/02d\/572\/ebc02d5722e2424fb0afdecd3523f5e6.gif\" width=\"444\" height=\"746\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ebc\/02d\/572\/ebc02d5722e2424fb0afdecd3523f5e6.gif\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041d\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043c\u043e\u0434\u0435\u043b\u044c, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435, \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441\u043b\u0430\u0439\u0434\u0430 \u0438\u043c\u0435\u044e\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<details class=\"spoiler\">\n<summary>\u041c\u043e\u0434\u0435\u043b\u044c<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import json from pathlib import Path  BASE_DIR = Path(__file__).resolve().parent.parent DATA_DIR = BASE_DIR.joinpath(\"assets\", \"data\")   class SliderMenuScreenModel:     def __init__(self):         self.pizza_description = {}         path_to_pizza_description = DATA_DIR.joinpath(             DATA_DIR, \"pizza-description.json\"         )         if path_to_pizza_description.exists():             with open(path_to_pizza_description) as json_file:                 self.pizza_description = json.loads(json_file.read())         self._observers = []      def notify_observers(self):         for observer in self._observers:             observer.model_is_changed()      def add_observer(self, observer):         self._observers.append(observer)      def remove_observer(self, observer):         self._observers.remove(observer)<\/code><\/pre>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import os  from kivy.core.window import Window from kivy.properties import ObjectProperty, NumericProperty  from kivymd.uix.screen import MDScreen  from Utility.observer import Observer from View.SliderMenuScreen.components import PizzaCard   class SliderMenuScreenView(MDScreen, Observer):     controller = ObjectProperty()     model = ObjectProperty()     manager_screens = ObjectProperty()     parallax_step = NumericProperty(50)      _cursor_pos_x = 0      def __init__(self, **kw):         super().__init__(**kw)         self.model.add_observer(self)      def on_enter(self):         self.ids.carousel.clear_widgets()         self.generate_and_added_slides_to_carousel()      def generate_and_added_slides_to_carousel(self):         for pizza_name in self.model.pizza_description.keys():             card = PizzaCard(                 path_to_bg_image=os.path.join(                     \"assets\", \"images\", f\"{pizza_name}-bg.png\"                 ),                 view=self,             )             self.ids.carousel.add_widget(card)      def do_animation_card_content(self, instance_carousel, offset_value):         direction = self.get_direction_swipe(offset_value)         self._cursor_pos_x = offset_value         offset_value = max(min(abs(offset_value) \/ Window.width, 1), 0)          for instance_slide in [             instance_carousel.current_slide,             instance_carousel.next_slide,             instance_carousel.previous_slide         ]:             if instance_slide:                 if direction == \"left\":                     instance_slide.ids.image_bg.x -= offset_value                 elif direction == \"right\":                     instance_slide.ids.image_bg.x += offset_value      def get_direction_swipe(self, offset_value):         if self._cursor_pos_x > offset_value:             direction = \"left\"         else:             direction = \"right\"         return direction      def model_is_changed(self):         pass<\/code><\/pre>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u0435\u0440<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">from View.SliderMenuScreen.slider_menu_screen import SliderMenuScreenView   class SliderMenuScreenController:     def __init__(self, model):         self.model = model         self.view = SliderMenuScreenView(controller=self, model=self.model)      def on_slide_progress(self, instance_carousel, offset_value):         self.view.do_animation_card_content(instance_carousel, offset_value)      def get_view(self):         return self.view<\/code><\/pre>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0421\u043b\u0430\u0439\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">from kivy.properties import StringProperty, ObjectProperty  from kivymd.uix.card import MDCard from kivymd.uix.templates import StencilWidget   class PizzaCard(MDCard, StencilWidget):     path_to_bg_image = StringProperty()     view = ObjectProperty()<\/code><\/pre>\n<pre><code class=\"yaml\">&lt;PizzaCard>     size_hint: .9, .95     pos_hint: {\"center_x\": .5, \"center_y\": .5}     radius: 20     elevation: 24      MDRelativeLayout:          FitImage:             id: image_bg             source: root.path_to_bg_image             size_hint: None, .8             x: -root.view.parallax_step             y: root.height - self.height             width:                 root.width + \\                 root.view.parallax_step * len(root.view.ids.carousel.slides)<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u041d\u0443 \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435, \u0447\u0442\u043e \u043d\u0430\u043c \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c, &#8212; \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u0441\u043b\u0430\u0439\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0441\u043e\u0440\u0442\u043e\u0432 \u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u0438\u0446\u0446\u044b:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/5cf\/5ac\/4d0\/5cf5ac4d069b2739fdbd550463020ba9.png\" width=\"902\" height=\"760\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5cf\/5ac\/4d0\/5cf5ac4d069b2739fdbd550463020ba9.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0417\u0434\u0435\u0441\u044c \u0443\u0436\u0435 \u0432\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e. \u041c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0438\u0434\u0436\u0435\u0442 \u0434\u043b\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u0438\u0446\u0446\u044b, \u0432\u0438\u0434\u0436\u0435\u0442 \u0434\u043b\u044f \u043f\u043e\u0434\u043f\u0438\u0441\u0438 \u0441\u043e\u0440\u0442\u043e\u0432 \u043f\u0438\u0446\u0446\u044b \u0432 \u0443\u0436\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0435 \u043d\u0430\u043c\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u043e <em>PizzaCard <\/em>\u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u044d\u0442\u0438\u0445 \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432 (\u043f\u043e\u0437\u0438\u0446\u0438\u044e \u043f\u043e \u043e\u0441\u0438 <em>x<\/em> \u0434\u043b\u044f \u043c\u0435\u0442\u043e\u043a \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f <em>scale<\/em> \u0438 <em>angle,\u043c\u0430\u0441\u0448\u0442\u0430\u0431 \u0438 \u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435,<\/em> \u0434\u043b\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f) \u0432 \u0442\u043e\u043c \u0436\u0435 \u043c\u0435\u0442\u043e\u0434\u0435 \u043a\u043b\u0430\u0441\u0441\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 <em>parallax<\/em> \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u043c. \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 <em>PizzaImage<\/em> \u0438 \u043e\u0434\u043d\u043e\u0438\u043c\u0435\u043d\u043d\u043e\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0434\u043b\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u0438\u0446\u0446\u044b \u0432 \u043c\u043e\u0434\u0443\u043b\u0435 <em>View\/SliderMenuScreen\/components\/card\/card.py \u0438 <\/em>\u0444\u0430\u0439\u043b\u0435 <em>View\/SliderMenuScreen\/components\/card\/card.kv:<\/em><\/p>\n<pre><code class=\"python\">from kivy.properties import StringProperty, NumericProperty from kivy.uix.image import Image  from kivymd.uix.card import MDCard from kivymd.uix.templates import StencilWidget, ScaleWidget, RotateWidget   class PizzaImage(Image, ScaleWidget, RotateWidget):     \"\"\"The class implements the pizza image in the slide card.\"\"\"      angle = NumericProperty(-45)     scale = NumericProperty(1)   class PizzaCard(MDCard, StencilWidget):     pizza_image = StringProperty()     pizza_name = StringProperty()     pizza_description = StringProperty()     pizza_cost = StringProperty()<\/code><\/pre>\n<p>\u041f\u043e\u043c\u0438\u043c\u043e \u043a\u043b\u0430\u0441\u0441\u0430 <em>Image<\/em>, \u043c\u044b \u0443\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043b\u0438 \u043a\u043b\u0430\u0441\u0441 <em>PizzaImage<\/em> \u043e\u0442 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 <em>ScaleWidge<\/em> \u0438 <em>RotateWidget<\/em>, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435\u043c \u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u043e\u043c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u0438\u0446\u0446\u044b.<\/p>\n<pre><code class=\"yaml\">&lt;PizzaImage>     scale_value_x: self.scale     scale_value_y: self.scale     rotate_value_angle: self.angle     rotate_value_axis: (0, 0, 1)<\/code><\/pre>\n<p>\u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0441 \u0444\u043e\u043d\u043e\u0432\u044b\u043c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c \u0441\u043b\u0430\u0439\u0434\u0430, \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c \u043f\u0438\u0446\u0446\u044b, \u043c\u0435\u0442\u043a\u0430\u043c\u0438 \u0441\u043e\u0440\u0442\u043e\u0432 \u043f\u0438\u0446\u0446\u044b \u0438 \u043a\u043d\u043e\u043f\u043a\u043e\u0439 \u0446\u0435\u043d\u044b \u0432 \u0444\u0430\u0439\u043b\u0435 <em>View\/SliderMenuScreen\/components\/card\/card.kv:<\/em><\/p>\n<pre><code class=\"yaml\">&lt;PizzaImage>     scale_value_x: self.scale     scale_value_y: self.scale     rotate_value_angle: self.angle     rotate_value_axis: (0, 0, 1)   &lt;PizzaCard>     size_hint: .9, .95     pos_hint: {\"center_x\": .5, \"center_y\": .5}     radius: 20     elevation: 24      MDRelativeLayout:          FitImage:             id: image_bg             source: root.path_to_bg_image             size_hint: None, .8             x: -root.view.parallax_step             y: root.height - self.height             width:                 root.width + \\                 root.view.parallax_step * len(root.view.ids.carousel.slides)          PizzaImage:             id: pizza_image             source: root.pizza_image             size_hint: None, None             size: root.width \/ 1.2, root.width \/ 1.2             pos_hint: {\"center_x\": .5}             y: image_bg.y - dp(24)          MDLabel:             id: pizza_name             text: root.pizza_name             bold: True             adaptive_size: True             font_style: \"H4\"             font_name: \"assets\/font\/hot-pizza.ttf\"             color: 1, 1, 1, 1             x: dp(20)             y: root.height - self.height - dp(20)          MDLabel:             text: root.pizza_description             adaptive_size: True             text_size: root.width - (root.width * dp(30) \/ 100), None             color: 1, 1, 1, 1             font_name: \"assets\/font\/hot-pizza.ttf\"             x: pizza_name.x             y: pizza_name.y - self.height - dp(20)          MDRoundFlatButton:             text: root.pizza_cost             size_hint: .3, .065             pos_hint: {\"center_x\": .5}             y: \"18dp\"             line_width: 2             font_name: \"assets\/font\/hot-pizza.ttf\"             font_size: \"24sp\"<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0431\u043e\u043b\u0435\u0435 \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e, \u0442\u043e \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/faa\/e1a\/390\/faae1a390e812a08fe2e544958cf0c5c.png\" width=\"613\" height=\"504\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/faa\/e1a\/390\/faae1a390e812a08fe2e544958cf0c5c.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u043d\u043e\u0432\u044b\u0435 \u043f\u043e\u043b\u044f \u0432 \u043a\u043b\u0430\u0441\u0441 <em>PizzaCard<\/em> \u0434\u043b\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u0438\u0446\u0446\u044b, \u043c\u0435\u0442\u043e\u043a \u0438 \u043f\u0440., \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <em>generate_and_added_slides_to_carousel<\/em> \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"python\">class SliderMenuScreenView(MDScreen, Observer):     def generate_and_added_slides_to_carousel(self):         for pizza_name in self.model.pizza_description.keys():             pizza_name = pizza_name.lower()             scale = 1 if pizza_name == \"mexican\" else 2             card = PizzaCard(                 path_to_bg_image=os.path.join(                     \"assets\", \"images\", f\"{pizza_name}-bg.png\"                 ),                 pizza_name=pizza_name.capitalize(),                 pizza_description=self.model.pizza_description[pizza_name.capitalize()][                     0                 ],                 pizza_cost=self.model.pizza_description[pizza_name.capitalize()][1],                 pizza_image=os.path.join(\"assets\", \"images\", f\"{pizza_name}.png\"),                 view=self,             )             card.ids.pizza_image.scale = scale             self.ids.carousel.add_widget(card)<\/code><\/pre>\n<p>\u041d\u0430 \u043f\u0435\u0440\u0432\u043e\u043c \u0441\u043b\u0430\u0439\u0434\u0435 \u0441 \u0441\u043e\u0440\u0442\u043e\u043c \u043f\u0438\u0446\u0446\u044b <em>Mexican<\/em> \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044e \u043f\u0438\u0446\u0446\u044b \u043c\u044b \u0434\u0430\u043b\u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431 1, \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c \u0441\u043b\u0430\u0439\u0434\u0430\u043c \u0437\u0430\u0434\u0430\u043b\u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431 \u0440\u0430\u0432\u043d\u044b\u043c 2. \u0422\u0430\u043a \u0447\u0442\u043e \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043a\u0430\u0440\u0442\u0438\u043d\u0443:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3e8\/bbe\/fce\/3e8bbefce00d7cfcb997594e299ff1ca.gif\" width=\"446\" height=\"742\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3e8\/bbe\/fce\/3e8bbefce00d7cfcb997594e299ff1ca.gif\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0410\u043d\u0438\u043c\u0430\u0446\u0438\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u0438\u0446\u0446\u044b \u0438 \u043c\u0435\u0442\u043e\u043a \u0442\u0435\u043a\u0441\u0442\u0430 \u043f\u0440\u043e\u0441\u0442\u0430: \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e\/\u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e\/\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0441\u043b\u0430\u0439\u0434\u043e\u0432 \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0441\u0432\u0430\u0439\u043f\u0430 (&#171;<em>right\/left<\/em>&#171;) \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\/\u0434\u0435\u043a\u0440\u0435\u043c\u0435\u043d\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f <em>offset_value<\/em> \u0434\u043b\u044f \u0442\u0430\u043a\u0438\u0445 \u0441\u0432\u043e\u0439\u0441\u0442\u0432 \u043a\u0430\u043a \u043c\u0430\u0441\u0448\u0442\u0430\u0431 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u0438\u0446\u0446\u044b, \u0435\u0433\u043e \u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435, \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043c\u0435\u0442\u043a\u0438 \u0442\u0435\u043a\u0441\u0442\u0430 \u043f\u043e \u043e\u0441\u0438 <em>x<\/em>:<\/p>\n<pre><code class=\"python\"># Current slide. instance_carousel.current_slide.ids.image_bg.width += offset_value instance_carousel.current_slide.ids.pizza_image.scale = 1 - offset_value instance_carousel.current_slide.ids.pizza_image.angle += offset_value instance_carousel.current_slide.ids.pizza_name.x = (     self.width - abs(progress_value - self.width) + dp(20) )<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u0438\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 <em>do_animation_card_content <\/em>\u0432 \u043a\u043b\u0430\u0441\u0441\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u0434\u0443\u0442\u044b\u043c:<\/p>\n<pre><code class=\"python\">    def do_animation_card_content(self, instance_carousel, offset_value):         direction = self.get_direction_swipe(offset_value)         self._cursor_pos_x = offset_value         progress_value = offset_value         offset_value = max(min(abs(offset_value) \/ Window.width, 1), 0)          for instance_slide in [             instance_carousel.current_slide,             instance_carousel.next_slide,             instance_carousel.previous_slide,         ]:             if instance_slide:                 if direction == \"left\":                     instance_slide.ids.image_bg.x -= offset_value                 elif direction == \"right\":                     instance_slide.ids.image_bg.x += offset_value          if direction == \"left\":             # Current slide.             instance_carousel.current_slide.ids.image_bg.width += offset_value             instance_carousel.current_slide.ids.pizza_image.scale = 1 - offset_value             instance_carousel.current_slide.ids.pizza_image.angle += offset_value             instance_carousel.current_slide.ids.pizza_name.x = (                 self.width - abs(progress_value - self.width) + dp(20)             )             # Next slide.             if instance_carousel.next_slide:                 instance_carousel.next_slide.ids.image_bg.width += offset_value                 instance_carousel.next_slide.ids.pizza_image.scale = 2 - offset_value                 instance_carousel.next_slide.ids.pizza_image.angle += offset_value                 instance_carousel.next_slide.ids.pizza_name.x = (                     self.width - abs(progress_value) + dp(20)                 )             # Previous slide.             if instance_carousel.previous_slide:                 instance_carousel.previous_slide.ids.image_bg.width += offset_value                 instance_carousel.previous_slide.ids.pizza_image.scale = 2 - offset_value                 instance_carousel.previous_slide.ids.pizza_image.angle += offset_value                 instance_carousel.previous_slide.ids.pizza_name.x = dp(20) - abs(progress_value)         elif direction == \"right\":             # Current slide.             instance_carousel.current_slide.ids.image_bg.width -= offset_value             instance_carousel.current_slide.ids.pizza_image.scale = 1 - offset_value             instance_carousel.current_slide.ids.pizza_image.angle -= offset_value             instance_carousel.current_slide.ids.pizza_name.x = (                 self.width - abs(progress_value - self.width) + dp(20)             )             # Next slide.             if instance_carousel.next_slide:                 instance_carousel.next_slide.ids.image_bg.width -= offset_value                 instance_carousel.next_slide.ids.pizza_image.scale = 2 - offset_value                 instance_carousel.next_slide.ids.pizza_image.angle -= offset_value             # Previous slide.             if instance_carousel.previous_slide:                 instance_carousel.previous_slide.ids.image_bg.width -= offset_value                 instance_carousel.previous_slide.ids.pizza_image.scale = 2 - offset_value                 instance_carousel.previous_slide.ids.pizza_image.angle -= offset_value                 instance_carousel.previous_slide.ids.pizza_name.x = -(                     self.width - (progress_value + dp(20))                 )<\/code><\/pre>\n<p>\u0412 \u043c\u0435\u0442\u043e\u0434\u0435 \u044f\u0432\u043d\u043e \u043f\u0440\u043e\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u043e\u0434\u043d\u043e\u0442\u0438\u043f\u043d\u044b\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0438, \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u0432\u0441\u0435 \u044d\u0442\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u0443\u0436\u0430\u0442\u044c \u0434\u043e \u043e\u0434\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430, \u043d\u043e \u043c\u043d\u0435 \u0443\u0436\u0435 \u0431\u044b\u043b\u043e \u043b\u0435\u043d\u044c. \u0421\u0442\u0430\u0442\u044c\u044f \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u043b\u0430\u0441\u044c \u0434\u0432\u0430 \u0440\u0430\u0437\u0430 \u0441 \u043d\u0443\u043b\u044f \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043d\u043e\u0432\u044b\u0439 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 \u0425\u0430\u0431\u0440\u0430 \u0432\u0434\u0440\u0443\u0433 \u043f\u043e\u043a\u0430\u0437\u0430\u043b \u043c\u043d\u0435 \u043f\u0443\u0441\u0442\u043e\u0439 \u044d\u043a\u0440\u0430\u043d \u043f\u043e\u0441\u043b\u0435 \u043d\u0430\u0436\u0430\u0442\u0438\u044f \u043a\u043d\u043e\u043f\u043a\u0438 &#171;\u0412\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u0442\u0430\u0440\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f&#187;. \u042f \u0443\u0436\u0435 \u043c\u043e\u043b\u0447\u0443 \u043f\u0440\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u044e\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043f\u0443\u0441\u0442\u044f \u0434\u0435\u0441\u044f\u0442\u044c \u043f\u043e\u043f\u044b\u0442\u043e\u043a&#8230; \u041d\u043e \u044d\u0442\u043e \u0443\u0436\u0435 \u0434\u0440\u0443\u0433\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f. \u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043c\u044b \u043d\u0430\u043a\u043e\u043d\u0435\u0446-\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u043e\u043b\u0433\u043e\u0436\u0434\u0430\u043d\u043d\u044b\u0439 \u044d\u0444\u0444\u0435\u043a\u0442:<\/p>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/6151a6eb6ea11f3bbbaf1f6b\" data-style=\"\" id=\"6151a6eb6ea11f3bbbaf1f6b\" width=\"\"><\/div>\n<h2>P.S.<\/h2>\n<p>\u0412\u0438\u0434\u0435\u043e \u0431\u044b\u043b\u043e \u0437\u0430\u043b\u0438\u0442\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u043d\u0435\u0435, \u0447\u0435\u043c \u0432\u044b\u0448\u043b\u0430 \u0434\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f, \u0438 <em>parallax<\/em> \u044d\u0444\u0444\u0435\u043a\u0442\u0430 \u0434\u043b\u044f \u0444\u043e\u043d\u043e\u0432\u043e\u0433\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u043d\u0435\u043c \u043d\u0435\u0442. \u0418, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 \u043d\u0435 \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u043e \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 <em>MVC<\/em>, \u043d\u043e \u0442\u0430\u043a\u0430\u044f \u0446\u0435\u043b\u044c \u0438 \u043d\u0435 \u043f\u0440\u0435\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043b\u0430\u0441\u044c. \u0411\u043e\u043b\u0435\u0435 \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d\u043d\u044b\u0439 \u043a \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0448\u0430\u0431\u043b\u043e\u043d <em>MVC<\/em> \u0434\u043b\u044f <em>Kivy<\/em> \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0432 <a href=\"https:\/\/github.com\/HeaTTheatR\/LoginAppMVC\" rel=\"noopener noreferrer nofollow\">\u044d\u0442\u043e\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/a>. \u0414\u043e \u043d\u043e\u0432\u044b\u0445 \u0432\u0441\u0442\u0440\u0435\u0447!<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \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\/580132\/\"> https:\/\/habr.com\/ru\/articles\/580132\/<\/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<p>\u041f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e \u0432\u0430\u0441, \u0434\u043e\u0440\u043e\u0433\u0438\u0435 \u043b\u044e\u0431\u0438\u0442\u0435\u043b\u0438 \u0438 \u0437\u043d\u0430\u0442\u043e\u043a\u0438 <em>Python<\/em>! \u041f\u0440\u043e\u0448\u043b\u043e \u043f\u043e\u043b \u0433\u043e\u0434\u0430 \u0441 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u043c\u043e\u0435\u0439 <a href=\"https:\/\/habr.com\/ru\/post\/546684\/\" rel=\"noopener noreferrer nofollow\">\u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 <\/a>\u043d\u0430 \u0425\u0430\u0431\u0440\u0435. \u0411\u044b\u043b \u043f\u043e\u0433\u0440\u0443\u0436\u0435\u043d \u0432 \u043f\u0443\u0447\u0438\u043d\u0443 \u043e\u0431\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u0441\u0442\u0432 \u0438 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u044b. \u041d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u0441\u0435\u0433\u043e\u0434\u043d\u044f\u0448\u043d\u0435\u0439, \u0441\u0442\u0430\u0442\u044c\u0438 \u0431\u0443\u0434\u0443\u0442 \u0432\u044b\u0445\u043e\u0434\u0438\u0442\u044c \u0441 \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u043d\u043e\u0441\u0442\u044c\u044e \u0440\u0430\u0437 \u0432 \u043c\u0435\u0441\u044f\u0446. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438 \u0430\u043d\u0438\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u0434\u043b\u044f \u0441\u043b\u0430\u0439\u0434\u043e\u0432 \u0430 \u0442\u0430\u043a\u0436\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c parallax \u044d\u0444\u0444\u0435\u043a\u0442 \u0434\u043b\u044f \u0444\u043e\u043d\u043e\u0432\u043e\u0433\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 <em>Kivy<\/em> \u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 <em>KivyMD<\/em>. \u0414\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u043d\u0435\u0437\u043d\u0430\u043a\u043e\u043c \u043d\u0438 \u0441 \u043f\u0435\u0440\u0432\u044b\u043c \u043d\u0438 \u0441\u043e \u0432\u0442\u043e\u0440\u043e\u0439, \u0432\u043a\u0440\u0430\u0442\u0446\u0435 \u043d\u0430\u043f\u043e\u043c\u043d\u044e:<\/p>\n<figure class=\"float\"><figcaption><\/figcaption><\/figure>\n<p><a href=\"https:\/\/github.com\/kivy\/kivy\" rel=\"noopener noreferrer nofollow\">Kivy<\/a> &#8212; \u043a\u0440\u043e\u0441\u0441\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u044b\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c <em>Python\/Cython<\/em>. \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0432\u0432\u043e\u0434\u0430: <em>WM_Touch, WM_Pen, Mac OS X Trackpad Magic Mouse, Mtdev, Linux Kernel HID, TUIO<\/em>&#8230;<\/p>\n<figure class=\"float\"><figcaption><\/figcaption><\/figure>\n<p><a href=\"https:\/\/github.com\/kivymd\/KivyMD\" rel=\"noopener noreferrer nofollow\">KivyMD<\/a> &#8212; \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0430\u044f \u043d\u0430\u0431\u043e\u0440 \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432 \u0432 \u0441\u0442\u0438\u043b\u0435 <em>Google Material Design<\/em>, \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u043c <em>Kivy<\/em>. \u0412\u043d\u0435 \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u044b Kivy \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f. \u0422\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 &#8212; \u0431\u0435\u0442\u0430.<\/p>\n<h2>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439<\/h2>\n<pre><code class=\"bash\">pip install \"kivy[base] @ https:\/\/github.com\/kivy\/kivy\/archive\/master.zip\" pip install https:\/\/github.com\/kivymd\/KivyMD\/archive\/master.zip<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0432\u0430\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a <em>Kivy<\/em> \u043c\u0430\u0441\u0442\u0435\u0440 \u0432\u0435\u0440\u0441\u0438\u0438, \u0430 \u0432\u0442\u043e\u0440\u0430\u044f &#8212; \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 <em>KivyMD<\/em> \u0442\u0430\u043a\u0436\u0435 \u043c\u0430\u0441\u0442\u0435\u0440 \u0432\u0435\u0440\u0441\u0438\u0438. \u0412\u0441\u0435. \u041c\u043e\u0436\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. \u041d\u043e \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043e\u0439 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 <em>PizzaAppConcept<\/em>, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c. \u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0435, \u0432\u0441\u0435\u0433\u043e \u043e\u0434\u0438\u043d \u044d\u043a\u0440\u0430\u043d, \u043d\u043e \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044f \u043b\u044e\u0431\u043b\u044e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u044e \u0432 \u043b\u044e\u0431\u043e\u043c \u0441\u0432\u043e\u0435\u043c \u043a\u043e\u0434\u0435, \u044f \u0440\u0435\u0448\u0438\u043b, \u0447\u0442\u043e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0430 \u043d\u0430 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0435 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/Model-View-Controller\" rel=\"noopener noreferrer nofollow\">MVC<\/a>, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u043e \u043c\u043e\u0435\u043c\u0443 \u0441\u0443\u0431\u044a\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u043c\u0443 \u043c\u043d\u0435\u043d\u0438\u044e \u044d\u0442\u043e\u0442 \u0448\u0430\u0431\u043b\u043e\u043d \u043a\u0430\u043a \u043d\u0435\u043b\u044c\u0437\u044f \u043b\u0443\u0447\u0448\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u0440\u044f\u0434\u043a\u0430 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435. \u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 <em>MVC<\/em> \u044f \u043d\u0435 \u0431\u0443\u0434\u0443 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u0437\u0434\u0435\u0441\u044c. \u0414\u0435\u0442\u0430\u043b\u0438 \u0440\u0430\u0441\u043a\u0440\u043e\u044e\u0442\u0441\u044f \u0441\u0430\u043c\u0438 \u0441\u043e\u0431\u043e\u0439 \u043f\u043e \u0445\u043e\u0434\u0443 \u0443\u0433\u043b\u0443\u0431\u043b\u0435\u043d\u0438\u044f \u0432 \u0441\u0435\u0433\u043e\u0434\u043d\u044f\u0448\u043d\u0438\u0439 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b.<\/p>\n<h2>\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 MVC<\/h2>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u041f\u0440\u043e\u0435\u043a\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<ul>\n<li>\n<p><strong>assets<\/strong> &#8212; \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0448\u0440\u0438\u0444\u0442\u044b \u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/p>\n<\/li>\n<li>\n<p><strong>Controller<\/strong> &#8212; \u043c\u043e\u0434\u0443\u043b\u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u0432<\/p>\n<\/li>\n<li>\n<p><strong>Model<\/strong> &#8212; \u043c\u043e\u0434\u0443\u043b\u0438 \u043c\u043e\u0434\u0435\u043b\u0435\u0439<\/p>\n<\/li>\n<li>\n<p><strong>Utility<\/strong> &#8212; \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043c\u043e\u0434\u0443\u043b\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/p>\n<\/li>\n<li>\n<p><strong>View<\/strong> &#8212; \u043f\u0430\u043a\u0435\u0442\u044b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0439<\/p>\n<\/li>\n<\/ul>\n<p>\u0420\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0438\u043c\u0435\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043c\u043e\u0434\u0443\u043b\u0438 \u043c\u043e\u0434\u0435\u043b\u0438, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u0438\u043c\u0435\u044e\u0442 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0435 \u0438\u043c\u0435\u043d\u0430.<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u042d\u0442\u043e \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u043e \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435, \u0435\u0441\u043b\u0438 \u043f\u0440\u043e\u0435\u043a\u0442 \u0431\u043e\u043b\u044c\u0448\u043e\u0439. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u043c\u043e\u0435\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0448\u0435\u0441\u0442\u043d\u0430\u0434\u0446\u0430\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0436\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0439 \u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u0432.<\/p>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u0442\u044c \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u044d\u043a\u0440\u0430\u043d\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441-\u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u0435\u043b\u044c. \u042d\u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0443\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d \u043a\u0430\u0436\u0434\u044b\u043c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c. \u041a\u043b\u0430\u0441\u0441-\u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u0435\u043b\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 <em>model_is_changed<\/em> &#8212; \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437, \u043a\u043e\u0433\u0434\u0430 \u0438\u0437\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043a\u043b\u0430\u0441\u0441\u0430\u0445 \u043c\u043e\u0434\u0435\u043b\u0435\u0439, \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0441\u0438\u0433\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044e \u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u0435\u0434\u0448\u0438\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u0445.<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u041a\u043b\u0430\u0441\u0441-\u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0434\u0443\u043b\u044f <em>observer.py<\/em>:<\/p>\n<pre><code class=\"python\"># Of course, \"very flexible Python\" allows you to do without an abstract # superclass at all or use the clever exception `NotImplementedError`. In my # opinion, this can negatively affect the architecture of the application. # I would like to point out that using Kivy, one could use the on-signaling # model. In this case, when the state changes, the model will send a signal # that can be received by all attached observers. This approach seems less # universal - you may want to use a different library in the future.   class Observer:     \"\"\"Abstract superclass for all observers.\"\"\"      def model_is_changed(self):         \"\"\"         The method that will be called on the observer when the model changes.         \"\"\"<\/code><\/pre>\n<p>\u041a\u0430\u043a \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445 \u043a \u043a\u043b\u0430\u0441\u0441\u0443 <em>Observer<\/em>, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/kivy.org\/doc\/stable\/api-kivy.properties.html\" rel=\"noopener noreferrer nofollow\"><em>properties<\/em><\/a> \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a <em>NumericProperty, StringProperty, DictProperty<\/em> \u0438 \u0434\u0440. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u0440\u0430\u0432\u043d\u0438\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 <em>Python<\/em> \u0438 <em>Kivy<\/em>:<\/p>\n<p><strong>Python<\/strong>:<\/p>\n<pre><code class=\"python\">class MyClass:     def __init__(self, a=1.0):         super().__init__()         self.a = a<\/code><\/pre>\n<p><strong>Kivy<\/strong>:<\/p>\n<pre><code class=\"python\">class MyClass:     a = NumericProperty(1.0)<\/code><\/pre>\n<p><em>Properties<\/em> \u0432 <em>Kivy<\/em> \u0443\u0434\u043e\u0431\u043d\u0435\u0435. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0432 properties <em>Kivy<\/em> \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u0440\u044f\u0434 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434\u043e\u0432, \u0442\u0430\u043a\u0438\u0445, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u0430\u043a <em>on_<\/em> \u043c\u0435\u0442\u043e\u0434\u044b:<\/p>\n<pre><code class=\"python\">class MyClass:     a = NumericProperty(1)      def on_a(self, instance_my_class, new_a_value):         \"\"\"         The method called as soon as a new value has been set for the         'a' attribute.         \"\"\"          print(\"My property a changed to\", new_a_value)<\/code><\/pre>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u0438\u043c, \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <em>properties<\/em> \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a <em>Kivy<\/em>, \u0434\u043b\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u043a\u043b\u0430\u0441\u0441\u0430, \u0447\u0442\u043e, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0449\u0435, \u0447\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u0430\u044f \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f. \u041d\u043e \u0432 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0432\u0435\u0441\u044c \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0442\u043e\u0447\u0435\u043d \u043f\u043e\u0434 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a <em>Kivy<\/em> \u0438 \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c, \u0435\u0441\u043b\u0438 \u0432\u044b \u0437\u0430\u0445\u043e\u0442\u0438\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u043e\u0439 <em>GUI<\/em> \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u0441\u0435 \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u0434 \u043d\u043e\u0432\u044b\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a &#8212; \u0438 \u043c\u043e\u0434\u0435\u043b\u0438, \u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u044b. \u0414\u0430\u043d\u043d\u0430\u044f \u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430 \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0447\u0442\u043e \u0432\u0430\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435, \u043c\u043e\u0434\u0435\u043b\u044c \u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u044b \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u0435\u043b\u044f, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430\u0448\u0435\u0433\u043e \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u044d\u043a\u0440\u0430\u043d\u0430 \u0441\u043e \u0441\u043b\u0430\u0439\u0434\u0430\u043c\u0438 \u0441\u043e\u0440\u0442\u043e\u0432 \u043f\u0438\u0446\u0446\u044b. \u0412 \u043f\u0430\u043a\u0435\u0442\u0435 <em>View<\/em> \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u043e\u0432\u044b\u0439 \u043f\u0430\u043a\u0435\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441 \u0438\u043c\u0435\u043d\u0435\u043c <em>SliderMenuScreen<\/em>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u043c \u043c\u043e\u0434\u0443\u043b\u044c <em>slider_menu_screen.py<\/em> \u0441 \u043a\u043b\u0430\u0441\u0441\u043e\u043c \u043d\u0430\u0448\u0435\u0433\u043e \u044d\u043a\u0440\u0430\u043d\u0430:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u041a\u043b\u0430\u0441\u0441 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f <em>SliderMenuScreenView<\/em> \u043c\u043e\u0434\u0443\u043b\u044f <em>slider_menu_screen.py<\/em>:<\/p>\n<pre><code class=\"python\">from kivy.properties import ObjectProperty  from kivymd.uix.screen import MDScreen  from Utility.observer import Observer   class SliderMenuScreenView(MDScreen, Observer):     \"\"\"     A class that implements a visual representation of the model data     :class:`~Model.slider_menu_screen.SliderMenuScreenModel`.      Implements a screen with slides of pizza varieties.     \"\"\"      controller = ObjectProperty()     \"\"\"     Controller object -     :class:`~Controller.slider_menu_screen.SliderMenuScreenController`.      :attr:`controller` is an :class:`~kivy.properties.ObjectProperty`     and defaults to `None`.     \"\"\"      model = ObjectProperty()     \"\"\"     Model object - :class:`~Model.slider_menu_screen.SliderMenuScreenModel`.      :attr:`model` is an :class:`~kivy.properties.ObjectProperty`     and defaults to `None`.     \"\"\"      manager_screens = ObjectProperty()     \"\"\"     Screen manager object - :class:`~kivy.uix.screenmanager.ScreenManager`.      :attr:`manager_screens` is an :class:`~kivy.properties.ObjectProperty`     and defaults to `None`.     \"\"\"      def __init__(self, **kw):         super().__init__(**kw)         self.model.add_observer(self)      def model_is_changed(self):         \"\"\"         The method that will be called on the observer when the model changes.         \"\"\"<\/code><\/pre>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u043c\u0435\u0442\u044c \u0442\u0440\u0438 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u043e\u043b\u044f:<\/p>\n<ul>\n<li>\n<p><strong>controller<\/strong> &#8212; \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430<\/p>\n<\/li>\n<li>\n<p><strong>model<\/strong> &#8212; \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 \u043c\u043e\u0434\u0435\u043b\u0438<\/p>\n<\/li>\n<li>\n<p><strong>manager_screens<\/strong> &#8212; \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 <em>kivy.uix.screenmanager.ScreenManager<\/em> (\u044d\u043a\u0440\u0430\u043d\u043d\u044b\u0439 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u044d\u043a\u0440\u0430\u043d\u043e\u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f)<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u0435\u043b\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0430\u043c\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434 <em>model_is_changed<\/em> \u0434\u043b\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043c\u043e\u0434\u0435\u043b\u0438. \u0422\u0430\u043a\u0436\u0435 \u043a\u043b\u0430\u0441\u0441 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f <em>SliderMenuScreenView<\/em> \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u0442\u0441\u044f \u043e\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 <em>kivymd.uix.screen.MDScreen<\/em>: \u043b\u044e\u0431\u043e\u0439 \u044d\u043a\u0440\u0430\u043d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 <em>ScreenManager<\/em> \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0443\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d \u043e\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 <em>MDScreen<\/em>.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f <em>SliderMenuScreenView<\/em>:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u041a\u043b\u0430\u0441\u0441 \u043c\u043e\u0434\u0435\u043b\u0438 <em>SliderMenuScreenModel<\/em>:<\/p>\n<pre><code class=\"python\"># The model implements the observer pattern. This means that the class must # support adding, removing, and alerting observers. In this case, the model is # completely independent of controllers and views. It is important that all # registered observers implement a specific method that will be called by the # model when they are notified (in this case, it is the `model_is_changed` # method). For this, observers must be descendants of an abstract class, # inheriting which, the `model_is_changed` method must be overridden.   class SliderMenuScreenModel:     \"\"\"Implements screen logic for pizza variety slides.\"\"\"      def __init__(self):         # List of observer classes. In our case, this will be the         # `View.SliderMenuScreen.slider_menu_screen.py` class.         # See `__init__` method of the above class.         self._observers = []      def notify_observers(self):         \"\"\"         The method that will be called on the observer when the model changes.         \"\"\"          for observer in self._observers:             observer.model_is_changed()      def add_observer(self, observer):         self._observers.append(observer)      def remove_observer(self, observer):         self._observers.remove(observer)<\/code><\/pre>\n<p>\u041c\u043e\u0434\u0435\u043b\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0442\u0440\u0438 \u043c\u0435\u0442\u043e\u0434\u0430: \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435\/\u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435\/\u043e\u043f\u043e\u0432\u0435\u0449\u0435\u043d\u0438\u0435 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u0435\u043b\u0435\u0439. \u041f\u043e\u043a\u0430 \u043d\u0430\u0448\u0430 \u043c\u043e\u0434\u0435\u043b\u044c \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0445. \u041f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u041a\u043b\u0430\u0441\u0441 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 <em>SliderMenuScreenController<\/em>:<\/p>\n<pre><code class=\"python\">from View.SliderMenuScreen.slider_menu_screen import SliderMenuScreenView   class SliderMenuScreenController:     \"\"\"     The `SliderMenuScreenController` class represents a controller     implementation. Coordinates work of the view with the model.      The controller implements the strategy pattern. The controller connects     to the view to control its actions.     \"\"\"      def __init__(self, model):         self.model = model  # Model.slider_menu_screen.SliderMenuScreenModel         self.view = SliderMenuScreenView(controller=self, model=self.model)      def get_view(self) -> SliderMenuScreenView:         return self.view<\/code><\/pre>\n<p>\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442 \u0432\u0441\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0442 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435: \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u0432\u0432\u043e\u0434, \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0438 \u0442.\u0434. \u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u044f \u044d\u0442\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f, \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u043c\u043e\u0434\u0435\u043b\u0438 \u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0438\u0440\u0443\u044f \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043b\u043e\u0433\u0438\u043a\u0443 \u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c. \u0412 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u043a\u043b\u0430\u0441\u0441\u0430 <em>SliderMenuScreenController<\/em> \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u044d\u0442\u043e\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 <em>get_view<\/em>. \u041f\u043e\u043a\u0430 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0432 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0435 \u043c\u044b \u043d\u0435 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u043c. \u041d\u0430 \u044d\u0442\u043e\u043c \u043c\u044b \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043c \u0441 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u043c <em>MVC<\/em>. \u0414\u0432\u0438\u0433\u0430\u0435\u043c\u0441\u044f \u0434\u0430\u043b\u044c\u0448\u0435&#8230;<\/p>\n<h2>\u0422\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430 \u0432 \u043f\u0440\u0438\u043e\u0436\u0435\u043d\u0438\u0435<\/h2>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0421 \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 <em>Kivy<\/em> \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041d\u043e \u043f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u043d\u0430\u0447\u0430\u0442\u044c \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u043c\u043e\u0434\u0443\u043b\u044c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c <em>screens.py<\/em> \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <em>View<\/em>:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u042d\u0442\u043e\u0442 \u043c\u043e\u0434\u0443\u043b\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u043b\u043e\u0432\u0430\u0440\u044c \u0441 \u043a\u043b\u0430\u0441\u0441\u0430\u043c\u0438<\/p>\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-389268","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/389268","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=389268"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/389268\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=389268"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=389268"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=389268"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}