{"id":88792,"date":"2026-08-01T19:08:32","date_gmt":"2026-08-01T11:08:32","guid":{"rendered":"https:\/\/www.wsisp.com\/helps\/88792.html"},"modified":"2026-08-01T19:08:32","modified_gmt":"2026-08-01T11:08:32","slug":"python-pyside6-%e5%ae%9e%e7%8e%b0%e4%bc%9a%e7%94%9f%e6%b0%94%e7%9a%84%e5%91%8a%e7%99%bd%e7%aa%97%e5%8f%a3%ef%bc%9a%e6%8c%89%e9%92%ae%e8%ba%b2%e9%81%bf%e3%80%81%e8%a1%a8%e6%83%85","status":"publish","type":"post","link":"https:\/\/www.wsisp.com\/helps\/88792.html","title":{"rendered":"Python + PySide6 \u5b9e\u73b0\u4f1a\u201c\u751f\u6c14\u201d\u7684\u544a\u767d\u7a97\u53e3\uff1a\u6309\u94ae\u8eb2\u907f\u3001\u8868\u60c5\u8ddf\u968f\u4e0e\u7231\u5fc3\u52a8\u753b\uff08\u9644\u5b8c\u6574\u4ee3\u7801\u3001 HTML \u7248\u3001\u9879\u76ee\u6587\u4ef6zip\uff09"},"content":{"rendered":"<p>\u672c\u9879\u76ee\u4f7f\u7528 Python &#043; PySide6 \u5236\u4f5c\u4e86\u4e00\u4e2a\u5177\u6709\u4e92\u52a8\u6548\u679c\u7684\u544a\u767d\u7a97\u53e3\u3002\u5f53\u9f20\u6807\u9760\u8fd1\u201c\u4e0d\u613f\u610f\u201d\u6309\u94ae\u65f6&#xff0c;\u6309\u94ae\u4f1a\u81ea\u52a8\u8eb2\u5f00&#xff0c;\u5361\u901a\u8868\u60c5\u4e5f\u4f1a\u9010\u6e10\u751f\u6c14&#xff1b;\u5f53\u9f20\u6807\u9760\u8fd1\u201c\u613f\u610f\u201d\u6309\u94ae\u65f6&#xff0c;\u8868\u60c5\u4f1a\u53d8\u5f00\u5fc3\u3002\u70b9\u51fb\u201c\u613f\u610f\u201d\u540e&#xff0c;\u7a97\u53e3\u4f1a\u663e\u793a\u7231\u5fc3\u52a8\u753b\u3002\u9879\u76ee\u540c\u65f6\u63d0\u4f9b\u4e00\u4e2a\u65e0\u9700\u5b89\u88c5\u4f9d\u8d56\u3001\u53cc\u51fb\u5373\u53ef\u8fd0\u884c\u7684 HTML \u7248\u672c\u3002<\/p>\n<\/p>\n<p>\u4e00\u3001\u9879\u76ee\u6548\u679c<\/p>\n<p>\u8fd9\u4e2a\u5c0f\u9879\u76ee\u5e76\u4e0d\u662f\u4e00\u4e2a\u666e\u901a\u7684\u9759\u6001\u5f39\u7a97&#xff0c;\u800c\u662f\u52a0\u5165\u4e86\u591a\u79cd\u5b9e\u65f6\u4ea4\u4e92\u6548\u679c&#xff1a;<\/p>\n<p>&#8211; \u773c\u775b\u4f1a\u8ddf\u968f\u9f20\u6807\u79fb\u52a8&#xff1b;<br \/>\n&#8211; \u9f20\u6807\u9760\u8fd1\u201c\u4e0d\u613f\u610f\u201d\u6309\u94ae\u65f6&#xff0c;\u8868\u60c5\u9010\u6e10\u751f\u6c14&#xff1b;<br \/>\n&#8211; \u201c\u4e0d\u613f\u610f\u201d\u6309\u94ae\u4f1a\u4e3b\u52a8\u8eb2\u907f\u9f20\u6807&#xff1b;<br \/>\n&#8211; \u70b9\u51fb\u201c\u4e0d\u613f\u610f\u201d\u540e&#xff0c;\u7a97\u53e3\u4f1a\u6296\u52a8\u5e76\u63d0\u793a\u201c\u70b9\u9519\u4e86&#xff0c;\u91cd\u6765\u201d&#xff1b;<br \/>\n&#8211; \u9f20\u6807\u9760\u8fd1\u201c\u613f\u610f\u201d\u6309\u94ae\u65f6&#xff0c;\u8868\u60c5\u4f1a\u9010\u6e10\u5f00\u5fc3&#xff1b;<br \/>\n&#8211; \u70b9\u51fb\u201c\u613f\u610f\u201d\u540e&#xff0c;\u6309\u94ae\u6587\u5b57\u6539\u53d8\u5e76\u51fa\u73b0\u4e0a\u6d6e\u7231\u5fc3&#xff1b;<br \/>\n&#8211; \u5728\u786e\u8ba4\u4e4b\u524d&#xff0c;\u684c\u9762\u7248\u4f1a\u963b\u6b62\u76f4\u63a5\u5173\u95ed\u6216\u6700\u5c0f\u5316\u7a97\u53e3&#xff1b;<br \/>\n&#8211; \u540c\u65f6\u63d0\u4f9b Python \u684c\u9762\u7248\u548c HTML \u7f51\u9875\u7248\u3002<\/p>\n<p class=\"img-center\"><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"225\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/08\/20260801110831-6a6dd3afa3c6e.png\" width=\"260\" \/><\/p>\n<p style=\"text-align:center\">&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;\u521d\u59cb\u754c\u9762&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p class=\"img-center\"><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"228\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/08\/20260801110831-6a6dd3afc5fda.png\" width=\"261\" \/><\/p>\n<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;\u4e0d\u613f\u610f\u754c\u9762&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<\/p>\n<p style=\"text-align:center\"><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"210\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/08\/20260801110831-6a6dd3afda3e4.png\" width=\"248\" \/><\/p>\n<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;\u613f\u610f\u540e\u754c\u9762&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<\/p>\n<\/p>\n<p>\u4e8c\u3001\u4f7f\u7528\u5230\u7684\u6280\u672f<\/p>\n<p>&gt;Python \u684c\u9762\u7248<\/p>\n<p>&#8211; Python 3<br \/>\n&#8211; PySide6<br \/>\n&#8211; QPainter \u81ea\u5b9a\u4e49\u7ed8\u56fe<br \/>\n&#8211; QTimer \u5b9a\u65f6\u5237\u65b0\u52a8\u753b<br \/>\n&#8211; \u9f20\u6807\u4f4d\u7f6e\u68c0\u6d4b<br \/>\n&#8211; \u8ddd\u79bb\u8ba1\u7b97\u4e0e\u7ebf\u6027\u63d2\u503c<br \/>\n&#8211; Qt \u4e8b\u4ef6\u5904\u7406<\/p>\n<p>&gt;HTML \u7f51\u9875\u7248<\/p>\n<p>&#8211; HTML5<br \/>\n&#8211; CSS3<br \/>\n&#8211; JavaScript<br \/>\n&#8211; Canvas 2D \u7ed8\u56fe<br \/>\n&#8211; &#096;requestAnimationFrame&#096; \u52a8\u753b\u5faa\u73af<br \/>\n&#8211; DOM \u4e8b\u4ef6\u76d1\u542c<\/p>\n<\/p>\n<p>\u4e09\u3001\u9879\u76ee\u6587\u4ef6\u7ed3\u6784<\/p>\n<p>&#096;&#096;&#096;text<br \/>\nconfession-project\/<br \/>\n\u251c\u2500 confession_reactive_window.py \u00a0 \u00a0# PySide6 \u684c\u9762\u7248<br \/>\n\u251c\u2500 confession_reactive_window.html \u00a0# HTML \u7f51\u9875\u7248<br \/>\n\u251c\u2500 requirements.txt \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 # Python \u4f9d\u8d56<br \/>\n\u2514\u2500 README.md \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 # \u9879\u76ee\u8bf4\u660e<\/p>\n<\/p>\n<p>\u56db\u3001\u8fd0\u884c Python \u684c\u9762\u7248<\/p>\n<p>1. \u786e\u8ba4 Python \u73af\u5883<\/p>\n<p>\u5728\u7ec8\u7aef\u4e2d\u6267\u884c&#xff1a;python &#8211;version<\/p>\n<p>\u5efa\u8bae\u4f7f\u7528 Python 3.9 \u53ca\u4ee5\u4e0a\u7248\u672c\u3002<\/p>\n<p>2. \u5b89\u88c5 PySide6<br \/>\npip install PySide6<\/p>\n<p>\u4e5f\u53ef\u4ee5\u4f7f\u7528\u9879\u76ee\u4e2d\u7684\u4f9d\u8d56\u6587\u4ef6&#xff1a;<br \/>\npip install -r requirements.txt<\/p>\n<p>3. \u542f\u52a8\u9879\u76ee<\/p>\n<p>\u8fdb\u5165\u4ee3\u7801\u6240\u5728\u76ee\u5f55&#xff0c;\u6267\u884c&#xff1a;<br \/>\npython confession_reactive_window.py<\/p>\n<p>\u5982\u679c Windows \u4e2d\u5b58\u5728\u591a\u4e2a Python&#xff0c;\u53ef\u4ee5\u5c1d\u8bd5&#xff1a;<br \/>\npy confession_reactive_window.py<\/p>\n<\/p>\n<p>\u4e94\u3001\u8fd0\u884c HTML \u7f51\u9875\u7248<\/p>\n<p>HTML \u7248\u672c\u4e0d\u9700\u8981\u5b89\u88c5 Python&#xff0c;\u4e5f\u4e0d\u9700\u8981\u914d\u7f6e\u670d\u52a1\u5668\u3002<\/p>\n<p>\u76f4\u63a5\u53cc\u51fb&#xff1a;<br \/>\nconfession_reactive_window.html<\/p>\n<p>\u6d4f\u89c8\u5668\u4f1a\u81ea\u52a8\u6253\u5f00\u9875\u9762\u3002\u5982\u679c\u76f4\u63a5\u6253\u5f00\u65f6\u6d4f\u89c8\u5668\u9650\u5236\u4e86\u90e8\u5206\u529f\u80fd&#xff0c;\u4e5f\u53ef\u4ee5\u5728\u5f53\u524d\u76ee\u5f55\u542f\u52a8\u4e00\u4e2a\u7b80\u5355\u670d\u52a1\u5668&#xff1a;<br \/>\npython -m http.server 8000<\/p>\n<p>\u7136\u540e\u8bbf\u95ee&#xff1a;<br \/>\nhttp:\/\/localhost:8000\/confession_reactive_window.html<\/p>\n<\/p>\n<p>\u516d\u3001\u6838\u5fc3\u5b9e\u73b0\u601d\u8def<\/p>\n<p>6.1 \u4f7f\u7528\u5b9a\u65f6\u5668\u6784\u5efa\u52a8\u753b\u5faa\u73af<\/p>\n<p>\u684c\u9762\u7248\u901a\u8fc7 &#096;QTimer&#096; \u6bcf\u9694\u7ea6 16 \u6beb\u79d2\u8c03\u7528\u4e00\u6b21\u52a8\u753b\u51fd\u6570&#xff1a;<\/p>\n<p>&#096;&#096;&#096;python<br \/>\nself.timer &#061; QTimer(self)<br \/>\nself.timer.timeout.connect(self.animate)<br \/>\nself.timer.start(16)<br \/>\n&#096;&#096;&#096;<\/p>\n<p>16 \u6beb\u79d2\u5bf9\u5e94\u7684\u5237\u65b0\u9891\u7387\u5927\u7ea6\u662f 60 FPS\u3002\u6bcf\u6b21\u5237\u65b0\u65f6&#xff0c;\u7a0b\u5e8f\u4f1a\u4f9d\u6b21\u5b8c\u6210&#xff1a;<\/p>\n<p>1. \u83b7\u53d6\u5f53\u524d\u9f20\u6807\u4f4d\u7f6e&#xff1b;<br \/>\n2. \u8ba1\u7b97\u60c5\u7eea\u5f3a\u5ea6&#xff1b;<br \/>\n3. \u5224\u65ad\u201c\u4e0d\u613f\u610f\u201d\u6309\u94ae\u662f\u5426\u9700\u8981\u79fb\u52a8&#xff1b;<br \/>\n4. \u66f4\u65b0\u7231\u5fc3\u4f4d\u7f6e&#xff1b;<br \/>\n5. \u8c03\u7528 &#096;update()&#096; \u91cd\u65b0\u7ed8\u5236\u7a97\u53e3\u3002<\/p>\n<p>&#096;&#096;&#096;python<br \/>\ndef animate(self):<br \/>\n\u00a0 \u00a0 self.tick_count &#043;&#061; 1<br \/>\n\u00a0 \u00a0 if not self.accepted:<br \/>\n\u00a0 \u00a0 \u00a0 \u00a0 self.update_intensity()<br \/>\n\u00a0 \u00a0 \u00a0 \u00a0 self.move_no_button_if_needed()<br \/>\n\u00a0 \u00a0 else:<br \/>\n\u00a0 \u00a0 \u00a0 \u00a0 self.float_hearts()<br \/>\n\u00a0 \u00a0 self.update()<br \/>\n&#096;&#096;&#096;<\/p>\n<p>\u8fd9\u79cd\u7ed3\u6784\u4e0e\u6e38\u620f\u4e2d\u7684\u201c\u66f4\u65b0\u72b6\u6001 &#043; \u7ed8\u5236\u753b\u9762\u201d\u5faa\u73af\u975e\u5e38\u76f8\u4f3c\u3002<\/p>\n<\/p>\n<p>6.2 \u6839\u636e\u9f20\u6807\u8ddd\u79bb\u8ba1\u7b97\u201c\u751f\u6c14\u7a0b\u5ea6\u201d<\/p>\n<p>\u7a0b\u5e8f\u4f1a\u8ba1\u7b97\u9f20\u6807\u4e0e\u201c\u4e0d\u613f\u610f\u201d\u6309\u94ae\u4e2d\u5fc3\u70b9\u4e4b\u95f4\u7684\u6b27\u6c0f\u8ddd\u79bb&#xff1a;<\/p>\n<p>&#096;&#096;&#096;python<br \/>\ncursor &#061; self.mapFromGlobal(QCursor.pos())<br \/>\ncenter &#061; self.no_button.geometry().center()<br \/>\ndx &#061; cursor.x() &#8211; center.x()<br \/>\ndy &#061; cursor.y() &#8211; center.y()<br \/>\ndistance &#061; math.hypot(dx, dy)<br \/>\n&#096;&#096;&#096;<\/p>\n<p>\u968f\u540e\u5c06\u8ddd\u79bb\u6620\u5c04\u4e3a 0&#xff5e;1 \u4e4b\u95f4\u7684\u60c5\u7eea\u503c&#xff1a;<\/p>\n<p>&#096;&#096;&#096;python<br \/>\ntarget &#061; clamp(1 &#8211; (distance &#8211; 25) \/ 160)<br \/>\nself.intensity &#043;&#061; (target &#8211; self.intensity) * 0.18<br \/>\n&#096;&#096;&#096;<\/p>\n<p>\u5176\u4e2d&#xff1a;<\/p>\n<p>&#8211; \u9f20\u6807\u8ddd\u79bb\u8d8a\u8fdc&#xff0c;&#096;intensity&#096; \u8d8a\u63a5\u8fd1 0&#xff1b;<br \/>\n&#8211; \u9f20\u6807\u8ddd\u79bb\u8d8a\u8fd1&#xff0c;&#096;intensity&#096; \u8d8a\u63a5\u8fd1 1&#xff1b;<br \/>\n&#8211; \u4f7f\u7528\u63d2\u503c\u800c\u4e0d\u662f\u76f4\u63a5\u8d4b\u503c&#xff0c;\u53ef\u4ee5\u8ba9\u8868\u60c5\u53d8\u5316\u66f4\u52a0\u5e73\u6ed1\u3002<\/p>\n<p>\u8fd9\u91cc\u7684\u66f4\u65b0\u516c\u5f0f\u53ef\u4ee5\u5199\u6210&#xff1a;<\/p>\n<p>&#096;&#096;&#096;text<br \/>\n\u5f53\u524d\u503c &#061; \u5f53\u524d\u503c &#043; (\u76ee\u6807\u503c &#8211; \u5f53\u524d\u503c) \u00d7 \u5e73\u6ed1\u7cfb\u6570<br \/>\n&#096;&#096;&#096;<\/p>\n<p>\u5b83\u662f\u4e00\u79cd\u975e\u5e38\u5e38\u7528\u7684\u7f13\u52a8\u65b9\u6cd5\u3002<\/p>\n<\/p>\n<p>6.3 \u9f20\u6807\u9760\u8fd1\u201c\u613f\u610f\u201d\u6309\u94ae\u65f6\u53d8\u5f00\u5fc3<\/p>\n<p>\u7a0b\u5e8f\u8fd8\u4f1a\u5355\u72ec\u8ba1\u7b97\u9f20\u6807\u4e0e\u201c\u613f\u610f\u201d\u6309\u94ae\u4e4b\u95f4\u7684\u8ddd\u79bb&#xff1a;<\/p>\n<p>&#096;&#096;&#096;python<br \/>\nyes_center &#061; self.yes_button.geometry().center()<br \/>\nyes_distance &#061; math.hypot(<br \/>\n\u00a0 \u00a0 cursor.x() &#8211; yes_center.x(),<br \/>\n\u00a0 \u00a0 cursor.y() &#8211; yes_center.y()<br \/>\n)<\/p>\n<p>happy_target &#061; clamp(1 &#8211; (yes_distance &#8211; 20) \/ 150)<br \/>\n&#096;&#096;&#096;<\/p>\n<p>\u5f53\u9f20\u6807\u9760\u8fd1\u5de6\u4fa7\u6309\u94ae\u65f6&#xff0c;&#096;happiness&#096; \u4f1a\u589e\u52a0\u3002\u5634\u5df4\u7684\u4e8c\u6b21\u8d1d\u585e\u5c14\u66f2\u7ebf\u63a7\u5236\u70b9\u4f1a\u968f\u4e4b\u4e0b\u79fb&#xff0c;\u4ece\u800c\u5f62\u6210\u7b11\u8138\u3002<\/p>\n<\/p>\n<p>6.4 \u8ba9\u201c\u4e0d\u613f\u610f\u201d\u6309\u94ae\u8eb2\u5f00\u9f20\u6807<\/p>\n<p>\u9996\u5148\u6269\u5927\u6309\u94ae\u7684\u68c0\u6d4b\u533a\u57df&#xff1a;<\/p>\n<p>&#096;&#096;&#096;python<br \/>\nrect &#061; self.no_button.geometry().adjusted(-90, -70, 90, 70)<br \/>\n&#096;&#096;&#096;<\/p>\n<p>\u5f53\u9f20\u6807\u8fdb\u5165\u8be5\u8303\u56f4\u65f6&#xff0c;\u7a0b\u5e8f\u4f1a\u51c6\u5907\u591a\u4e2a\u5019\u9009\u4f4d\u7f6e&#xff1a;<\/p>\n<p>&#096;&#096;&#096;python<br \/>\ncandidates &#061; [<br \/>\n\u00a0 \u00a0 QPointF(286, 300),<br \/>\n\u00a0 \u00a0 QPointF(330, 350),<br \/>\n\u00a0 \u00a0 QPointF(378, 302),<br \/>\n\u00a0 \u00a0 QPointF(250, 350),<br \/>\n\u00a0 \u00a0 QPointF(358, 334),<br \/>\n]<br \/>\n&#096;&#096;&#096;<\/p>\n<p>\u968f\u540e\u9009\u62e9\u8ddd\u79bb\u9f20\u6807\u6700\u8fdc\u7684\u4f4d\u7f6e&#xff1a;<\/p>\n<p>&#096;&#096;&#096;python<br \/>\nself.target_no_pos &#061; max(<br \/>\n\u00a0 \u00a0 candidates,<br \/>\n\u00a0 \u00a0 key&#061;lambda p: math.hypot(<br \/>\n\u00a0 \u00a0 \u00a0 \u00a0 p.x() &#043; 55 &#8211; cursor.x(),<br \/>\n\u00a0 \u00a0 \u00a0 \u00a0 p.y() &#043; 23 &#8211; cursor.y()<br \/>\n\u00a0 \u00a0 )<br \/>\n)<br \/>\n&#096;&#096;&#096;<\/p>\n<p>\u8fd9\u6837\u53ef\u4ee5\u907f\u514d\u6309\u94ae\u968f\u673a\u79fb\u52a8\u5230\u9f20\u6807\u9644\u8fd1&#xff0c;\u4f7f\u8eb2\u907f\u6548\u679c\u66f4\u52a0\u81ea\u7136\u3002<\/p>\n<p>\u4e3a\u4e86\u8ba9\u6309\u94ae\u4e0d\u662f\u77ac\u95f4\u8df3\u8dc3&#xff0c;\u7a0b\u5e8f\u518d\u6b21\u4f7f\u7528\u63d2\u503c&#xff1a;<\/p>\n<p>&#096;&#096;&#096;python<br \/>\nnext_pos &#061; current &#043; (self.target_no_pos &#8211; current) * 0.55<br \/>\nself.no_button.move(round(next_pos.x()), round(next_pos.y()))<br \/>\n&#096;&#096;&#096;<\/p>\n<p>\u5f53\u9f20\u6807\u975e\u5e38\u63a5\u8fd1\u65f6&#xff0c;\u6309\u94ae\u4f1a\u76f4\u63a5\u79fb\u52a8\u5230\u76ee\u6807\u4f4d\u7f6e&#xff0c;\u4ee5\u514d\u88ab\u5feb\u901f\u70b9\u51fb\u3002<\/p>\n<\/p>\n<p>6.5 \u4f7f\u7528 QPainter \u7ed8\u5236\u52a8\u6001\u8868\u60c5<\/p>\n<p>\u6574\u4e2a\u5361\u901a\u8138\u5e76\u4e0d\u662f\u56fe\u7247&#xff0c;\u800c\u662f\u901a\u8fc7 &#096;QPainter&#096; \u5b9e\u65f6\u7ed8\u5236\u7684&#xff1a;<\/p>\n<p>&#096;&#096;&#096;python<br \/>\ndef paintEvent(self, _event):<br \/>\n\u00a0 \u00a0 painter &#061; QPainter(self)<br \/>\n\u00a0 \u00a0 painter.setRenderHint(QPainter.Antialiasing)<br \/>\n\u00a0 \u00a0 self.draw_background(painter)<br \/>\n\u00a0 \u00a0 self.draw_face(painter)<br \/>\n\u00a0 \u00a0 self.draw_hearts(painter)<br \/>\n&#096;&#096;&#096;<\/p>\n<p>\u7ed8\u5236\u5185\u5bb9\u5305\u62ec&#xff1a;<\/p>\n<p>&#8211; \u6e10\u53d8\u80cc\u666f&#xff1b;<br \/>\n&#8211; \u692d\u5706\u5f62\u8138\u90e8&#xff1b;<br \/>\n&#8211; \u7709\u6bdb&#xff1b;<br \/>\n&#8211; \u773c\u775b\u548c\u9ad8\u5149&#xff1b;<br \/>\n&#8211; \u816e\u7ea2&#xff1b;<br \/>\n&#8211; \u5634\u5df4\u66f2\u7ebf&#xff1b;<br \/>\n&#8211; \u63a5\u53d7\u540e\u7684\u7231\u5fc3\u3002<\/p>\n<p>\u8868\u60c5\u4e3a\u4ec0\u4e48\u4f1a\u201c\u751f\u6c14\u201d&#xff1f;<\/p>\n<p>\u968f\u7740 &#096;intensity&#096; \u589e\u52a0&#xff1a;<\/p>\n<p>&#8211; \u8138\u90e8\u989c\u8272\u9010\u6e10\u53d8\u6df1&#xff1b;<br \/>\n&#8211; \u7709\u6bdb\u5185\u4fa7\u5411\u4e0b\u79fb\u52a8&#xff1b;<br \/>\n&#8211; \u773c\u775b\u9ad8\u5ea6\u7f29\u5c0f&#xff1b;<br \/>\n&#8211; \u816e\u7ea2\u900f\u660e\u5ea6\u589e\u52a0&#xff1b;<br \/>\n&#8211; \u5634\u5df4\u4ece\u5fae\u7b11\u53d8\u5e73&#xff0c;\u518d\u53d8\u6210\u5411\u4e0b\u5f2f\u66f2&#xff1b;<br \/>\n&#8211; \u5f3a\u5ea6\u8d85\u8fc7\u9608\u503c\u540e\u51fa\u73b0\u989d\u5916\u6587\u5b57\u63d0\u793a\u3002<\/p>\n<p>\u4f8b\u5982\u7709\u6bdb\u4f4d\u7f6e\u7684\u8ba1\u7b97&#xff1a;<\/p>\n<p>&#096;&#096;&#096;python<br \/>\nbrow_outer_y &#061; 78 &#043; anger * 2<br \/>\nbrow_inner_y &#061; 78 &#043; anger * 18<br \/>\n&#096;&#096;&#096;<\/p>\n<p>\u5f53 &#096;anger&#096; \u589e\u5927\u65f6&#xff0c;\u7709\u6bdb\u5185\u4fa7\u53d8\u5316\u66f4\u660e\u663e&#xff0c;\u56e0\u6b64\u4f1a\u5f62\u6210\u751f\u6c14\u7684\u89c6\u89c9\u6548\u679c\u3002<\/p>\n<\/p>\n<p>6.6 \u8ba9\u773c\u775b\u8ddf\u968f\u9f20\u6807<\/p>\n<p>\u7a0b\u5e8f\u8ba1\u7b97\u9f20\u6807\u76f8\u5bf9\u4e8e\u8138\u90e8\u4e2d\u5fc3\u7684\u65b9\u5411&#xff1a;<\/p>\n<p>&#096;&#096;&#096;python<br \/>\ndx &#061; cursor.x() &#8211; cx<br \/>\ndy &#061; cursor.y() &#8211; cy<br \/>\ndistance &#061; max(1, math.hypot(dx, dy))<\/p>\n<p>eye_dx &#061; dx \/ distance * (5 &#8211; anger * 2)<br \/>\neye_dy &#061; dy \/ distance * (4 &#8211; anger * 1.5)<br \/>\n&#096;&#096;&#096;<\/p>\n<p>\u8fd9\u91cc\u5148\u5bf9\u65b9\u5411\u5411\u91cf\u8fdb\u884c\u5f52\u4e00\u5316&#xff0c;\u518d\u4e58\u4ee5\u4e00\u4e2a\u8f83\u5c0f\u7684\u79fb\u52a8\u8ddd\u79bb\u3002\u8fd9\u6837\u773c\u7403\u53ea\u4f1a\u5728\u6709\u9650\u8303\u56f4\u5185\u79fb\u52a8&#xff0c;\u4e0d\u4f1a\u8dd1\u51fa\u773c\u7736\u3002<\/p>\n<\/p>\n<p>6.7 \u70b9\u51fb\u6309\u94ae\u540e\u7684\u4ea4\u4e92<\/p>\n<p>\u70b9\u51fb\u201c\u613f\u610f\u201d<\/p>\n<p>&#096;&#096;&#096;python<br \/>\ndef say_yes(self):<br \/>\n\u00a0 \u00a0 self.accepted &#061; True<br \/>\n\u00a0 \u00a0 self.intensity &#061; 0.0<br \/>\n\u00a0 \u00a0 self.title.setText(&#034;\u563f\u563f&#xff0c;\u90a3\u5c31\u8bf4\u597d\u5566&#xff01;&#034;)<br \/>\n\u00a0 \u00a0 self.tip.setText(&#034;\u4eca\u5929\u5f00\u59cb\u5c31\u662f\u6700\u7279\u522b\u7684\u4eba&#034;)<br \/>\n\u00a0 \u00a0 self.no_button.hide()<br \/>\n\u00a0 \u00a0 self.yes_button.setText(&#034;\u559c\u6b22\u4f60&#034;)<br \/>\n\u00a0 \u00a0 self.hearts &#061; []<br \/>\n&#096;&#096;&#096;<\/p>\n<p>\u786e\u8ba4\u540e\u4f1a\u9690\u85cf\u201c\u4e0d\u613f\u610f\u201d\u6309\u94ae&#xff0c;\u5e76\u8fdb\u5165\u7231\u5fc3\u52a8\u753b\u72b6\u6001\u3002<\/p>\n<p>\u70b9\u51fb\u201c\u4e0d\u613f\u610f\u201d<\/p>\n<p>&#096;&#096;&#096;python<br \/>\ndef say_no(self):<br \/>\n\u00a0 \u00a0 self.intensity &#061; 1.0<br \/>\n\u00a0 \u00a0 self.tip.setText(&#034;\u70b9\u9519\u4e86&#xff0c;\u91cd\u6765&#xff01;&#034;)<br \/>\n\u00a0 \u00a0 self.shake()<br \/>\n&#096;&#096;&#096;<\/p>\n<p>\u7a97\u53e3\u6296\u52a8\u4f7f\u7528\u591a\u4e2a\u5ef6\u8fdf\u4efb\u52a1\u5b9e\u73b0&#xff1a;<\/p>\n<p>&#096;&#096;&#096;python<br \/>\noffsets &#061; [8, -8, 6, -6, 3, -3, 0]<br \/>\nfor index, offset in enumerate(offsets):<br \/>\n\u00a0 \u00a0 QTimer.singleShot(<br \/>\n\u00a0 \u00a0 \u00a0 \u00a0 index * 35,<br \/>\n\u00a0 \u00a0 \u00a0 \u00a0 lambda o&#061;offset: self.move(start.x() &#043; o, start.y())<br \/>\n\u00a0 \u00a0 )<br \/>\n&#096;&#096;&#096;<\/p>\n<p>\u8fd9\u91cc\u5728 &#096;lambda&#096; \u53c2\u6570\u4e2d\u5199 &#096;o&#061;offset&#096; \u5f88\u91cd\u8981&#xff0c;\u53ef\u4ee5\u907f\u514d\u5faa\u73af\u53d8\u91cf\u5ef6\u8fdf\u7ed1\u5b9a\u5bfc\u81f4\u6240\u6709\u4efb\u52a1\u4f7f\u7528\u540c\u4e00\u4e2a\u503c\u3002<\/p>\n<\/p>\n<p>6.8 \u7231\u5fc3\u4e0a\u6d6e\u52a8\u753b<\/p>\n<p>\u63a5\u53d7\u540e&#xff0c;\u7a0b\u5e8f\u5b9a\u671f\u521b\u5efa\u65b0\u7684\u7231\u5fc3&#xff1a;<\/p>\n<p>&#096;&#096;&#096;python<br \/>\nself.hearts.append([<br \/>\n\u00a0 \u00a0 random.randint(160, 360),<br \/>\n\u00a0 \u00a0 185,<br \/>\n\u00a0 \u00a0 random.uniform(-0.8, 0.8),<br \/>\n\u00a0 \u00a0 random.randint(18, 28)<br \/>\n])<br \/>\n&#096;&#096;&#096;<\/p>\n<p>\u6bcf\u6b21\u5237\u65b0\u65f6\u4fee\u6539\u7231\u5fc3\u7684\u4f4d\u7f6e\u548c\u5c3a\u5bf8&#xff1a;<\/p>\n<p>&#096;&#096;&#096;python<br \/>\nheart[0] &#043;&#061; heart[2]<br \/>\nheart[1] -&#061; 1.8<br \/>\nheart[3] -&#061; 0.18<br \/>\n&#096;&#096;&#096;<\/p>\n<p>\u8fd9\u5206\u522b\u8868\u793a&#xff1a;<\/p>\n<p>&#8211; \u6c34\u5e73\u65b9\u5411\u4ea7\u751f\u8f7b\u5fae\u6f02\u79fb&#xff1b;<br \/>\n&#8211; \u7eb5\u5750\u6807\u4e0d\u65ad\u51cf\u5c0f&#xff0c;\u5b9e\u73b0\u5411\u4e0a\u79fb\u52a8&#xff1b;<br \/>\n&#8211; \u5b57\u53f7\u9010\u6e10\u51cf\u5c0f&#xff1b;<br \/>\n&#8211; \u8d85\u51fa\u8303\u56f4\u540e\u4ece\u5217\u8868\u4e2d\u5220\u9664\u3002<\/p>\n<\/p>\n<p>6.9 \u963b\u6b62\u5173\u95ed\u548c\u6700\u5c0f\u5316<\/p>\n<p>\u684c\u9762\u7248\u91cd\u5199\u4e86 &#096;closeEvent&#096;&#xff1a;<\/p>\n<p>&#096;&#096;&#096;python<br \/>\ndef closeEvent(self, event):<br \/>\n\u00a0 \u00a0 if self.accepted:<br \/>\n\u00a0 \u00a0 \u00a0 \u00a0 event.accept()<br \/>\n\u00a0 \u00a0 \u00a0 \u00a0 return<\/p>\n<p>\u00a0 \u00a0 event.ignore()<br \/>\n\u00a0 \u00a0 self.intensity &#061; 1.0<br \/>\n\u00a0 \u00a0 self.tip.setText(&#034;\u5148\u70b9\u613f\u610f\u624d\u53ef\u4ee5\u5173\u95ed&#034;)<br \/>\n\u00a0 \u00a0 self.shake()<br \/>\n&#096;&#096;&#096;<\/p>\n<p>\u5728\u7528\u6237\u70b9\u51fb\u201c\u613f\u610f\u201d\u4e4b\u524d&#xff0c;\u5173\u95ed\u8bf7\u6c42\u4f1a\u88ab\u5ffd\u7565\u3002<\/p>\n<p>\u9879\u76ee\u8fd8\u76d1\u542c\u7a97\u53e3\u72b6\u6001\u53d8\u5316&#xff0c;\u5728\u6700\u5c0f\u5316\u65f6\u6062\u590d\u7a97\u53e3\u3002\u8fd9\u4e2a\u8bbe\u8ba1\u9002\u5408\u7528\u4e8e\u8da3\u5473\u6f14\u793a&#xff0c;\u4f46\u5b9e\u9645\u5206\u4eab\u65f6\u5e94\u63d0\u524d\u544a\u77e5\u5bf9\u65b9&#xff0c;\u5e76\u4fdd\u7559\u660e\u786e\u7684\u9000\u51fa\u65b9\u5f0f&#xff0c;\u907f\u514d\u5f71\u54cd\u6b63\u5e38\u4f7f\u7528\u3002<\/p>\n<\/p>\n<p>\u4e03\u3001HTML \u7248\u672c\u7684\u5b9e\u73b0\u5dee\u5f02<\/p>\n<p>\u7f51\u9875\u7248\u672c\u4e0e\u684c\u9762\u7248\u7684\u4ea4\u4e92\u903b\u8f91\u57fa\u672c\u4e00\u81f4&#xff0c;\u4f46\u5b9e\u73b0\u65b9\u5f0f\u4e0d\u540c&#xff1a;<\/p>\n<p>| \u529f\u80fd | PySide6 \u7248\u672c | HTML \u7248\u672c |<br \/>\n|&#8212;|&#8212;|&#8212;|<br \/>\n| \u56fe\u5f62\u7ed8\u5236 | QPainter | Canvas 2D |<br \/>\n| \u52a8\u753b\u5237\u65b0 | QTimer | requestAnimationFrame |<br \/>\n| \u9f20\u6807\u4f4d\u7f6e | QCursor | mousemove \u4e8b\u4ef6 |<br \/>\n| \u6309\u94ae\u79fb\u52a8 | QWidget.move | \u4fee\u6539 CSS left\/top |<br \/>\n| \u7231\u5fc3\u52a8\u753b | QPainter \u7ed8\u5236 | \u52a8\u6001\u521b\u5efa DOM \u5143\u7d20 |<br \/>\n| \u5173\u95ed\u63d0\u793a | closeEvent | beforeunload |<\/p>\n<p>HTML \u52a8\u753b\u5faa\u73af\u5982\u4e0b&#xff1a;<\/p>\n<p>&#096;&#096;&#096;javascript<br \/>\nfunction loop() {<br \/>\n\u00a0 updateEmotion();<br \/>\n\u00a0 moveNoButton();<br \/>\n\u00a0 draw();<br \/>\n\u00a0 requestAnimationFrame(loop);<br \/>\n}<\/p>\n<p>loop();<br \/>\n&#096;&#096;&#096;<\/p>\n<p>&#096;requestAnimationFrame&#096; \u4f1a\u5728\u6d4f\u89c8\u5668\u51c6\u5907\u4e0b\u4e00\u5e27\u753b\u9762\u65f6\u8c03\u7528\u56de\u8c03\u51fd\u6570&#xff0c;\u6bd4\u56fa\u5b9a\u65f6\u95f4\u95f4\u9694\u66f4\u9002\u5408\u7f51\u9875\u52a8\u753b\u3002<\/p>\n<p>\u9700\u8981\u6ce8\u610f&#xff1a;\u4e0d\u540c\u6d4f\u89c8\u5668\u5bf9\u79bb\u5f00\u9875\u9762\u63d0\u793a\u7684\u5904\u7406\u65b9\u5f0f\u4e0d\u540c&#xff0c;\u6d4f\u89c8\u5668\u53ef\u80fd\u53ea\u663e\u793a\u7edf\u4e00\u63d0\u793a&#xff0c;\u800c\u4e0d\u4f1a\u663e\u793a\u4ee3\u7801\u4e2d\u81ea\u5b9a\u4e49\u7684\u6587\u5b57\u3002<\/p>\n<\/p>\n<p>\u516b\u3001\u5e38\u89c1\u95ee\u9898<\/p>\n<p>1. \u63d0\u793a &#096;No module named &#039;PySide6&#039;&#096;<\/p>\n<p>\u8bf4\u660e\u5f53\u524d Python \u73af\u5883\u6ca1\u6709\u5b89\u88c5 PySide6&#xff1a;<\/p>\n<p>&#096;&#096;&#096;bash<br \/>\npython -m pip install PySide6<br \/>\n&#096;&#096;&#096;<\/p>\n<p>\u5b89\u88c5\u540e\u91cd\u65b0\u8fd0\u884c\u3002<\/p>\n<p>2. \u5df2\u5b89\u88c5 PySide6&#xff0c;\u8fd0\u884c\u65f6\u4ecd\u7136\u62a5\u9519<\/p>\n<p>\u53ef\u80fd\u662f &#096;pip&#096; \u548c &#096;python&#096; \u5bf9\u5e94\u7684\u4e0d\u662f\u540c\u4e00\u4e2a\u73af\u5883\u3002\u6267\u884c&#xff1a;<\/p>\n<p>&#096;&#096;&#096;bash<br \/>\npython -m pip show PySide6<br \/>\n&#096;&#096;&#096;<\/p>\n<p>\u5982\u679c\u6ca1\u6709\u8f93\u51fa&#xff0c;\u518d\u6267\u884c&#xff1a;<\/p>\n<p>&#096;&#096;&#096;bash<br \/>\npython -m pip install PySide6<br \/>\n&#096;&#096;&#096;<\/p>\n<p>3. \u53cc\u51fb Python \u6587\u4ef6\u4e00\u95ea\u800c\u8fc7<\/p>\n<p>\u4e0d\u8981\u76f4\u63a5\u53cc\u51fb&#xff0c;\u5efa\u8bae\u5728\u7ec8\u7aef\u8fd0\u884c&#xff1a;<\/p>\n<p>&#096;&#096;&#096;bash<br \/>\npython confession_reactive_window.py<br \/>\n&#096;&#096;&#096;<\/p>\n<p>\u8fd9\u6837\u53ef\u4ee5\u770b\u5230\u5177\u4f53\u62a5\u9519\u4fe1\u606f\u3002<\/p>\n<p>4. \u4e2d\u6587\u5b57\u4f53\u663e\u793a\u5f02\u5e38<\/p>\n<p>\u9879\u76ee\u9ed8\u8ba4\u4f7f\u7528\u201cMicrosoft YaHei UI\u201d\u3002\u5982\u679c\u7cfb\u7edf\u4e2d\u6ca1\u6709\u8be5\u5b57\u4f53&#xff0c;\u53ef\u4ee5\u6539\u4e3a&#xff1a;<\/p>\n<p>&#096;&#096;&#096;python<br \/>\nQFont(&#034;SimHei&#034;, 18, QFont.Bold)<br \/>\n&#096;&#096;&#096;<\/p>\n<p>Linux \u4e0b\u4e5f\u53ef\u4ee5\u6539\u6210\u7cfb\u7edf\u4e2d\u5df2\u5b89\u88c5\u7684\u4e2d\u6587\u5b57\u4f53\u3002<\/p>\n<p>5. HTML \u9875\u9762\u53ef\u4ee5\u76f4\u63a5\u53d1\u7ed9\u522b\u4eba\u5417&#xff1f;<\/p>\n<p>\u53ef\u4ee5\u3002HTML \u6587\u4ef6\u5df2\u7ecf\u5305\u542b CSS \u548c JavaScript&#xff0c;\u4e0d\u4f9d\u8d56\u5176\u4ed6\u672c\u5730\u6587\u4ef6\u3002\u5bf9\u65b9\u4e0b\u8f7d\u540e\u53cc\u51fb\u5373\u53ef\u6253\u5f00\u3002<\/p>\n<p>6. \u53ef\u4ee5\u6253\u5305\u6210 EXE \u5417&#xff1f;<\/p>\n<p>\u53ef\u4ee5\u4f7f\u7528 PyInstaller&#xff1a;<\/p>\n<p>&#096;&#096;&#096;bash<br \/>\npip install pyinstaller<br \/>\npyinstaller &#8211;onefile &#8211;windowed confession_reactive_window.py<br \/>\n&#096;&#096;&#096;<\/p>\n<p>\u751f\u6210\u7ed3\u679c\u4f4d\u4e8e&#xff1a;<\/p>\n<p>&#096;&#096;&#096;text<br \/>\ndist\/confession_reactive_window.exe<br \/>\n&#096;&#096;&#096;<\/p>\n<p>\u5982\u679c\u60f3\u8bbe\u7f6e\u56fe\u6807&#xff1a;<\/p>\n<p>&#096;&#096;&#096;bash<br \/>\npyinstaller &#8211;onefile &#8211;windowed &#8211;icon&#061;app.ico confession_reactive_window.py<br \/>\n&#096;&#096;&#096;<\/p>\n<\/p>\n<p>\u4e5d\u3001\u53ef\u4ee5\u7ee7\u7eed\u6269\u5c55\u7684\u529f\u80fd<\/p>\n<p>\u8fd9\u4e2a\u9879\u76ee\u8fd8\u53ef\u4ee5\u7ee7\u7eed\u52a0\u5165&#xff1a;<\/p>\n<p>1. \u80cc\u666f\u97f3\u4e50\u4e0e\u97f3\u6548&#xff1b;<br \/>\n2. \u81ea\u5b9a\u4e49\u59d3\u540d\u548c\u544a\u767d\u6587\u5b57&#xff1b;<br \/>\n3. \u8f93\u5165\u6846\u751f\u6210\u4e13\u5c5e\u7248\u672c&#xff1b;<br \/>\n4. \u66f4\u591a\u8868\u60c5\u72b6\u6001&#xff0c;\u4f8b\u5982\u5bb3\u7f9e\u3001\u60ca\u8bb6\u3001\u59d4\u5c48&#xff1b;<br \/>\n5. \u7c92\u5b50\u70df\u82b1\u52a8\u753b&#xff1b;<br \/>\n6. \u8bb0\u5f55\u6309\u94ae\u88ab\u8eb2\u907f\u7684\u6b21\u6570&#xff1b;<br \/>\n7. \u624b\u673a\u7aef\u89e6\u6478\u9002\u914d&#xff1b;<br \/>\n8. PyInstaller \u4e00\u952e\u6253\u5305&#xff1b;<br \/>\n9. \u5c06 HTML \u90e8\u7f72\u5230 GitHub Pages&#xff1b;<br \/>\n10. \u751f\u6210\u4e8c\u7ef4\u7801\u4f9b\u624b\u673a\u626b\u7801\u6253\u5f00\u3002<\/p>\n<\/p>\n<p>\u5341\u3001\u9879\u76ee\u603b\u7ed3<\/p>\n<p>\u8fd9\u4e2a\u9879\u76ee\u867d\u7136\u4f53\u91cf\u4e0d\u5927&#xff0c;\u4f46\u6db5\u76d6\u4e86 GUI \u548c\u524d\u7aef\u52a8\u753b\u4e2d\u7684\u591a\u4e2a\u57fa\u7840\u77e5\u8bc6\u70b9&#xff1a;<\/p>\n<p>&#8211; \u9f20\u6807\u4ea4\u4e92&#xff1b;<br \/>\n&#8211; \u52a8\u753b\u5faa\u73af&#xff1b;<br \/>\n&#8211; \u8ddd\u79bb\u8ba1\u7b97&#xff1b;<br \/>\n&#8211; \u5e73\u6ed1\u63d2\u503c&#xff1b;<br \/>\n&#8211; \u81ea\u5b9a\u4e49\u7ed8\u56fe&#xff1b;<br \/>\n&#8211; \u7a97\u53e3\u4e8b\u4ef6&#xff1b;<br \/>\n&#8211; DOM \u64cd\u4f5c&#xff1b;<br \/>\n&#8211; Canvas \u7ed8\u56fe&#xff1b;<br \/>\n&#8211; \u7b80\u5355\u72b6\u6001\u673a\u8bbe\u8ba1\u3002<\/p>\n<p>\u76f8\u6bd4\u53ea\u4f7f\u7528\u9759\u6001\u56fe\u7247&#xff0c;\u8fd9\u79cd\u5b8c\u5168\u901a\u8fc7\u4ee3\u7801\u7ed8\u5236\u5e76\u5b9e\u65f6\u53d8\u5316\u7684\u8868\u60c5\u66f4\u6709\u4e92\u52a8\u611f&#xff0c;\u4e5f\u5f88\u9002\u5408\u4f5c\u4e3a Python GUI\u3001PySide6 \u6216 JavaScript Canvas \u7684\u5165\u95e8\u7ec3\u4e60\u3002<\/p>\n<p>\u5982\u679c\u8fd9\u7bc7\u6587\u7ae0\u5bf9\u4f60\u6709\u5e2e\u52a9&#xff0c;\u6b22\u8fce\u70b9\u8d5e\u3001\u6536\u85cf\u548c\u8bc4\u8bba\u3002\u540e\u7eed\u8fd8\u53ef\u4ee5\u7ee7\u7eed\u5c1d\u8bd5\u589e\u52a0\u97f3\u4e50\u3001\u914d\u7f6e\u9875\u9762\u3001EXE \u6253\u5305\u548c\u5728\u7ebf\u90e8\u7f72\u529f\u80fd\u3002<\/p>\n<\/p>\n<p>\u9644\u5f55&#xff1a;<\/p>\n<p>-\u9879\u76ee\u5b8c\u6574\u4ee3\u7801<\/p>\n<p>import math<br \/>\nimport random<br \/>\nimport sys<\/p>\n<p>from PySide6.QtCore import QEvent, QPointF, QRectF, Qt, QTimer<br \/>\nfrom PySide6.QtGui import QColor, QCursor, QFont, QLinearGradient, QPainter, QPainterPath, QPen, QRadialGradient<br \/>\nfrom PySide6.QtWidgets import QApplication, QLabel, QPushButton, QWidget<\/p>\n<p>def clamp(value, low&#061;0.0, high&#061;1.0):<br \/>\n    return max(low, min(high, value))<\/p>\n<p>class ReactiveConfessionWindow(QWidget):<br \/>\n    def __init__(self):<br \/>\n        super().__init__()<br \/>\n        self.setWindowTitle(&#034;\u4e00\u4e2a\u5c0f\u95ee\u9898&#034;)<br \/>\n        self.setFixedSize(520, 420)<br \/>\n        self.setStyleSheet(&#034;background: #fff4f8;&#034;)<\/p>\n<p>        self.intensity &#061; 0.0<br \/>\n        self.happiness &#061; 0.0<br \/>\n        self.target_no_pos &#061; QPointF(314, 328)<br \/>\n        self.hearts &#061; []<br \/>\n        self.accepted &#061; False<br \/>\n        self.tick_count &#061; 0<\/p>\n<p>        self.title &#061; QLabel(&#034;\u53ef\u4ee5\u5ac1\u7ed9\u6211\u561b&#xff1f;&#034;, self)<br \/>\n        self.title.setGeometry(0, 210, 520, 38)<br \/>\n        self.title.setAlignment(Qt.AlignCenter)<br \/>\n        self.title.setStyleSheet(&#034;color: #3a2830; background: transparent;&#034;)<br \/>\n        self.title.setFont(QFont(&#034;Microsoft YaHei UI&#034;, 18, QFont.Bold))<\/p>\n<p>        self.tip &#061; QLabel(&#034;\u4e0d\u8981\u9760\u8fd1\u53f3\u8fb9&#xff0c;\u8868\u60c5\u4f1a\u751f\u6c14&#034;, self)<br \/>\n        self.tip.setGeometry(0, 250, 520, 28)<br \/>\n        self.tip.setAlignment(Qt.AlignCenter)<br \/>\n        self.tip.setStyleSheet(&#034;color: #9b5a70; background: transparent;&#034;)<br \/>\n        self.tip.setFont(QFont(&#034;Microsoft YaHei UI&#034;, 10))<\/p>\n<p>        self.yes_button &#061; QPushButton(&#034;\u613f\u610f&#034;, self)<br \/>\n        self.yes_button.setGeometry(120, 318, 110, 46)<br \/>\n        self.yes_button.clicked.connect(self.say_yes)<br \/>\n        self.yes_button.setStyleSheet(<br \/>\n            &#034;&#034;&#034;<br \/>\n            QPushButton {<br \/>\n                border: 0;<br \/>\n                border-radius: 20px;<br \/>\n                background: #ff7fa3;<br \/>\n                color: white;<br \/>\n                font: bold 15px &#034;Microsoft YaHei UI&#034;;<br \/>\n            }<br \/>\n            QPushButton:hover { background: #ff5f8e; }<br \/>\n            &#034;&#034;&#034;<br \/>\n        )<\/p>\n<p>        self.no_button &#061; QPushButton(&#034;\u4e0d\u613f\u610f&#034;, self)<br \/>\n        self.no_button.setGeometry(314, 318, 110, 46)<br \/>\n        self.no_button.clicked.connect(self.say_no)<br \/>\n        self.no_button.setStyleSheet(<br \/>\n            &#034;&#034;&#034;<br \/>\n            QPushButton {<br \/>\n                border: 2px solid #ffc3d2;<br \/>\n                border-radius: 20px;<br \/>\n                background: white;<br \/>\n                color: #6a3e4d;<br \/>\n                font: bold 15px &#034;Microsoft YaHei UI&#034;;<br \/>\n            }<br \/>\n            QPushButton:hover { background: #fff0f5; }<br \/>\n            &#034;&#034;&#034;<br \/>\n        )<\/p>\n<p>        self.timer &#061; QTimer(self)<br \/>\n        self.timer.timeout.connect(self.animate)<br \/>\n        self.timer.start(16)<\/p>\n<p>    def animate(self):<br \/>\n        self.tick_count &#043;&#061; 1<br \/>\n        if not self.accepted:<br \/>\n            self.update_intensity()<br \/>\n            self.move_no_button_if_needed()<br \/>\n        else:<br \/>\n            self.float_hearts()<br \/>\n        self.update()<\/p>\n<p>    def update_intensity(self):<br \/>\n        cursor &#061; self.mapFromGlobal(QCursor.pos())<br \/>\n        center &#061; self.no_button.geometry().center()<br \/>\n        dx &#061; cursor.x() &#8211; center.x()<br \/>\n        dy &#061; cursor.y() &#8211; center.y()<br \/>\n        distance &#061; math.hypot(dx, dy)<br \/>\n        target &#061; clamp(1 &#8211; (distance &#8211; 25) \/ 160)<br \/>\n        self.intensity &#043;&#061; (target &#8211; self.intensity) * 0.18<\/p>\n<p>        yes_center &#061; self.yes_button.geometry().center()<br \/>\n        yes_distance &#061; math.hypot(cursor.x() &#8211; yes_center.x(), cursor.y() &#8211; yes_center.y())<br \/>\n        happy_target &#061; clamp(1 &#8211; (yes_distance &#8211; 20) \/ 150)<br \/>\n        if self.intensity &gt; 0.15:<br \/>\n            happy_target *&#061; 0.25<br \/>\n        self.happiness &#043;&#061; (happy_target &#8211; self.happiness) * 0.16<\/p>\n<p>        if self.intensity &gt; 0.78:<br \/>\n            self.tip.setText(&#034;\u4e0d\u8bb8\u9760\u8fd1\u90a3\u4e2a\u6309\u94ae&#xff01;&#034;)<br \/>\n            self.tip.setStyleSheet(&#034;color: #b00020; background: transparent;&#034;)<br \/>\n        elif self.intensity &gt; 0.35:<br \/>\n            self.tip.setText(&#034;\u4f60\u662f\u4e0d\u662f\u60f3\u70b9\u53f3\u8fb9&#xff1f;&#034;)<br \/>\n            self.tip.setStyleSheet(&#034;color: #d9480f; background: transparent;&#034;)<br \/>\n        else:<br \/>\n            self.tip.setText(&#034;\u4e0d\u51c6\u9760\u8fd1\u53f3\u8fb9&#xff0c;\u8868\u60c5\u4f1a\u751f\u6c14\u751f\u6c14&#034;)<br \/>\n            self.tip.setStyleSheet(&#034;color: #9b5a70; background: transparent;&#034;)<\/p>\n<p>    def move_no_button_if_needed(self):<br \/>\n        cursor &#061; self.mapFromGlobal(QCursor.pos())<br \/>\n        rect &#061; self.no_button.geometry().adjusted(-90, -70, 90, 70)<br \/>\n        if rect.contains(cursor):<br \/>\n            candidates &#061; [<br \/>\n                QPointF(286, 300),<br \/>\n                QPointF(330, 350),<br \/>\n                QPointF(378, 302),<br \/>\n                QPointF(250, 350),<br \/>\n                QPointF(358, 334),<br \/>\n            ]<br \/>\n            self.target_no_pos &#061; max(candidates, key&#061;lambda p: math.hypot(p.x() &#043; 55 &#8211; cursor.x(), p.y() &#043; 23 &#8211; cursor.y()))<\/p>\n<p>        current &#061; QPointF(self.no_button.x(), self.no_button.y())<br \/>\n        distance_to_cursor &#061; math.hypot(current.x() &#043; 55 &#8211; cursor.x(), current.y() &#043; 23 &#8211; cursor.y())<br \/>\n        if distance_to_cursor &lt; 95:<br \/>\n            next_pos &#061; self.target_no_pos<br \/>\n        else:<br \/>\n            next_pos &#061; current &#043; (self.target_no_pos &#8211; current) * 0.55<br \/>\n        self.no_button.move(round(next_pos.x()), round(next_pos.y()))<\/p>\n<p>    def say_yes(self):<br \/>\n        self.accepted &#061; True<br \/>\n        self.intensity &#061; 0.0<br \/>\n        self.title.setText(&#034;\u563f\u563f&#xff0c;\u90a3\u5c31\u8bf4\u597d\u5566&#xff01;&#034;)<br \/>\n        self.tip.setText(&#034;\u4eca\u5929\u5f00\u59cb\u5c31\u662f\u6700\u7279\u522b\u7684\u4eba&#034;)<br \/>\n        self.tip.setStyleSheet(&#034;color: #d6336c; background: transparent;&#034;)<br \/>\n        self.no_button.hide()<br \/>\n        self.yes_button.setText(&#034;\u559c\u6b22\u4f60&#034;)<br \/>\n        self.hearts &#061; []<\/p>\n<p>    def say_no(self):<br \/>\n        self.intensity &#061; 1.0<br \/>\n        self.tip.setText(&#034;\u70b9\u9519\u4e86&#xff0c;\u91cd\u6765&#xff01;&#034;)<br \/>\n        self.shake()<\/p>\n<p>    def shake(self):<br \/>\n        start &#061; self.pos()<br \/>\n        offsets &#061; [8, -8, 6, -6, 3, -3, 0]<br \/>\n        for index, offset in enumerate(offsets):<br \/>\n            QTimer.singleShot(index * 35, lambda o&#061;offset: self.move(start.x() &#043; o, start.y()))<\/p>\n<p>    def float_hearts(self):<br \/>\n        if self.tick_count % 8 &#061;&#061; 0:<br \/>\n            self.hearts.append([random.randint(160, 360), 185, random.uniform(-0.8, 0.8), random.randint(18, 28)])<br \/>\n        next_hearts &#061; []<br \/>\n        for heart in self.hearts:<br \/>\n            heart[0] &#043;&#061; heart[2]<br \/>\n            heart[1] -&#061; 1.8<br \/>\n            heart[3] -&#061; 0.18<br \/>\n            if heart[1] &gt; 20 and heart[3] &gt; 4:<br \/>\n                next_hearts.append(heart)<br \/>\n        self.hearts &#061; next_hearts<\/p>\n<p>    def paintEvent(self, _event):<br \/>\n        painter &#061; QPainter(self)<br \/>\n        painter.setRenderHint(QPainter.Antialiasing)<br \/>\n        self.draw_background(painter)<br \/>\n        self.draw_face(painter)<br \/>\n        self.draw_hearts(painter)<\/p>\n<p>    def draw_background(self, p):<br \/>\n        gradient &#061; QLinearGradient(0, 0, 0, self.height())<br \/>\n        gradient.setColorAt(0, QColor(&#034;#fff7fb&#034;))<br \/>\n        gradient.setColorAt(1, QColor(&#034;#ffeaf1&#034;))<br \/>\n        p.fillRect(self.rect(), gradient)<\/p>\n<p>    def draw_face(self, p):<br \/>\n        anger &#061; self.intensity<br \/>\n        cx, cy &#061; 260, 116<br \/>\n        face_w &#061; 154 &#043; anger * 8<br \/>\n        face_h &#061; 142 &#8211; anger * 4<\/p>\n<p>        face_color &#061; QColor(<br \/>\n            int(255),<br \/>\n            int(222 &#8211; anger * 42),<br \/>\n            int(138 &#8211; anger * 38),<br \/>\n        )<br \/>\n        face_gradient &#061; QRadialGradient(QPointF(cx &#8211; 26, cy &#8211; 36), 145)<br \/>\n        face_gradient.setColorAt(0, QColor(&#034;#fff4b8&#034;))<br \/>\n        face_gradient.setColorAt(1, face_color)<br \/>\n        p.setBrush(face_gradient)<br \/>\n        p.setPen(QPen(QColor(&#034;#2b2424&#034;), 4))<br \/>\n        p.drawEllipse(QRectF(cx &#8211; face_w \/ 2, cy &#8211; face_h \/ 2, face_w, face_h))<\/p>\n<p>        cursor &#061; self.mapFromGlobal(QCursor.pos())<br \/>\n        dx &#061; cursor.x() &#8211; cx<br \/>\n        dy &#061; cursor.y() &#8211; cy<br \/>\n        distance &#061; max(1, math.hypot(dx, dy))<br \/>\n        eye_dx &#061; dx \/ distance * (5 &#8211; anger * 2)<br \/>\n        eye_dy &#061; dy \/ distance * (4 &#8211; anger * 1.5)<\/p>\n<p>        p.setPen(QPen(QColor(&#034;#2b2424&#034;), 5, Qt.SolidLine, Qt.RoundCap))<br \/>\n        brow_outer_y &#061; 78 &#043; anger * 2<br \/>\n        brow_inner_y &#061; 78 &#043; anger * 18<br \/>\n        brow_outer_offset &#061; 15<br \/>\n        brow_inner_offset &#061; 15<br \/>\n        left_brow_center &#061; 217<br \/>\n        right_brow_center &#061; 303<br \/>\n        p.drawLine(<br \/>\n            QPointF(left_brow_center &#8211; brow_outer_offset, brow_outer_y),<br \/>\n            QPointF(left_brow_center &#043; brow_inner_offset, brow_inner_y),<br \/>\n        )<br \/>\n        p.drawLine(<br \/>\n            QPointF(right_brow_center &#8211; brow_inner_offset, brow_inner_y),<br \/>\n            QPointF(right_brow_center &#043; brow_outer_offset, brow_outer_y),<br \/>\n        )<\/p>\n<p>        self.draw_eye(p, 218, 103, eye_dx, eye_dy, anger)<br \/>\n        self.draw_eye(p, 302, 103, eye_dx, eye_dy, anger)<\/p>\n<p>        blush &#061; QColor(&#034;#ff8fab&#034;)<br \/>\n        blush.setAlphaF(0.45 &#043; anger * 0.35)<br \/>\n        p.setPen(Qt.NoPen)<br \/>\n        p.setBrush(blush)<br \/>\n        p.drawEllipse(QRectF(172, 120, 38 &#043; anger * 8, 22))<br \/>\n        p.drawEllipse(QRectF(310, 120, 38 &#043; anger * 8, 22))<\/p>\n<p>        p.setPen(QPen(QColor(&#034;#2b2424&#034;), 5, Qt.SolidLine, Qt.RoundCap))<br \/>\n        p.setBrush(Qt.NoBrush)<br \/>\n        self.draw_mouth(p, anger, self.happiness)<\/p>\n<p>        if anger &gt; 0.55:<br \/>\n            p.setFont(QFont(&#034;Microsoft YaHei UI&#034;, 20, QFont.Bold))<br \/>\n            p.setPen(QColor(&#034;#b00020&#034;))<br \/>\n            p.drawText(QRectF(238, 38, 44, 34), Qt.AlignCenter, &#034;No&#034;)<\/p>\n<p>    def draw_eye(self, p, cx, cy, dx, dy, anger):<br \/>\n        eye_w &#061; 24 &#8211; anger * 3<br \/>\n        eye_h &#061; 31 &#8211; anger * 7<br \/>\n        p.setPen(QPen(QColor(&#034;#2b2424&#034;), 3))<br \/>\n        p.setBrush(QColor(&#034;#1f1f1f&#034;))<br \/>\n        p.drawEllipse(QRectF(cx &#8211; eye_w \/ 2 &#043; dx, cy &#8211; eye_h \/ 2 &#043; dy, eye_w, eye_h))<br \/>\n        p.setPen(Qt.NoPen)<br \/>\n        p.setBrush(QColor(&#034;#ffffff&#034;))<br \/>\n        p.drawEllipse(QRectF(cx &#8211; 5 &#043; dx, cy &#8211; 10 &#043; dy, 9, 8))<br \/>\n        p.drawEllipse(QRectF(cx &#043; 2 &#043; dx, cy &#043; 4 &#043; dy, 6, 5))<\/p>\n<p>    def draw_mouth(self, p, anger, happiness):<br \/>\n        left &#061; QPointF(222, 136)<br \/>\n        right &#061; QPointF(298, 136)<br \/>\n        smile_control &#061; QPointF(260, 140 &#043; happiness * 24)<br \/>\n        flat_control &#061; QPointF(260, 137)<br \/>\n        frown_control &#061; QPointF(260, 116)<\/p>\n<p>        if anger &lt; 0.45:<br \/>\n            amount &#061; anger \/ 0.45<br \/>\n            control &#061; QPointF(<br \/>\n                smile_control.x() &#043; (flat_control.x() &#8211; smile_control.x()) * amount,<br \/>\n                smile_control.y() &#043; (flat_control.y() &#8211; smile_control.y()) * amount,<br \/>\n            )<br \/>\n        else:<br \/>\n            amount &#061; (anger &#8211; 0.45) \/ 0.55<br \/>\n            control &#061; QPointF(<br \/>\n                flat_control.x() &#043; (frown_control.x() &#8211; flat_control.x()) * amount,<br \/>\n                flat_control.y() &#043; (frown_control.y() &#8211; flat_control.y()) * amount,<br \/>\n            )<\/p>\n<p>        mouth &#061; QPainterPath()<br \/>\n        mouth.moveTo(left)<br \/>\n        mouth.quadTo(control, right)<br \/>\n        p.drawPath(mouth)<\/p>\n<p>    def draw_hearts(self, p):<br \/>\n        if not self.accepted:<br \/>\n            return<br \/>\n        p.setFont(QFont(&#034;Arial&#034;, 22, QFont.Bold))<br \/>\n        p.setPen(QColor(&#034;#ff4d6d&#034;))<br \/>\n        for x, y, _speed, size in self.hearts:<br \/>\n            p.setFont(QFont(&#034;Arial&#034;, int(size), QFont.Bold))<br \/>\n            p.drawText(QPointF(x, y), &#034;\u2665&#034;)<\/p>\n<p>    def closeEvent(self, event):<br \/>\n        if self.accepted:<br \/>\n            event.accept()<br \/>\n            return<br \/>\n        event.ignore()<br \/>\n        self.intensity &#061; 1.0<br \/>\n        self.tip.setText(&#034;\u5148\u70b9\u613f\u610f\u624d\u53ef\u4ee5\u5173\u95ed&#034;)<br \/>\n        self.tip.setStyleSheet(&#034;color: #b00020; background: transparent;&#034;)<br \/>\n        self.shake()<\/p>\n<p>    def changeEvent(self, event):<br \/>\n        if event.type() &#061;&#061; QEvent.WindowStateChange and not self.accepted:<br \/>\n            if self.windowState() &amp; Qt.WindowMinimized:<br \/>\n                QTimer.singleShot(0, self.restore_from_minimize)<br \/>\n        super().changeEvent(event)<\/p>\n<p>    def restore_from_minimize(self):<br \/>\n        self.setWindowState(self.windowState() &amp; ~Qt.WindowMinimized)<br \/>\n        self.showNormal()<br \/>\n        self.raise_()<br \/>\n        self.activateWindow()<br \/>\n        self.intensity &#061; 1.0<br \/>\n        self.tip.setText(&#034;\u5148\u70b9\u613f\u610f\u624d\u53ef\u4ee5\u6700\u5c0f\u5316&#034;)<br \/>\n        self.tip.setStyleSheet(&#034;color: #b00020; background: transparent;&#034;)<br \/>\n        self.shake()<\/p>\n<p>def main():<br \/>\n    app &#061; QApplication(sys.argv)<br \/>\n    window &#061; ReactiveConfessionWindow()<br \/>\n    window.show()<br \/>\n    sys.exit(app.exec())<\/p>\n<p>if __name__ &#061;&#061; &#034;__main__&#034;:<br \/>\n    main()<\/p>\n<p>-HTML \u7248\u5b8c\u6574\u4ee3\u7801<\/p>\n<p>&lt;!doctype html&gt;<br \/>\n&lt;html lang&#061;&#034;zh-CN&#034;&gt;<br \/>\n&lt;head&gt;<br \/>\n  &lt;meta charset&#061;&#034;utf-8&#034; \/&gt;<br \/>\n  &lt;meta name&#061;&#034;viewport&#034; content&#061;&#034;width&#061;device-width, initial-scale&#061;1&#034; \/&gt;<br \/>\n  &lt;title&gt;\u4e00\u4e2a\u5c0f\u95ee\u9898&lt;\/title&gt;<br \/>\n  &lt;style&gt;<br \/>\n    * { box-sizing: border-box; }<br \/>\n    body {<br \/>\n      min-height: 100vh;<br \/>\n      margin: 0;<br \/>\n      display: grid;<br \/>\n      place-items: center;<br \/>\n      overflow: hidden;<br \/>\n      background: linear-gradient(180deg, #fff8fb 0%, #ffeaf1 100%);<br \/>\n      font-family: &#034;Microsoft YaHei UI&#034;, system-ui, sans-serif;<br \/>\n      color: #2b2424;<br \/>\n    }<br \/>\n    .card {<br \/>\n      width: min(520px, calc(100vw &#8211; 28px));<br \/>\n      padding: 22px 24px 28px;<br \/>\n      border-radius: 28px;<br \/>\n      background: rgba(255, 255, 255, 0.72);<br \/>\n      box-shadow: 0 26px 80px rgba(255, 117, 156, 0.24);<br \/>\n      text-align: center;<br \/>\n      user-select: none;<br \/>\n    }<br \/>\n    canvas { width: 100%; height: 190px; display: block; }<br \/>\n    h1 { margin: 4px 0 8px; font-size: 26px; }<br \/>\n    .tip { height: 26px; margin: 0 0 22px; color: #9b5a70; font-weight: 600; }<br \/>\n    .buttons { position: relative; height: 78px; }<br \/>\n    button {<br \/>\n      position: absolute;<br \/>\n      top: 14px;<br \/>\n      width: 118px;<br \/>\n      height: 48px;<br \/>\n      border-radius: 24px;<br \/>\n      font: 700 16px &#034;Microsoft YaHei UI&#034;, system-ui, sans-serif;<br \/>\n      cursor: pointer;<br \/>\n    }<br \/>\n    #yesBtn {<br \/>\n      left: 88px;<br \/>\n      border: 0;<br \/>\n      color: #fff;<br \/>\n      background: #ff7fa3;<br \/>\n      box-shadow: 0 12px 22px rgba(255, 95, 142, 0.28);<br \/>\n    }<br \/>\n    #yesBtn:hover { background: #ff5f8e; }<br \/>\n    #noBtn {<br \/>\n      left: 296px;<br \/>\n      border: 2px solid #ffc3d2;<br \/>\n      color: #6a3e4d;<br \/>\n      background: #fff;<br \/>\n    }<br \/>\n    .shake { animation: shake 260ms linear; }<br \/>\n    &#064;keyframes shake {<br \/>\n      0%, 100% { transform: translateX(0); }<br \/>\n      20% { transform: translateX(8px); }<br \/>\n      40% { transform: translateX(-8px); }<br \/>\n      60% { transform: translateX(5px); }<br \/>\n      80% { transform: translateX(-5px); }<br \/>\n    }<br \/>\n    .heart {<br \/>\n      position: fixed;<br \/>\n      color: #ff4d6d;<br \/>\n      font: 800 24px Arial, sans-serif;<br \/>\n      pointer-events: none;<br \/>\n      animation: floatUp 1.8s ease-out forwards;<br \/>\n    }<br \/>\n    &#064;keyframes floatUp {<br \/>\n      from { transform: translateY(0) scale(0.8); opacity: 1; }<br \/>\n      to { transform: translateY(-120px) scale(1.35); opacity: 0; }<br \/>\n    }<br \/>\n  &lt;\/style&gt;<br \/>\n&lt;\/head&gt;<br \/>\n&lt;body&gt;<br \/>\n  &lt;main class&#061;&#034;card&#034; id&#061;&#034;card&#034;&gt;<br \/>\n    &lt;canvas id&#061;&#034;face&#034; width&#061;&#034;520&#034; height&#061;&#034;190&#034;&gt;&lt;\/canvas&gt;<br \/>\n    &lt;h1 id&#061;&#034;title&#034;&gt;\u53ef\u4ee5\u548c\u6211\u5728\u4e00\u8d77\u5417&#xff1f;&lt;\/h1&gt;<br \/>\n    &lt;p class&#061;&#034;tip&#034; id&#061;&#034;tip&#034;&gt;\u9f20\u6807\u8d8a\u9760\u8fd1\u53f3\u8fb9&#xff0c;\u8868\u60c5\u8d8a\u751f\u6c14&lt;\/p&gt;<br \/>\n    &lt;div class&#061;&#034;buttons&#034; id&#061;&#034;buttonArea&#034;&gt;<br \/>\n      &lt;button id&#061;&#034;yesBtn&#034;&gt;\u613f\u610f&lt;\/button&gt;<br \/>\n      &lt;button id&#061;&#034;noBtn&#034;&gt;\u4e0d\u613f\u610f&lt;\/button&gt;<br \/>\n    &lt;\/div&gt;<br \/>\n  &lt;\/main&gt;<\/p>\n<p>  &lt;script&gt;<br \/>\n    const canvas &#061; document.getElementById(&#034;face&#034;);<br \/>\n    const ctx &#061; canvas.getContext(&#034;2d&#034;);<br \/>\n    const card &#061; document.getElementById(&#034;card&#034;);<br \/>\n    const title &#061; document.getElementById(&#034;title&#034;);<br \/>\n    const tip &#061; document.getElementById(&#034;tip&#034;);<br \/>\n    const buttonArea &#061; document.getElementById(&#034;buttonArea&#034;);<br \/>\n    const yesBtn &#061; document.getElementById(&#034;yesBtn&#034;);<br \/>\n    const noBtn &#061; document.getElementById(&#034;noBtn&#034;);<\/p>\n<p>    const mouse &#061; { x: 260, y: 95, pageX: innerWidth \/ 2, pageY: innerHeight \/ 2 };<br \/>\n    let anger &#061; 0, happiness &#061; 0, accepted &#061; false;<br \/>\n    let noTarget &#061; { x: 296, y: 14 };<\/p>\n<p>    window.addEventListener(&#034;mousemove&#034;, (event) &#061;&gt; {<br \/>\n      mouse.pageX &#061; event.clientX;<br \/>\n      mouse.pageY &#061; event.clientY;<br \/>\n      const rect &#061; canvas.getBoundingClientRect();<br \/>\n      mouse.x &#061; (event.clientX &#8211; rect.left) * (canvas.width \/ rect.width);<br \/>\n      mouse.y &#061; (event.clientY &#8211; rect.top) * (canvas.height \/ rect.height);<br \/>\n    });<\/p>\n<p>    window.addEventListener(&#034;beforeunload&#034;, (event) &#061;&gt; {<br \/>\n      if (!accepted) {<br \/>\n        event.preventDefault();<br \/>\n        event.returnValue &#061; &#034;\u5148\u70b9\u613f\u610f\u624d\u53ef\u4ee5\u79bb\u5f00\u54e6&#034;;<br \/>\n      }<br \/>\n    });<\/p>\n<p>    yesBtn.onclick &#061; () &#061;&gt; {<br \/>\n      accepted &#061; true;<br \/>\n      anger &#061; 0;<br \/>\n      title.textContent &#061; &#034;\u563f\u563f&#xff0c;\u90a3\u5c31\u8bf4\u597d\u5566&#xff01;&#034;;<br \/>\n      tip.textContent &#061; &#034;\u4eca\u5929\u5f00\u59cb\u5c31\u662f\u7279\u522b\u7684\u4eba&#034;;<br \/>\n      tip.style.color &#061; &#034;#d6336c&#034;;<br \/>\n      yesBtn.textContent &#061; &#034;\u559c\u6b22\u4f60&#034;;<br \/>\n      noBtn.style.display &#061; &#034;none&#034;;<br \/>\n      for (let i &#061; 0; i &lt; 18; i&#043;&#043;) setTimeout(spawnHeart, i * 90);<br \/>\n    };<\/p>\n<p>    noBtn.onclick &#061; () &#061;&gt; {<br \/>\n      anger &#061; 1;<br \/>\n      tip.textContent &#061; &#034;\u70b9\u9519\u4e86&#xff0c;\u91cd\u6765&#xff01;&#034;;<br \/>\n      tip.style.color &#061; &#034;#b00020&#034;;<br \/>\n      card.classList.remove(&#034;shake&#034;);<br \/>\n      void card.offsetWidth;<br \/>\n      card.classList.add(&#034;shake&#034;);<br \/>\n      dodgeNoButton(true);<br \/>\n    };<\/p>\n<p>    function clamp(v, lo &#061; 0, hi &#061; 1) { return Math.max(lo, Math.min(hi, v)); }<br \/>\n    function center(el) {<br \/>\n      const r &#061; el.getBoundingClientRect();<br \/>\n      return { x: r.left &#043; r.width \/ 2, y: r.top &#043; r.height \/ 2 };<br \/>\n    }<\/p>\n<p>    function updateEmotion() {<br \/>\n      if (accepted) {<br \/>\n        happiness &#043;&#061; (1 &#8211; happiness) * 0.08;<br \/>\n        anger &#043;&#061; (0 &#8211; anger) * 0.16;<br \/>\n        return;<br \/>\n      }<br \/>\n      const nc &#061; center(noBtn);<br \/>\n      const nd &#061; Math.hypot(mouse.pageX &#8211; nc.x, mouse.pageY &#8211; nc.y);<br \/>\n      const angerTarget &#061; clamp(1 &#8211; (nd &#8211; 18) \/ 170);<br \/>\n      anger &#043;&#061; (angerTarget &#8211; anger) * 0.18;<\/p>\n<p>      const yc &#061; center(yesBtn);<br \/>\n      const yd &#061; Math.hypot(mouse.pageX &#8211; yc.x, mouse.pageY &#8211; yc.y);<br \/>\n      let happyTarget &#061; clamp(1 &#8211; (yd &#8211; 18) \/ 150);<br \/>\n      if (anger &gt; 0.15) happyTarget *&#061; 0.25;<br \/>\n      happiness &#043;&#061; (happyTarget &#8211; happiness) * 0.16;<\/p>\n<p>      if (anger &gt; 0.78) {<br \/>\n        tip.textContent &#061; &#034;\u4e0d\u8bb8\u9760\u8fd1\u90a3\u4e2a\u6309\u94ae&#xff01;&#034;;<br \/>\n        tip.style.color &#061; &#034;#b00020&#034;;<br \/>\n      } else if (anger &gt; 0.35) {<br \/>\n        tip.textContent &#061; &#034;\u4f60\u662f\u4e0d\u662f\u60f3\u70b9\u53f3\u8fb9&#xff1f;&#034;;<br \/>\n        tip.style.color &#061; &#034;#d9480f&#034;;<br \/>\n      } else {<br \/>\n        tip.textContent &#061; &#034;\u9f20\u6807\u8d8a\u9760\u8fd1\u53f3\u8fb9&#xff0c;\u8868\u60c5\u8d8a\u751f\u6c14&#034;;<br \/>\n        tip.style.color &#061; &#034;#9b5a70&#034;;<br \/>\n      }<br \/>\n    }<\/p>\n<p>    function dodgeNoButton(force &#061; false) {<br \/>\n      if (accepted) return;<br \/>\n      const area &#061; buttonArea.getBoundingClientRect();<br \/>\n      const r &#061; noBtn.getBoundingClientRect();<br \/>\n      const near &#061; r.left &#8211; 105 &lt; mouse.pageX &amp;&amp; mouse.pageX &lt; r.right &#043; 105 &amp;&amp;<br \/>\n                   r.top &#8211; 78 &lt; mouse.pageY &amp;&amp; mouse.pageY &lt; r.bottom &#043; 78;<br \/>\n      if (!force &amp;&amp; !near) return;<br \/>\n      const lx &#061; mouse.pageX &#8211; area.left, ly &#061; mouse.pageY &#8211; area.top;<br \/>\n      const candidates &#061; [<br \/>\n        { x: 246, y: 3 }, { x: 312, y: 26 }, { x: 366, y: 4 },<br \/>\n        { x: 222, y: 28 }, { x: 334, y: 8 }<br \/>\n      ];<br \/>\n      noTarget &#061; candidates.reduce((best, item) &#061;&gt; {<br \/>\n        const bd &#061; Math.hypot(best.x &#043; 59 &#8211; lx, best.y &#043; 24 &#8211; ly);<br \/>\n        const id &#061; Math.hypot(item.x &#043; 59 &#8211; lx, item.y &#043; 24 &#8211; ly);<br \/>\n        return id &gt; bd ? item : best;<br \/>\n      }, candidates[0]);<br \/>\n    }<\/p>\n<p>    function moveNoButton() {<br \/>\n      if (accepted) return;<br \/>\n      dodgeNoButton(false);<br \/>\n      const x0 &#061; parseFloat(noBtn.style.left || &#034;296&#034;);<br \/>\n      const y0 &#061; parseFloat(noBtn.style.top || &#034;14&#034;);<br \/>\n      const nc &#061; center(noBtn);<br \/>\n      const d &#061; Math.hypot(mouse.pageX &#8211; nc.x, mouse.pageY &#8211; nc.y);<br \/>\n      const speed &#061; d &lt; 98 ? 1 : 0.58;<br \/>\n      noBtn.style.left &#061; &#096;${x0 &#043; (noTarget.x &#8211; x0) * speed}px&#096;;<br \/>\n      noBtn.style.top &#061; &#096;${y0 &#043; (noTarget.y &#8211; y0) * speed}px&#096;;<br \/>\n    }<\/p>\n<p>    function draw() {<br \/>\n      ctx.clearRect(0, 0, canvas.width, canvas.height);<br \/>\n      const cx &#061; 260, cy &#061; 92;<br \/>\n      const faceW &#061; 154 &#043; anger * 8, faceH &#061; 142 &#8211; anger * 4;<br \/>\n      const grad &#061; ctx.createRadialGradient(cx &#8211; 26, cy &#8211; 36, 4, cx, cy, 145);<br \/>\n      grad.addColorStop(0, &#034;#fff4b8&#034;);<br \/>\n      grad.addColorStop(1, &#096;rgb(255, ${Math.round(222 &#8211; anger * 42)}, ${Math.round(138 &#8211; anger * 38)})&#096;);<br \/>\n      ctx.lineWidth &#061; 4; ctx.strokeStyle &#061; &#034;#2b2424&#034;; ctx.fillStyle &#061; grad;<br \/>\n      ellipse(cx, cy, faceW \/ 2, faceH \/ 2); ctx.fill(); ctx.stroke();<\/p>\n<p>      const dx &#061; mouse.x &#8211; cx, dy &#061; mouse.y &#8211; cy;<br \/>\n      const dist &#061; Math.max(1, Math.hypot(dx, dy));<br \/>\n      const eyeDx &#061; dx \/ dist * (5 &#8211; anger * 2);<br \/>\n      const eyeDy &#061; dy \/ dist * (4 &#8211; anger * 1.5);<br \/>\n      drawBrows(); drawEye(218, 100, eyeDx, eyeDy); drawEye(302, 100, eyeDx, eyeDy);<br \/>\n      drawBlush(); drawMouth();<br \/>\n      if (anger &gt; 0.55) {<br \/>\n        ctx.fillStyle &#061; &#034;#b00020&#034;;<br \/>\n        ctx.font &#061; &#034;bold 24px &#039;Microsoft YaHei UI&#039;&#034;;<br \/>\n        ctx.textAlign &#061; &#034;center&#034;;<br \/>\n        ctx.fillText(&#034;\u6012&#034;, cx, 52);<br \/>\n      }<br \/>\n    }<\/p>\n<p>    function ellipse(cx, cy, rx, ry) { ctx.beginPath(); ctx.ellipse(cx, cy, rx, ry, 0, 0, Math.PI * 2); }<br \/>\n    function line(x1, y1, x2, y2) { ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); ctx.stroke(); }<\/p>\n<p>    function drawBrows() {<br \/>\n      const outerY &#061; 56 &#043; anger * 2, innerY &#061; 56 &#043; anger * 18;<br \/>\n      ctx.strokeStyle &#061; &#034;#2b2424&#034;; ctx.lineWidth &#061; 5; ctx.lineCap &#061; &#034;round&#034;;<br \/>\n      line(187, outerY, 232, innerY);<br \/>\n      line(288, innerY, 333, outerY);<br \/>\n    }<\/p>\n<p>    function drawEye(cx, cy, dx, dy) {<br \/>\n      const w &#061; 24 &#8211; anger * 3, h &#061; 31 &#8211; anger * 7;<br \/>\n      ctx.strokeStyle &#061; &#034;#2b2424&#034;; ctx.lineWidth &#061; 3; ctx.fillStyle &#061; &#034;#1f1f1f&#034;;<br \/>\n      ellipse(cx &#043; dx, cy &#043; dy, w \/ 2, h \/ 2); ctx.fill(); ctx.stroke();<br \/>\n      ctx.fillStyle &#061; &#034;white&#034;;<br \/>\n      ellipse(cx &#8211; 5 &#043; dx, cy &#8211; 10 &#043; dy, 4.5, 4); ctx.fill();<br \/>\n      ellipse(cx &#043; 4 &#043; dx, cy &#043; 4 &#043; dy, 3, 2.5); ctx.fill();<br \/>\n    }<\/p>\n<p>    function drawBlush() {<br \/>\n      ctx.fillStyle &#061; &#096;rgba(255, 143, 171, ${0.45 &#043; anger * 0.35})&#096;;<br \/>\n      ellipse(191, 120, 19 &#043; anger * 4, 11); ctx.fill();<br \/>\n      ellipse(329, 120, 19 &#043; anger * 4, 11); ctx.fill();<br \/>\n    }<\/p>\n<p>    function drawMouth() {<br \/>\n      const smileY &#061; 139 &#043; happiness * 25, flatY &#061; 136, frownY &#061; 115;<br \/>\n      let controlY;<br \/>\n      if (anger &lt; 0.45) controlY &#061; smileY &#043; (flatY &#8211; smileY) * (anger \/ 0.45);<br \/>\n      else controlY &#061; flatY &#043; (frownY &#8211; flatY) * ((anger &#8211; 0.45) \/ 0.55);<br \/>\n      ctx.strokeStyle &#061; &#034;#2b2424&#034;; ctx.lineWidth &#061; 5; ctx.lineCap &#061; &#034;round&#034;;<br \/>\n      ctx.beginPath(); ctx.moveTo(222, 135); ctx.quadraticCurveTo(260, controlY, 298, 135); ctx.stroke();<br \/>\n    }<\/p>\n<p>    function spawnHeart() {<br \/>\n      const h &#061; document.createElement(&#034;div&#034;);<br \/>\n      h.className &#061; &#034;heart&#034;; h.textContent &#061; &#034;\u2665&#034;;<br \/>\n      h.style.left &#061; &#096;${innerWidth \/ 2 &#043; (Math.random() &#8211; 0.5) * 190}px&#096;;<br \/>\n      h.style.top &#061; &#096;${innerHeight \/ 2 &#8211; 10 &#043; (Math.random() &#8211; 0.5) * 60}px&#096;;<br \/>\n      document.body.appendChild(h); setTimeout(() &#061;&gt; h.remove(), 1900);<br \/>\n    }<\/p>\n<p>    function loop() { updateEmotion(); moveNoButton(); draw(); requestAnimationFrame(loop); }<br \/>\n    loop();<br \/>\n  &lt;\/script&gt;<br \/>\n&lt;\/body&gt;<br \/>\n&lt;\/html&gt;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u672c\u9879\u76ee\u4f7f\u7528 Python  PySide6 \u5236\u4f5c\u4e86\u4e00\u4e2a\u5177\u6709\u4e92\u52a8\u6548\u679c\u7684\u544a\u767d\u7a97\u53e3\u3002\u5f53\u9f20\u6807\u9760\u8fd1\u201c\u4e0d\u613f\u610f\u201d\u6309\u94ae\u65f6&#xff0c;\u6309\u94ae\u4f1a\u81ea\u52a8\u8eb2\u5f00&#xff0c;\u5361\u901a\u8868\u60c5\u4e5f\u4f1a\u9010\u6e10\u751f\u6c14&#xff1b;\u5f53\u9f20\u6807\u9760\u8fd1\u201c\u613f\u610f\u201d\u6309\u94ae\u65f6&#xff0c;\u8868\u60c5\u4f1a\u53d8\u5f00\u5fc3\u3002\u70b9\u51fb\u201c\u613f\u610f\u201d\u540e&#xff0c;\u7a97\u53e3\u4f1a\u663e\u793a\u7231\u5fc3\u52a8\u753b\u3002\u9879\u76ee\u540c\u65f6\u63d0\u4f9b\u4e00\u4e2a\u65e0\u9700\u5b89\u88c5\u4f9d\u8d56\u3001\u53cc\u51fb\u5373\u53ef\u8fd0\u884c\u7684 HTML \u7248\u672c\u3002\u4e00\u3001\u9879\u76ee\u6548\u679c\u8fd9\u4e2a\u5c0f\u9879\u76ee\u5e76\u4e0d\u662f\u4e00\u4e2a\u666e\u901a\u7684\u9759\u6001\u5f39\u7a97&#xff0c;\u800c\u662f\u52a0\u5165\u4e86\u591a\u79cd\u5b9e\u65f6\u4ea4\u4e92\u6548\u679c&#xff1a;- \u773c\u775b\u4f1a\u8ddf\u968f\u9f20\u6807\u79fb\u52a8&amp;<\/p>\n","protected":false},"author":2,"featured_media":88789,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[567,187,81,87,190],"topic":[],"class_list":["post-88792","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-server","tag-html","tag-javascript","tag-python","tag-87","tag-190"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.3 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Python + PySide6 \u5b9e\u73b0\u4f1a\u201c\u751f\u6c14\u201d\u7684\u544a\u767d\u7a97\u53e3\uff1a\u6309\u94ae\u8eb2\u907f\u3001\u8868\u60c5\u8ddf\u968f\u4e0e\u7231\u5fc3\u52a8\u753b\uff08\u9644\u5b8c\u6574\u4ee3\u7801\u3001 HTML \u7248\u3001\u9879\u76ee\u6587\u4ef6zip\uff09 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.wsisp.com\/helps\/88792.html\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Python + PySide6 \u5b9e\u73b0\u4f1a\u201c\u751f\u6c14\u201d\u7684\u544a\u767d\u7a97\u53e3\uff1a\u6309\u94ae\u8eb2\u907f\u3001\u8868\u60c5\u8ddf\u968f\u4e0e\u7231\u5fc3\u52a8\u753b\uff08\u9644\u5b8c\u6574\u4ee3\u7801\u3001 HTML \u7248\u3001\u9879\u76ee\u6587\u4ef6zip\uff09 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"og:description\" content=\"\u672c\u9879\u76ee\u4f7f\u7528 Python PySide6 \u5236\u4f5c\u4e86\u4e00\u4e2a\u5177\u6709\u4e92\u52a8\u6548\u679c\u7684\u544a\u767d\u7a97\u53e3\u3002\u5f53\u9f20\u6807\u9760\u8fd1\u201c\u4e0d\u613f\u610f\u201d\u6309\u94ae\u65f6&#xff0c;\u6309\u94ae\u4f1a\u81ea\u52a8\u8eb2\u5f00&#xff0c;\u5361\u901a\u8868\u60c5\u4e5f\u4f1a\u9010\u6e10\u751f\u6c14&#xff1b;\u5f53\u9f20\u6807\u9760\u8fd1\u201c\u613f\u610f\u201d\u6309\u94ae\u65f6&#xff0c;\u8868\u60c5\u4f1a\u53d8\u5f00\u5fc3\u3002\u70b9\u51fb\u201c\u613f\u610f\u201d\u540e&#xff0c;\u7a97\u53e3\u4f1a\u663e\u793a\u7231\u5fc3\u52a8\u753b\u3002\u9879\u76ee\u540c\u65f6\u63d0\u4f9b\u4e00\u4e2a\u65e0\u9700\u5b89\u88c5\u4f9d\u8d56\u3001\u53cc\u51fb\u5373\u53ef\u8fd0\u884c\u7684 HTML \u7248\u672c\u3002\u4e00\u3001\u9879\u76ee\u6548\u679c\u8fd9\u4e2a\u5c0f\u9879\u76ee\u5e76\u4e0d\u662f\u4e00\u4e2a\u666e\u901a\u7684\u9759\u6001\u5f39\u7a97&#xff0c;\u800c\u662f\u52a0\u5165\u4e86\u591a\u79cd\u5b9e\u65f6\u4ea4\u4e92\u6548\u679c&#xff1a;- \u773c\u775b\u4f1a\u8ddf\u968f\u9f20\u6807\u79fb\u52a8&amp;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.wsisp.com\/helps\/88792.html\" \/>\n<meta property=\"og:site_name\" content=\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"article:published_time\" content=\"2026-08-01T11:08:32+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/08\/20260801110831-6a6dd3afa3c6e.png\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"16 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/88792.html\",\"url\":\"https:\/\/www.wsisp.com\/helps\/88792.html\",\"name\":\"Python + PySide6 \u5b9e\u73b0\u4f1a\u201c\u751f\u6c14\u201d\u7684\u544a\u767d\u7a97\u53e3\uff1a\u6309\u94ae\u8eb2\u907f\u3001\u8868\u60c5\u8ddf\u968f\u4e0e\u7231\u5fc3\u52a8\u753b\uff08\u9644\u5b8c\u6574\u4ee3\u7801\u3001 HTML \u7248\u3001\u9879\u76ee\u6587\u4ef6zip\uff09 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"isPartOf\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\"},\"datePublished\":\"2026-08-01T11:08:32+00:00\",\"dateModified\":\"2026-08-01T11:08:32+00:00\",\"author\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/88792.html#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.wsisp.com\/helps\/88792.html\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/88792.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.wsisp.com\/helps\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Python + PySide6 \u5b9e\u73b0\u4f1a\u201c\u751f\u6c14\u201d\u7684\u544a\u767d\u7a97\u53e3\uff1a\u6309\u94ae\u8eb2\u907f\u3001\u8868\u60c5\u8ddf\u968f\u4e0e\u7231\u5fc3\u52a8\u753b\uff08\u9644\u5b8c\u6574\u4ee3\u7801\u3001 HTML \u7248\u3001\u9879\u76ee\u6587\u4ef6zip\uff09\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\",\"url\":\"https:\/\/www.wsisp.com\/helps\/\",\"name\":\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"description\":\"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"contentUrl\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"caption\":\"admin\"},\"sameAs\":[\"http:\/\/wp.wsisp.com\"],\"url\":\"https:\/\/www.wsisp.com\/helps\/author\/admin\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Python + PySide6 \u5b9e\u73b0\u4f1a\u201c\u751f\u6c14\u201d\u7684\u544a\u767d\u7a97\u53e3\uff1a\u6309\u94ae\u8eb2\u907f\u3001\u8868\u60c5\u8ddf\u968f\u4e0e\u7231\u5fc3\u52a8\u753b\uff08\u9644\u5b8c\u6574\u4ee3\u7801\u3001 HTML \u7248\u3001\u9879\u76ee\u6587\u4ef6zip\uff09 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.wsisp.com\/helps\/88792.html","og_locale":"zh_CN","og_type":"article","og_title":"Python + PySide6 \u5b9e\u73b0\u4f1a\u201c\u751f\u6c14\u201d\u7684\u544a\u767d\u7a97\u53e3\uff1a\u6309\u94ae\u8eb2\u907f\u3001\u8868\u60c5\u8ddf\u968f\u4e0e\u7231\u5fc3\u52a8\u753b\uff08\u9644\u5b8c\u6574\u4ee3\u7801\u3001 HTML \u7248\u3001\u9879\u76ee\u6587\u4ef6zip\uff09 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","og_description":"\u672c\u9879\u76ee\u4f7f\u7528 Python PySide6 \u5236\u4f5c\u4e86\u4e00\u4e2a\u5177\u6709\u4e92\u52a8\u6548\u679c\u7684\u544a\u767d\u7a97\u53e3\u3002\u5f53\u9f20\u6807\u9760\u8fd1\u201c\u4e0d\u613f\u610f\u201d\u6309\u94ae\u65f6&#xff0c;\u6309\u94ae\u4f1a\u81ea\u52a8\u8eb2\u5f00&#xff0c;\u5361\u901a\u8868\u60c5\u4e5f\u4f1a\u9010\u6e10\u751f\u6c14&#xff1b;\u5f53\u9f20\u6807\u9760\u8fd1\u201c\u613f\u610f\u201d\u6309\u94ae\u65f6&#xff0c;\u8868\u60c5\u4f1a\u53d8\u5f00\u5fc3\u3002\u70b9\u51fb\u201c\u613f\u610f\u201d\u540e&#xff0c;\u7a97\u53e3\u4f1a\u663e\u793a\u7231\u5fc3\u52a8\u753b\u3002\u9879\u76ee\u540c\u65f6\u63d0\u4f9b\u4e00\u4e2a\u65e0\u9700\u5b89\u88c5\u4f9d\u8d56\u3001\u53cc\u51fb\u5373\u53ef\u8fd0\u884c\u7684 HTML \u7248\u672c\u3002\u4e00\u3001\u9879\u76ee\u6548\u679c\u8fd9\u4e2a\u5c0f\u9879\u76ee\u5e76\u4e0d\u662f\u4e00\u4e2a\u666e\u901a\u7684\u9759\u6001\u5f39\u7a97&#xff0c;\u800c\u662f\u52a0\u5165\u4e86\u591a\u79cd\u5b9e\u65f6\u4ea4\u4e92\u6548\u679c&#xff1a;- \u773c\u775b\u4f1a\u8ddf\u968f\u9f20\u6807\u79fb\u52a8&amp;","og_url":"https:\/\/www.wsisp.com\/helps\/88792.html","og_site_name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","article_published_time":"2026-08-01T11:08:32+00:00","og_image":[{"url":"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/08\/20260801110831-6a6dd3afa3c6e.png"}],"author":"admin","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"admin","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"16 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.wsisp.com\/helps\/88792.html","url":"https:\/\/www.wsisp.com\/helps\/88792.html","name":"Python + PySide6 \u5b9e\u73b0\u4f1a\u201c\u751f\u6c14\u201d\u7684\u544a\u767d\u7a97\u53e3\uff1a\u6309\u94ae\u8eb2\u907f\u3001\u8868\u60c5\u8ddf\u968f\u4e0e\u7231\u5fc3\u52a8\u753b\uff08\u9644\u5b8c\u6574\u4ee3\u7801\u3001 HTML \u7248\u3001\u9879\u76ee\u6587\u4ef6zip\uff09 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","isPartOf":{"@id":"https:\/\/www.wsisp.com\/helps\/#website"},"datePublished":"2026-08-01T11:08:32+00:00","dateModified":"2026-08-01T11:08:32+00:00","author":{"@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41"},"breadcrumb":{"@id":"https:\/\/www.wsisp.com\/helps\/88792.html#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.wsisp.com\/helps\/88792.html"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.wsisp.com\/helps\/88792.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.wsisp.com\/helps"},{"@type":"ListItem","position":2,"name":"Python + PySide6 \u5b9e\u73b0\u4f1a\u201c\u751f\u6c14\u201d\u7684\u544a\u767d\u7a97\u53e3\uff1a\u6309\u94ae\u8eb2\u907f\u3001\u8868\u60c5\u8ddf\u968f\u4e0e\u7231\u5fc3\u52a8\u753b\uff08\u9644\u5b8c\u6574\u4ee3\u7801\u3001 HTML \u7248\u3001\u9879\u76ee\u6587\u4ef6zip\uff09"}]},{"@type":"WebSite","@id":"https:\/\/www.wsisp.com\/helps\/#website","url":"https:\/\/www.wsisp.com\/helps\/","name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","description":"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41","name":"admin","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/","url":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","contentUrl":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","caption":"admin"},"sameAs":["http:\/\/wp.wsisp.com"],"url":"https:\/\/www.wsisp.com\/helps\/author\/admin"}]}},"_links":{"self":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/88792","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/comments?post=88792"}],"version-history":[{"count":0,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/88792\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/media\/88789"}],"wp:attachment":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/media?parent=88792"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/categories?post=88792"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/tags?post=88792"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/topic?post=88792"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}