diff options
Diffstat (limited to 'sources/pyside2/doc')
114 files changed, 5811 insertions, 3629 deletions
diff --git a/sources/pyside2/doc/_themes/pysidedocs/static/pyside.css b/sources/pyside2/doc/_themes/pysidedocs/static/pyside.css new file mode 100644 index 000000000..956e3113b --- /dev/null +++ b/sources/pyside2/doc/_themes/pysidedocs/static/pyside.css @@ -0,0 +1,1892 @@ +@import url('cookie-confirm.css') screen; + +/* -- admonitions -- */ + +div.admonition { + margin: 1em 0 1em; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +div.admonition dl { + margin-bottom: 0; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} +.body { + width: 100% +} +.bodywrapper .admonition p.admonition-title { + margin-bottom:5px +} + +.bodywrapper .admonition p { + margin:0 +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +div.warning { + background-color: #ffe4e4; + border: 1px solid #f66; +} + +div.seealso { + background-color: #ffffcc; + border: 1px solid #ffff66; +} + +div.note { + border: 1px solid #e3e3e3; +} + +table.docutils { + margin-right: auto; + margin-bottom: 10px; + border: none; + width: initial; +} + +table.docutils.colwidths-given td { + float: none; +} + +table.docutils th, +table.docutils td { + padding-left:0; + border: none; +} + +table.docutils td ul { + margin:0 +} + +table.docutils td ul > li { + margin: 0 0 0.5em; +} +h2 em { + float: right; + font-size: 10px; + position: relative; + top: -20px; +} + +.document { + padding-bottom: 20px; +} + +.documentwrapper { + margin-left: 255px; +} + +.body blockquote { + border: none; + padding-left: 0; + margin-bottom: 2em; +} + +.sphinxsidebar { + float: left; + width: 186px; + padding: 25px; + text-align: left; + background-color: #fff; +} + +.sphinxsidebar ul { + padding: 0px; + margin: 0px; + list-style-position: inside; +} + +.sphinxsidebar > ul { + padding: 0px; + margin: 0px; +} + +.sphinxsidebar ul li li { + margin-left: 10px; + padding: 0px; + font-size: 0.95em; +} + +.sphinxsidebar ul a, +.sphinxsidebar p.topless a { + word-break: break-word; +} + +.sphinxsidebar h3, .sphinxsidebar h3 a { + color: #333; +} + +.sphinxsidebar p.topless { + margin: 1em 0 1em; +} + +.pysidetoc ul { + list-style: none; + padding: 0px; + margin: 0px; +} + +.pysidetoc em { + font-style: normal; +} + +.pysidetoc strong { + display: block; + padding: 5px; + margin: 0 10px 10px 0; + border: 1px solid #ddd; + background-color: #f4f4f4; + -moz-border-radius:6px; + -webkit-border-radius:6px; + -khtml-border-radius:6px; +} + +.section .docutils.container td { + float:left; +} + +.hide { + display: none; +} + +/* copy-notice */ +.document + p { + margin-left: 255px; + width: 70%; + font-size: 0.75em; + margin: 0 35px 15px 280px; +} + +#searchbox { + border-top: 1px solid #989898; + padding-top: 10px; + margin-left: -10px; + margin-right: -10px; + padding-left: 10px; + padding-right: 10px; +} + +#search_button { + border: 1px solid #3A393A; + background-color: #3A393A; + color: white; + cursor: pointer; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + -khtml-border-radius: 5px; + +} + +form { + margin: 0px; + padding: 0px; +} + +#searchbox h3 { + padding: 10px 0 0 0; + margin-bottom: 5px; +} + +/* search field */ +form #q { + width: 136px; + /* height: 22px; */ + /* border: none; */ + margin: 0px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + -khtml-border-radius: 5px; + margin-top: 2px; + padding: 4px; + line-height: 22px; +} + +#search-results h2 { + display: none; +} + +#search-results h2 { + display: none; +} + +#search-results ul.search { + margin: 0px; + padding: 0px; +} + +ul.search div.context { + padding-left: 40px; +} + +#installation td { + text-align: center; + font-weight: bold; +} + +em { + color: inherit; + font-style:italic; +} + +/******** REL bar *********/ + +.related { + display: inline; +} + +.related h3 { + display: none; +} + +.align-center { + text-align: center; +} + +.contentstable { + width: 100%; +} + +.contentstable td { + padding-left: 30px; + vertical-align: top; +} + +p.biglink a { + font-size: 20px; +} + +dt:target, .highlight { + background-color: #fbe54e; +} + +p.highlight-link { + margin-top: 10px; + font-size: 0.8em; +} + +#synopsis table, table.field-list { + margin: 1em 0 1em 0; +} + +table.field-list tr { + text-align: left; +} + +tt.descname { + font-size: 120%; + font-weight: bold; +} + +#functions ul, #virtual-functions ul, #slots ul, #signals ul, #static-functions ul { + list-style: none; + margin: 0px; + padding: 10px; + border: 1px solid #ddd; + background-color: #f4f4f4; + -moz-border-radius:10px; + -webkit-border-radius:10px; + -khtml-border-radius:10px; +} + +#synopsis span.pre { + color: #009491; + font-weight: bolder; +} + +#detailed-description .class dt, +#detailed-description .method dt, +#detailed-description .staticmethod dt, +#detailed-description .attribute dt { + margin: 0px; + margin-bottom: 10px; + padding: 10px; + border: 1px solid #ddd; + background-color: #f4f4f4; + -moz-border-radius:10px; + -webkit-border-radius:10px; + -khtml-border-radius:10px; +} + +.document dl.attribute, +.document dl.class, +.document dl.method, +.document dl.staticmethod { + margin-top: 2em; +} + +.document dl.attribute dd, +.document dl.class dd, +.document dl.method dd, +.document dl.staticmethod dd { + padding-left: 1em; +} + +/* Qt theme */ +#navbar { + position:fixed; + top:0; + left:0; + z-index:100; + background:#fff; + width:100% +} +#navbar .container, .fixed .container { + max-width:1280px; + margin:0 auto; + padding:0 3.9%; /* 0? */ + position:relative; + overflow:visible +} +#navbar .navbar-header { + position:relative +} +#menuextras li a:hover span { + color: #41cd52; +} +/* new header */ +#mm-wrap, #mm-wrap #mm-helper, +#mm-wrap #mm-helper li.mm-item, +#mm-wrap #mm-helper a.mm-link { + -moz-transition: none; + -o-transition: none; + -webkit-transition: none; + transition: none; + -webkit-border-radius: 0 0 0 0; + -moz-border-radius: 0 0 0 0; + -ms-border-radius: 0 0 0 0; + -o-border-radius: 0 0 0 0; + border-radius: 0 0 0 0; + -webkit-box-shadow: none; + -moz-box-shadow: none; + -ms-box-shadow: none; + -o-box-shadow: none; + box-shadow: none; + background: none; + border: 0; + bottom: auto; + box-sizing: border-box; + clip: auto; + color: #090e21; + display: block; + float: none; + font-family: inherit; + font-size: 14px; + height: auto; + left: auto; + line-height: 1.7; + list-style-type: none; + margin: 0; + min-height: 0; + opacity: 1; + outline: none; + overflow: visible; + padding: 0; + position: relative; + right: auto; + text-align: left; + text-decoration: none; + text-transform: none; + top: auto; + vertical-align: baseline; + visibility: inherit; + width: auto; +} +#mm-wrap #mm-helper { + visibility:visible; + text-align:right; + padding:0 0px 0 0px +} +#navbar #mm-wrap #mm-helper li.mm-item { + border-right:solid #f3f3f4 1px; + padding-right:30px; + padding-left:30px +} +#navbar #mm-wrap #mm-helper li.mm-item > a:hover { + opacity: .5 +} +#mm-wrap #mm-helper > li.mm-item { + margin:0 0 0 0; + display:inline-block; + height:auto; + vertical-align:middle +} +#navbar #mm-wrap #mm-helper li.mm-item:nth-child(3) { + border-right:0 +} +#mm-wrap #mm-helper a.mm-link { + cursor: pointer +} +@media (max-width: 1279px) { + #navbar { + padding:0; + position:relative; + } + #navbar .container { + max-width:100% + } + .container { + padding:0 2% + } +} +#navbar .navbar-oneQt { + display:inline; + float:left; + width:31px; + color:#41cd52 +} +#navbar .navbar-oneQt:before { + content:attr(data-icon); + position:absolute; + top:14px; + left:0; + color:#41cd52; + font-family:'Qt Icons'; + line-height:1; + font-size:40px; + transition:all 0.3s ease-in-out; +} +#mm-wrap { + clear:both; + background:rgba(255, 255, 255, 0.1); + -webkit-border-radius:0px 0px 0px 0px; + -moz-border-radius:0px 0px 0px 0px; + -ms-border-radius:0px 0px 0px 0px; + -o-border-radius:0px 0px 0px 0px; + border-radius:0px 0px 0px 0px +} +#mm-wrap #mm-helper li.mm-item:last-child a { + background:transparent url("icon_avatar.png") 50% 50% no-repeat !important; + background-size:24px !important; + width:24px !important; + height:24px !important; +} +#navbar #mm-wrap #mm-helper li.mm-item > a { + opacity:1; + -webkit-transition:all 0.3s ease-in-out; + -moz-transition:all 0.3s ease-in-out; + -ms-transition:all 0.3s ease-in-out; + -o-transition:all 0.3s ease-in-out; + transition:all 0.3s ease-in-out; +} +#mm-wrap #mm-helper > li.mm-item > a.mm-link { + border-top:0px solid #fff; + border-left:0px solid #fff; + border-right:0px solid #fff; + border-bottom:0px solid #fff; + outline:none; + text-decoration:none; + padding:0 0 0 0; + line-height:70px; + font-weight:normal; + height:70px; + vertical-align:baseline; + text-align:left; + width:auto; + display:block; + color:#090e21; + text-transform:none; + text-decoration:none; + background:rgba(0, 0, 0, 0); + -webkit-border-radius:0px 0px 0px 0px; + -moz-border-radius:0px 0px 0px 0px; + -ms-border-radius:0px 0px 0px 0px; + -o-border-radius:0px 0px 0px 0px; + border-radius:0px 0px 0px 0px; + font-family:inherit; + font-size:14px; +} +/* end new header */ +@media (min-width: 1320px) { + .body .flowListDiv dl.flowList { + -webkit-column-count:3; + -moz-column-count:3; + column-count:3 + } +} +@media (min-width: 1120px) { + #navbar.fixed { + -moz-box-shadow:0px 0px 8px rgba(0,0,0,0.23); + -webkit-box-shadow:0px 0px 8px rgba(0,0,0,0.23); + box-shadow:0px 0px 8px rgba(0,0,0,0.23) + } + #navbar.fixed #mm-wrap #mm-helper > li.mm-item > a.mm-link { + height:50px; + line-height:50px + } + #navbar.fixed .navbar-oneQt:before { + font-size:35px; + top:7px + } + + .flowListDiv dl.flowList { + -webkit-column-count:2; + -moz-column-count:2; + column-count:2 + } +} +@media (max-width: 1120px) { + #navbar { + padding:0; + position:relative + } + #navbar .navbar-oneQt:before { + left:10px + } + #navbar .container { + max-width:100%; + padding:0 + } + #footerbar .container { + padding:0 + } + body .main { + margin-top:0px + } + #footerbar .footer-main .footer-nav { + padding:3.9% 0 3.9% 3%; + border-bottom:1px solid #413d3b; + float:none; + display:block; + width:auto + } + #footerbar .footer-main .theqtcompany { + clear:both; + float:left; + margin:30px 0 8px 3% + } + #footerbar .footer-main .footer-social { + float:left; + padding:50px 0px 0px 3% + } + #footerbar #menu-footer-submenu { + clear:both; + float:none; + display:block; + padding:0px 0px 3.9% 3% + } + ul#menu-footer-submenu { + margin-left: 0 + } +} +.cookies_yum { + background-color:#cecfd5; + display:none; + width:100% +} +.cookies_yum img { + width:25px; + top:6px; + display:inline-block; + position:absolute; + left:13px +} +.cookies_yum div { + margin:0 auto; + max-width:1280px; + min-height:30px; + padding:6px 0px 6px 0px; + position:relative +} +.cookies_yum p { + color:#09102b; + margin:0px; + font-size:0.79em; + display:inline-block; + line-height:1.2; + padding:0 30px 0 50px +} +.cookies_yum p a { + white-space:nowrap +} +.cookies_yum a:hover { + color:#46a2da +} +.cookies_yum .close { + width:15px; + height:15px; + background-image:url("cookiebar-x.png"); + background-size:15px 30px; + background-position:top left; + cursor:pointer; + top:13px; + right:13px; + position:absolute; + transition:none +} +.cookies_yum .close:hover { + background-position:bottom left +} +#sidebar-toggle,#toc-toggle { + width:24px; + height:14px; + background-size:24px 28px; + cursor:pointer; + background-image:url("list_expand.png"); + float:right +} +#sidebar-toggle.collapsed, +#toc-toggle.collapsed { + background-position:bottom left +} +#sidebar-content > h2 { + display:none +} +#footerbar { + background:#222840; + color:#fff; + font-size: 0.9em; +} +#footerbar.fixed { + bottom:0; + left:0; + width:100% +} +#footerbar .footer-nav { + display:inline; + float:left +} +#footerbar .footer-main .footer-nav li { + float:left; + margin-right:1em +} +#footerbar .footer-main .footer-nav li a { + display:block; + padding:30px 0 10px 0; + line-height:20px; + height:20px; + color:#fff; + font-weight: 600; +} +#footerbar .footer-main .footer-nav li a:hover,#footerbar .footer-main .footer-nav li.current-menu-item a { + color:#eee +} +#footerbar .footer-main .footer-nav .sub-menu { + margin-left:0; + margin-bottom:0 +} +#footerbar .footer-main .footer-nav .sub-menu li { + float:none; + width: 100%; +} +#footerbar .footer-main .footer-nav .sub-menu ul { + padding:1px 1em; + font-size:0.786em; + line-height:8px; + float:none; + color:#5d5b59; + margin-bottom:0 +} +#footerbar .footer-main .footer-nav .sub-menu li a { + padding:2px 0; + font-size:1em; + float:none; + color:#cecfd5; + font-weight: 400; +} +#footerbar .footer-main .footer-nav .sub-menu li a:hover,#footerbar .footer-main .footer-nav .sub-menu li.current-menu-item a { + color:#eee +} +#footerbar .theqtcompany { + background:url("theqtcompany.png") no-repeat; + background-size:100%; + width:215px; + height:68px; + display:inline; + float:right; + margin:29px 0 28px 30px +} +#footerbar .footer-social { + display:inline; + float:right; + width:164px +} +#footerbar .footer-main .footer-social>div { + margin-left:0.1em; + margin-bottom:10px +} +#footerbar .disclaimer { + font-size:0.786em; + line-height:2.73; + color:#868584; + padding-top:20px; + padding-bottom:0.5% +} +#footerbar .disclaimer a { + color:#bdbebf +} +#footerbar .disclaimer a:hover { + color:#d6d6d6 +} +#footerbar .disclaimer ul li { + float:left; + vertical-align:middle; + margin-left:1.18em +} +#footerbar .disclaimer ul li:first-child { + margin-left:0 +} +#footerbar .disclaimer ul.lang-selector a { + color:#506a34; + color:rgba(128,195,66,0.3) +} +#footerbar .disclaimer ul.lang-selector a:hover { + color:#80c342; + color:rgba(128,195,66,0.7) +} +#menu-footer-menu, #menu-footer-menu ul { + margin-left:0; + margin-bottom:0 +} +@font-face { + font-family: 'Titillium Web'; + font-style: normal; + font-weight: 400; + src: url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.eot"); + /* IE9 Compat Modes */ + src: local("Titillium Web"), local("TitilliumWeb-Regular"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.eot?#iefix") format("embedded-opentype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.woff2") format("woff2"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.woff") format("woff"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.ttf") format("truetype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.svg#TitilliumWeb") format("svg"); + /* Legacy iOS */ +} +/* titillium-web-italic - latin_latin-ext */ +@font-face { + font-family: 'Titillium Web'; + font-style: italic; + font-weight: 400; + src: url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.eot"); + /* IE9 Compat Modes */ + src: local("Titillium WebItalic"), local("TitilliumWeb-Italic"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.eot?#iefix") format("embedded-opentype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.woff2") format("woff2"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.woff") format("woff"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.ttf") format("truetype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.svg#TitilliumWeb") format("svg"); + /* Legacy iOS */ +} +/* titillium-web-600 - latin_latin-ext */ +@font-face { + font-family: 'Titillium Web'; + font-style: normal; + font-weight: 600; + src: url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.eot"); + /* IE9 Compat Modes */ + src: local("Titillium WebSemiBold"), local("TitilliumWeb-SemiBold"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.eot?#iefix") format("embedded-opentype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.woff2") format("woff2"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.woff") format("woff"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.ttf") format("truetype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.svg#TitilliumWeb") format("svg"); + /* Legacy iOS */ +} +@font-face { + font-family:'Droid Sans Mono'; + font-style:normal; + font-weight:400; + src:local("Droid Sans Mono"),local("DroidSansMono"),url(//fonts.gstatic.com/s/droidsansmono/v7/ns-m2xQYezAtqh7ai59hJUYuTAAIFFn5GTWtryCmBQ4.woff) format("woff") +} +@font-face { + font-family:'Qt Icons'; + src:url("../style/icomoon.eot?-tgjuoj"); + src:url("../style/icomoon.eot?#iefix-tgjuoj") format("embedded-opentype"),url("../style/icomoon.woff?-tgjuoj") format("woff"),url("../style/icomoon.ttf?-tgjuoj") format("truetype"),url("../style/icomoon.svg?-tgjuoj#icomoon") format("svg"); + font-weight:normal; + font-style:normal +} +@font-face { + font-family:'social-icons'; + src:url("../style/social-icons.eot?54625607"); + src:url("../style/social-icons.eot?54625607#iefix") format("embedded-opentype"), + url("../style/social-icons.woff?54625607") format("woff"); + font-weight:normal; + font-style:normal +} +.clearfix:before,.clearfix:after { + content:" "; + display:table +} +.clearfix:after { + clear:both +} +.clearfix { + *zoom:1 +} +.clearfix .right { + float:right +} +html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video { + margin:0; + padding:0; + border:0; + font-size:100% +} +html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,caption,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video { + vertical-align:baseline +} +h1,h2,h3,h4,h5,h6 { + font-weight:300 +} +.body h2,.body h3,.body h4,.body h5,.body h6 { + margin:1.5em 0 0.75em +} +.body h1 { + margin-bottom:0.75em; + font-size:2.25em; +} +.body h3.fn,.body h3.flags { + color:#26282a; + font-size:1.46em; + padding:15px 0 15px 0; + border-bottom:2px #eee solid; + word-wrap:break-word +} +.body .fngroup { + border-bottom:2px #eee solid; + padding-bottom:15px; + margin-bottom:1.5em +} +.body .fngroup h3.fngroupitem { + margin:0; + padding-bottom:0; + border:none +} +.body h3.fn .name, +.body h3 span.type, +.qmlname span.name { + font-weight: 400 +} +.qmlname { + font-size:1.46em +} +.qmlproto table { + border:none; + border-bottom:2px #eee solid +} +.qmlproto table p { + max-width:100% +} +.qmlproto table tr { + background-color:#fff +} +.qmlname td, .qmlname th { + border:none; + text-align:left; + padding:5px 0 0 0 +} +.qmlreadonly,.qmldefault { + padding:0 5px 0 5px; + font-size:0.75em; + background-color:#eee; + float:right +} +.qmlreadonly { + color:#414141 +} +.qmldefault { + color:#D14141 +} +.rightAlign { + padding:3px 5px 3px 10px; + text-align:right +} +.centerAlign.functionIndex { + text-align:center; + font-size:150%; + margin-bottom: 1em +} +article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section { + display:block +} +body { + line-height:1; + font-family:'Titillium Web', Arial, Helvetica, sans-serif; + font-weight:400; + transition-duration:1s; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + font-size: 16px; + background-color:#f3f3f4; + color:#404244; +} +ol,ul { + list-style:none +} +.body ol,.body ul { + margin-top:0.75em; + margin-left:20px +} +.bodywrapper ol>li { + list-style-type:decimal; + margin-left:15px +} +.bodywrapper ol.a >li { + list-style-type:lower-alpha; +} +.bodywrapper ol.A >li { + list-style-type:upper-alpha; +} +.bodywrapper ol.i >li { + list-style-type:lower-roman; +} +.bodywrapper ol.I >li { + list-style-type:upper-roman; +} +.body li p { + margin-top:1em +} +blockquote,q { + quotes:none; + border-left:10px solid #ddd; + padding-left:10px +} +blockquote:before,blockquote:after,q:before,q:after { + content:''; + content:none; + width:100% +} +table { + border-collapse:collapse; + border-spacing:0; + margin-bottom:5px; + width:100% +} +a { + color:#17a81a; + text-decoration:none; + transition-duration:0.3s +} +a:hover { + color:#17a81a +} +.main,#footerbar>div { + max-width:1280px; + width:95%; + margin:0 auto +} +.main { + margin-top:80px +} +@media (max-width: 1120px) { + .main,.navbar-header,#footerbar>div { + width: 100%; + margin: 0; + } + .main .main-rounded { + padding: 0 15px; + } +} +.main_index { + background-color:#fff +} +.sectionlist { + margin-bottom:2em +} +[class*="col-"] { + letter-spacing:normal +} +.landing,.main_index .row { + letter-spacing:-0.31em +} +.main_index .row>div { + letter-spacing:normal +} +.col-1,.body { + display:inline-block; + background-color:#fff; + padding: 25px 35px 20px 30px; + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + -ms-box-sizing:border-box; + box-sizing:border-box; +} +.col-1 h2 { + font-size:1.8em; + font-weight:300; + line-height:1.1; + margin-bottom:0.83em; + margin-top:1em +} +.icons1of3 img { + display:inline-block; + float:left; + margin-right:0.75em; + margin-top:-5px; + width:2.75em +} +div.multi-column { + position:relative +} +div.multi-column div { + display:-moz-inline-box; + display:inline-block; + vertical-align:top; + margin-top:1em; + margin-right:2em; + width:16em +} +.sidebar { + display:block; + position:relative; + position:sticky; + float:left; + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + -ms-box-sizing:border-box; + box-sizing:border-box; + width:20%; + padding-right:20px +} +.sidebar li { + text-overflow:ellipsis; + overflow:hidden +} +.toc,.sectionlist { + padding:25px; + background-color:#fff; + margin-bottom:1.25em +} +.sidebar .sectionlist p { + margin-bottom:0 +} +.sectionlist.promo { + padding:0; + background-color:#f3f3f4 +} +.sidebar-content:empty { + display:none; + visibility:hidden +} +.col-2 h2,.toc h3,.sidebar-content h2, +.sidebar-content h3,.sectionlist h2, +.sphinxsidebar h3 { + font-weight:400; + margin-bottom:1em +} +.toc h3 a { + color:#404244 +} +.title { + font-size:2.25em; + font-weight:300; + letter-spacing:-1px; + line-height:1.15em; + margin-bottom:0.5em; + word-wrap:break-word +} +.navigationbar,col-1 h2 { + font-size:0.85em +} +.navigationbar h1 { + font-size:2.5em; + margin-bottom:0.85em; + margin-top:0.85em +} +.navigationbar li { + display:inline-block; + margin-right:5px; + position:relative; + padding-right:10px; + color:#585a5c +} +.navigationbar ul:last-of-type li a { + color:#404244 +} +.sectionlist li, .sphinxsidebar li { + padding-bottom: 10px; + line-height: 1.75em; +} +.col-1 ul { + margin-bottom:1.56em +} +.bodywrapper li { + margin-top:0.5em; + line-height:1.25em +} +.bodywrapper li.level2 { + margin-left:10px; + margin-top:0.4em; + font-size:0.9375em; +} +.bodywrapper p, +.bodywrapper dd { + line-height:1.25em; + margin:1em 0 1em; + color:#404244 +} +.bodywrapper b { + font-weight:600 +} +.body ul,.body ol { + /* margin-bottom:1.5em */ +} +.bodywrapper ul ul { + margin-top:0.5em +} +.bodywrapper .naviNextPrevious { + margin-top:25px; + max-width:100% +} +.naviNextPrevious.headerNavi, +p.naviNextPrevious + p { + display:none +} +.nextPage { + float:right +} +.prevPage:before { + content:"< " +} +.nextPage:after { + content:" >" +} +.navigationbar li a { + color:#404244 +} +.navigationbar li:after { + color:#404244; + content:"›"; + display:inline-block; + font-size:1.5em; + line-height:1; + position:absolute; + right:-2px; + top:-4px +} +.sub-navigation { + margin-top:10px +} +.navigationbar li:last-child:after,.sub-navigation li:after { + content:none +} +.navigationbar { + margin-bottom:10px; + line-height:1em +} +#buildversion { + margin-bottom:10px; + font-style:italic; + font-size:small; + float:right +} +.copy-notice { + width:75%; + font-size:0.75em; + margin:20px 35px 0 10px; + line-height:1.75em; + float:right; + color:#585a5c +} +.copy-notice.index { + margin-top:10px; + float:none +} +li a.active { + color:#585a5c +} +.flowList { + padding:25px +} +.flowListDiv dl { + -webkit-column-count:1; + -moz-column-count:1; + column-count:1 +} +.flowList dd { + display:inline-block; + margin-left:10px; + width:90%; + line-height:1.15em; + overflow-x:hidden; + text-overflow:ellipsis +} +.alphaChar { + font-size:2em; + position:absolute +} +.flowList.odd { + background-color:#f9f9f9 +} +.body ul>li,.doc-column ul>li { + list-style-image:url("list_arrow.png"); + margin-left:15px; + color:#404244; + margin-top:0.65em; + line-height:1em +} +.bodywrapper table p { + margin:0px; + padding:0px +} +.bodywrapper table p { + margin:0px; + padding:0px; + min-height:1.25em +} +.bodywrapper .qmldoc { + margin-top:0.75em +} +.body h2 { + margin-top: 1.5em; + font-size:1.75em +} +.body h3 { + font-size:1.35em +} +.body h4 { + font-size:1.15em +} +.body p img { + margin-top:0.75em; + max-width:100% +} +.body .border img { + box-shadow:3px 3px 8px 3px rgba(200,200,200,0.5) +} +.body .border .player { + box-shadow:3px 3px 8px 3px rgba(200,200,200,0.5) +} +.body p.figCaption { + transform:translateY(-30px); + color:#606366; + font-size:95%; + margin-left:3px; + font-style:italic +} +.body table { + width:initial; + vertical-align:initial +} +table .odd { + background-color:#f9f9f9 +} +table thead { + text-align:left; + padding-left:20px +} +table,table td,table th { + border:1px solid #eee +} +table td,table th { + padding:5px 20px; + line-height:1.3 +} +.body .fixed table td { + min-width:50%; + width:50% +} +table.alignedsummary,table.propsummary { + width:initial +} +table.valuelist td.tblval { + font-size:0.75em +} +div.main_index .row { + border-bottom:10px solid #f3f3f4 +} +div.main_index .row { + position:relative +} +div.main_index .row>div { + display:inline-block; + width:50%; + vertical-align:top; + padding:2em 3em; + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + -ms-box-sizing:border-box; + box-sizing:border-box +} +div.main_index h2 { + font-size:2.1875em; + margin-bottom:1em +} +#search_bar { + width:40%; + float:right +} +div.main_index .row:after { + content:""; + position:absolute; + top:0; + right:50%; + height:100%; + width:10px; + background-color:#f3f3f4 +} +div.table { + overflow-x:auto +} +.body tr > td > pre { + font-size:0.75em +} +p.qt_commercial { + border:3px solid #5caa15; + margin:0 auto; + padding:15px; + width:28%; + text-align:center; + clear:both +} +h1.qt_commercial { + padding:20px; + background-color:#5caa15; + display:inline; + float:right; + font-size:1.25em; + line-height:1.25em; + height:1.25em; + color:#fff +} +div.qt_commercial { + border-top:5px solid #5caa15; + margin-bottom:50px +} +div.pre { + position:relative; + height:auto +} +pre, .LegaleseLeft { + background-color:#3a4055; + color:#fff; + display:block; + font-family:"Droid Sans Mono"; + line-height:1.5; + overflow-x:auto; + margin-bottom:25px; + padding:25px; + margin-top:0.75em; + font-size: .8em; +} +.bodywrapper .LegaleseLeft p { + color:#fff; + white-space: pre-wrap +} +pre .str,code .str { + color:#aaaaaa +} +pre .kwd,code .kwd { + color:#ffff55 +} +pre .com,code .com { + color:#55ffff +} +pre .typ,code .typ { + color:#4f9d08 +} +pre a .typ,code a .typ { + color:#21be2b +} +pre .lit,code .lit { + color:#ff55ff +} +pre .pun,code .pun { + color:#fff +} +pre .pln,code .pln { + color:#fff +} +@media print { + pre { + background-color:#eee !important + } + pre .str,code .str { + color:#060 + } + pre .kwd,code .kwd{ + color:#006; + font-weight:bold + } + pre .com,code .com { + color:#600 + } + pre .typ,code .typ { + color:#404; + font-weight:bold + } + pre .lit,code .lit { + color:#044 + } + pre .pun,code .pun { + color:#440 + } + pre .pln,code .pln { + color:#000 + } +} +pre.wrap { + white-space:pre-wrap +} +pre span.wrap { + display:none; + background:url("wrap.png") no-repeat; + right:0; + top:2px; + position:absolute; + width:20px; + height:14px; + margin:4px; + opacity:0.65 +} +span.wrap:hover { + opacity:1 +} +span.wrap:active { + opacity:0.75 +} +.copy_text { + background-color:#46a2da; + color:#fff; + border:2px solid #46a2da; + padding:10px 16px; + margin-left:-10px; + margin-top:-50px; + position:absolute; + opacity:0; + cursor:pointer; + float:right +} +.copy_text:hover { + background-color:#fff; + color:#46a2da +} +code,.codelike { + font-family:"Droid Sans Mono" +} +h3.fn code { + font-size:0.75em; + float:right; + background-color:#eee; + padding:3px; + margin: 3px 0 0 20px +} +pre:hover>.copy_text { + display:inline-block; + opacity:1; + transition:0.5s ease +} +#main_title_bar { + background:url("pyside-logo.png") no-repeat; + background-size:100%; + width:366px; + height:86px; + margin:15px 0 15px 0 +} +#main_title_bar h1 { + visibility:hidden +} +#main_title_bar .search_bar { + letter-spacing:normal; + width:50%; + display:inline-block; + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + -ms-box-sizing:border-box; + box-sizing:border-box; + vertical-align:middle +} +#main_title_bar h1 { + letter-spacing:normal; + display:inline-block; + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + -ms-box-sizing:border-box; + box-sizing:border-box; + vertical-align:middle +} +#main_title_bar .search_bar * { + letter-spacing:normal; + padding:0; + margin:0; + border:none +} +#sidebar-toggle,#toc-toggle { + display:none +} +@media (max-width: 980px) { + body { + font-size:calc-em(14px) + } + #main_title_bar>h1,#main_title_bar .search_bar { + width:100% + } + #main_title_bar .search_bar { + margin-bottom:15px + } + .main { + margin-top:0px + } + .main_index .row { + border:none !important + } + .title { + font-size:1.5em; + font-weight:400; + word-wrap:break-word + } + .col-1,.body,.naviNextPrevious,.sidebar { + padding:10px + } + .sidebar { + position:relative; + padding-top:0 + } + .search .sidebar { + display:none; + visibility:hidden + } + .col-2 h2,.toc h3,.sidebar-content h2,.sidebar-content h3,.sectionlist h2 { + text-align:center; + margin-bottom:5px + } + div.main_index .row:after { + content:none + } + div.main_index .row>div { + display:block !important; + width:100%; + padding:15px; + margin:0 + } + .body,.sidebar,.col-1 { + width:100% + } + .sidebar-content,.col-2,.toc { + background-color:#fff; + margin-bottom:1em; + padding:20px + } + #sidebar-toggle,#toc-toggle { + display:block + } + #sidebar-toggle.collapsed + h2 { + display:block + } + .bodywrapper p { + margin-bottom:1em; + max-width:100% + } + table td,table th { + padding:5px 5px + } + .sectionlist { + padding:0 + } + .sidebar > .sectionlist { + padding:20px + } + .sectionlist.promo { + max-width:46%; + margin:0 auto 1em auto; + float:left; + padding:0 2% + } + .sidebar .sidebar-content { + clear:both + } + .copy-notice { + float:none; + width:initial + } +} +[id]:target > *:first-child, +dt[id]:target { + -webkit-animation:highlighter 3s; + animation:highlighter 3s +} +@-webkit-keyframes highlighter { + 25% { + background-color:#d1e8f6; + color:#444 + } + 75% { + background-color:#d1e8f6; + color:#444 + } +} +@keyframes highlighter { + 25% { + background-color:#d1e8f6; + color:#444 + } + 75% { + background-color:#d1e8f6; + color:#444 + } +} +@-webkit-keyframes copypaste { + 25% { + opacity:1 + } + 100% { + border-radius:10px; + margin-top:-50px; + opacity:1 + } +} +@keyframes copypaste { + 25% { + opacity:1 + } + 100% { + border-radius:10px; + margin-top:-50px; + opacity:1 + } +} +#footer { + clear:both +} +.footer-social i { + font-family: "social-icons"; + font-style: normal; + font-size:150%; + margin: .55em; + color: #cecfd5 +} +.footer-social i:hover { + color: #eee +} +.footer-social .icon-twitter:before { + content: '\f099' +} +.footer-social .icon-facebook:before { + content: '\f09a' +} +.footer-social .icon-youtube:before { + content: '\f16a' +} +.menuextraslanguages { + display:none; + visibility:hidden +} +form.gsc-search-box { + font-size: 25px !important; + margin-top: 0 !important; + margin-right: 0 !important; + margin-bottom: 4px !important; + margin-left: 0 !important; + width: 102.5% !important; +} +table.gsc-search-box { + border-style: none !important; + border-width: 0 !important; + border-spacing: 0 0 !important; + width: 100% !important; + margin-bottom: 2px !important; +} + +table.gsc-search-box td { + vertical-align: middle !important; +} + +table.gsc-search-box td.gsc-input { + padding-right: 0px !important; +} +table.gsc-search-box td.gsc-input input { + background-position: 10px center !important; +} + +td.gsc-search-button { + width: 1% !important; +} + +td.gsc-clear-button { + width: 14px !important; + visibility:hidden !important; + display:none !important; +} +table.gsc-branding td, +table.gsc-branding { + margin: 0 0 0 0 !important; + padding: 0 0 0 0 !important; + border: none !important; +} + +table.gsc-branding { + border-style: none !important; + border-width: 0 !important; + border-spacing: 0 0 !important; + width: 100% !important; +} + +.gsc-branding-text { + color: #676767 !important; +} + +td.gsc-branding-text { + vertical-align: top !important; +} +td.gsc-branding-text div.gsc-branding-text { + padding-bottom: 2px !important; + text-align: right !important; + font-size: 11px !important; + margin-right: 2px !important; +} + +td.gsc-branding-img { + width: 65px !important; + vertical-align: bottom !important; +} + +img.gsc-branding-img { + padding-top: 1px !important; + margin: 0 0 0 0 !important; + padding-right: 0 !important; + padding-left: 0 !important; + padding-bottom: 0 !important; + border: none !important; + display: inline !important; +} + +input.gsc-search-button { + background-color: white !important; + height: 35px !important; + width: 25px !important; + color: transparent !important; + background-image: url("doc_search.png") !important; + background-size: 25px auto; + background-position: 0px 5px; + background-repeat: no-repeat; + margin-left: -43px !important; + overflow: hidden; + min-width: 20px !important; +} + +input.gsc-search-button:hover { + cursor: pointer; +} + +input.gsc-search-button:focus { + outline: none; + box-shadow: none; +} + +.gsc-search-box-tools .gsc-clear-button { + display: none !important; + visibility: none !important; +} + +.gsc-overflow-hidden { + overflow: hidden !important; +} + +input.gsc-input { + background-color: #fff !important; + border: 1px solid #d6d6d6 !important; + box-sizing: border-box !important; + -moz-box-sizing: border-box !important; + color: #868482 !important; + outline: 0 none !important; + padding: 9px 10px 10px !important; + transition: color 0.5s ease 0s, box-shadow 0.5s ease 0s, background-color 0.5s ease 0s !important; +} + +input { + font-family: 'Titillium Web', Arial, Helvetica, sans-serif !important; + line-height: 1.5 !important; + font-weight: 300 !important; + vertical-align:middle +} + +input:focus { + border-color: #46a2da; + box-shadow: 0 0 5px #46a2da; + color: #000; +} + +.animation { + width: 100%; + border-style: none; + border-width: 0 +} + +.player { + width: auto; + position: relative; + display: table; + margin-bottom:1.5em; +} + +.playcontrol { + display: none; + background: url("play_icon.svg") no-repeat center, + linear-gradient( + rgba(0,0,0,0.15), rgba(0,0,0,0.15) + ); + background-size: 25%; + width: 100%; + height: 100%; + position: absolute; + left: 0%; + right: 0%; + top: 0%; + bottom: 0%; + margin: auto +} + +/* expand/collapse code sections */ +pre input { + display:none; + visibility:hidden +} +pre label { + display:block; + margin:-3px 3px 0 -16px; + text-align:center; + color:#21be2b; + float:left; +} +pre label:hover { + color:#fff +} +pre label::before { + font-weight:600; + font-size:16px; + content:"+"; + display:inline-block; + width:16px; + height:16px +} +#ec_expand { + height:16px; + overflow:hidden; + transition:height 0.35s; +} +#ec_expand::before { + content:"...*/"; + color:#aaa; + background-color:#3a4055; + z-index:99 !important; + right:25px; + position:absolute +} +#ec_toggle:checked ~ #ec_expand { + height:initial +} +#ec_toggle:checked ~ #ec_expand::before { + content:"" +} +#ec_toggle:checked ~ label::before { + content:"-" +} + +/* permalinks */ +h1:hover > .headerlink, +h2:hover > .plink, +h2:hover > .headerlink, +h3:hover > .plink, +h3:hover > .headerlink, +h4:hover > .plink, +h4:hover > .headerlink, +h5:hover > .plink, +h5:hover > .headerlink { + opacity:1 +} +a.plink, a.headerlink { + opacity: 0; + padding-left: 8px; + font-size: 0.8em; + font-weight: 600; + transition: opacity 180ms ease-in-out +} +a.plink::before { + content:'\00B6' +} diff --git a/sources/pyside2/doc/_themes/pysidedocs/static/pysidedocs.css b/sources/pyside2/doc/_themes/pysidedocs/static/pysidedocs.css deleted file mode 100644 index 6b1c4274e..000000000 --- a/sources/pyside2/doc/_themes/pysidedocs/static/pysidedocs.css +++ /dev/null @@ -1,477 +0,0 @@ -* { - font: 100% Verdana, Arial, Helvetica, sans-serif; - font-size:12px; -} - -html { - height: 100%; -} - -body { - margin: 0; - padding: 0; - background-color: #EBEBEB; - height: 100%; - color: #333; -} - -strong { - font-weight:bold; -} - -.document { - padding-bottom: 90px; -} - -#container { - position: relative; - min-height: 100%; - background-image: url(fakebar.png); - background-repeat: repeat-y; - background-color: white; -} - -.footer { - position: absolute; - bottom: 0px; - margin-top: 50px; - text-align:center; - background-color: white; - border-top: 2px solid #e0e0e0; - white-space: normal; - height: 90px; - width: 100%; -} - -.footer img { - margin-left: 8px; - margin-right: 8px; -} - -.sphinxsidebar { - float: left; - width: 250px; - padding: 0px 10px 0px 10px; - text-align: left; -} - -.sphinxsidebar ul { - padding: 0px; - margin: 0px; - list-style-position: inside; -} - -.sphinxsidebar > ul { - padding: 0px; - margin: 0px; -} - -.sphinxsidebar ul li { - margin-left: 10px; - padding: 0px; -} - -.sphinxsidebar h3, .sphinxsidebar h3 a { - font-weight: bold; - color: #333; -} - -.documentwrapper { - margin-left: 270px; - text-align: left; - background-color: #ffffff; - border-left: 1px solid #989898; - font-size:18px; - padding: 10px 50px 15px 50px; - height: 100%; -} - -h1 { - font-size:18px; - padding-left: 50px; - padding-bottom: 15px; - padding-top: 15px; - border-bottom: 1px solid #c2c2c2; -/* text-transform:uppercase; */ - margin-right: -100px; - position: relative; - left: -50px; - top: -10px; -} - -h2 { - font-size:12px; - font-weight:bold; - border-left-width: 1px; - border-right-width: 1px; - border-top-width: 1px; - border-bottom-width: 2px; - border-style: solid; - border-left-color: #b1b1b1; - border-right-color: #b1b1b1; - border-top-color: #b1b1b1; - border-bottom-color: #009491; - background-color: #e0e0e0; - padding:5px; - margin-top: 20px; - -moz-border-radius:5px; - -webkit-border-radius:5px; - -khtml-border-radius:5px; -} - -h3, h4 { - font-weight: bolder; -} - -pre { - border-top: 1px solid #e0e0e0; - border-bottom: 1px solid #e0e0e0; - background-color: #fafafa; - padding: 5px; - font: 100% monospace; - overflow: auto; -} - -pre * { - font: 100% monospace; -} - -.pre { - font: 100% monospace; -} - -.headerlink { - font-size: 100%; - color: inherit; - float: right; - visibility: Hidden -} - -h1 .headerlink { - padding-right: 50px; -} - -h1:hover .headerlink, h2:hover .headerlink, h3:hover .headerlink { - visibility: Visible; -} - -a, a:visited { - color: #009491; - text-decoration: none; -} - -a:hover { - text-decoration: underline; -} - -/* -- admonitions ----------------------------------------------------------- */ - -div.admonition { - margin-top: 10px; - margin-bottom: 10px; - padding: 7px; -} - -div.admonition dt { - font-weight: bold; -} - -div.admonition dl { - margin-bottom: 0; -} - -p.admonition-title { - margin: 0px 10px 5px 0px; - font-weight: bold; -} - -div.body p.centered { - text-align: center; - margin-top: 25px; -} - -div.warning { - background-color: #ffe4e4; - border: 1px solid #f66; -} - -div.seealso { - background-color: #ffffcc; - border: 1px solid #ffff66; -} - -div.note { - border: 1px solid #e3e3e3; -} - -table.docutils { - margin-left: auto; - margin-right: auto; - margin-bottom: 10px; - border: none; -} - -table.docutils td { - border: none; -} - -table.docutils th { - border: none; - font-weight: bold; - vertical-align: top; -} - -h2 em { - float: right; - font-size: 10px; - position: relative; - top: -20px; -} - -/* Table of pymaemo components */ - -#development table.docutils td { - border-bottom: 1px solid #EBEBEB; -} - -#development th { - background-color: #EBEBEB; - color: #FC7E00; - padding: 5px; -} - -#development th:first-child { - -moz-border-radius: 20px 0px 0px 0px; - -webkit-border-radius: 20px 0px 0px 0px; - -khtml-border-radius: 20px 0px 0px 0px; - padding-left: 10px; -} -#development th:last-child { - -moz-border-radius: 0px 20px 0px 0px; - -webkit-border-radius: 0px 20px 0px 0px; - -khtml-border-radius: 0px 20px 0px 0px; - padding-right: 10px; - width: 100px; -} - -hr { - border: none; - border-bottom: 1px dashed #EBEBEB; - width: 70% -} - -.oldnews { - text-align: right; -} - -/******************* TOPO *****************************/ -.header { - background-image: url(bg_topo.jpg); - background-repeat: repeat-x; - height: 147px; -} - -.header_container { - background-image: url(bg_header.png); - background-repeat: no-repeat; - background-position: 100px 0px; -} - -.logo { - text-align: left; - margin-bottom: 10px; -} - -#searchbox { - border-top: 1px solid #989898; - padding-top: 10px; - margin-left: -10px; - margin-right: -10px; - padding-left: 10px; - padding-right: 10px; -} - -#search_button { - border: 1px solid #3A393A; - background-color: #3A393A; - color: white; - cursor: pointer; - -moz-border-radius: 5px; - -webkit-border-radius: 5px; - -khtml-border-radius: 5px; - -} - -form { - margin: 0px; - padding: 0px; -} - -/* search field */ -form #q { - width: 136px; -/* height: 22px; */ - border: none; - margin: 0px; - -moz-border-radius: 5px; - -webkit-border-radius: 5px; - -khtml-border-radius: 5px; - margin-top: 2px; - padding: 4px; - line-height: 22px -} - -#search-results h2 { - display: none; -} - -#search-results h2 { - display: none; -} - -#search-results ul.search { - margin: 0px; - padding: 0px; -} - -ul.search div.context { - padding-left: 40px; -} - -#installation td { - text-align: center; - font-weight: bold; -} - -em { - color: inherit; - font-style:italic; -} - -/******** REL bar *********/ - -.related { - display: inline; -} - -.related ul { - padding: 0px 0px 0px 10px; - margin: 0px; - text-align: left; - background-image: url(relbar_bg.png); -} - -.related li { - display: inline; - color: white; - font-weight: bold; -} - -.related li a { - color: inherit; - line-height: 35px; - font-weight: bold; - vertical-align: middle; -} - -.related li.right { - float: right; - margin-right: 5px; -} - -.related h3 { - display: none; -} - -.align-center { - text-align: center; -} - -.contentstable { - width: 100%; -} - -.contentstable td { - padding-left: 30px; - vertical-align: top; -} - -p.biglink a { - font-size: 20px; -} - -dt:target, .highlight { - background-color: #fbe54e; -} - -img { - border: 0px; -} - -.figure .caption { - font-style:italic; -} - -table.footnote { - margin: 0px; -} - -#synopsis table, table.field-list { - margin: 0px; -} - -tt.descname { - font-size: 120%; - font-weight: bold; -} - -#functions ul, #virtual-functions ul, #slots ul, #signals ul, #static-functions ul { - list-style: none; - margin: 0px; - padding: 10px; - border: 1px solid #ddd; - background-color: #f4f4f4; - -moz-border-radius:10px; - -webkit-border-radius:10px; - -khtml-border-radius:10px; -} - -#synopsis span.pre { - color: #009491; - font-weight: bolder; -} - -#detailed-description .class dt, #detailed-description .method dt, #detailed-description .attribute dt { - margin: 0px; - padding: 10px; - border: 1px solid #ddd; - background-color: #f4f4f4; - -moz-border-radius:10px; - -webkit-border-radius:10px; - -khtml-border-radius:10px; -} - -.pysidetoc ul { - list-style: none; - padding: 0px; - margin: 0px; -} - -.pysidetoc em { - font-style: normal; -} - -.pysidetoc strong { - display: block; - padding: 5px; - border: 1px solid #ddd; - background-color: #f4f4f4; - -moz-border-radius:6px; - -webkit-border-radius:6px; - -khtml-border-radius:6px; -} - -.hide { - display: none; -} - diff --git a/sources/pyside2/doc/_themes/pysidedocs/theme.conf b/sources/pyside2/doc/_themes/pysidedocs/theme.conf index e0a652a5d..01a4dd4a1 100644 --- a/sources/pyside2/doc/_themes/pysidedocs/theme.conf +++ b/sources/pyside2/doc/_themes/pysidedocs/theme.conf @@ -1,6 +1,6 @@ [theme] inherit = default -stylesheet = pysidedocs.css +stylesheet = pyside.css pygments_style = none [options] diff --git a/sources/pyside2/doc/contents.rst b/sources/pyside2/doc/contents.rst index 464f6e1da..675a5b73a 100644 --- a/sources/pyside2/doc/contents.rst +++ b/sources/pyside2/doc/contents.rst @@ -10,7 +10,6 @@ tutorials/index.rst deployment.rst pysideapi2.rst - pysideversion.rst licenses.rst Module Index diff --git a/sources/pyside2/doc/deployment-cxfreeze.rst b/sources/pyside2/doc/deployment-cxfreeze.rst index 40b65621b..f0a71ca80 100644 --- a/sources/pyside2/doc/deployment-cxfreeze.rst +++ b/sources/pyside2/doc/deployment-cxfreeze.rst @@ -2,10 +2,9 @@ |project| & cx_Freeze ===================== -`cx_Freeze <https://anthony-tuininga.github.io/cx_Freeze/>`_ allows you to freeze your Python -application into executables. -The supported platforms are Linux, macOS, Windows, FreeBSD, among others. - +`cx_Freeze <https://anthony-tuininga.github.io/cx_Freeze/>`_ lets you +freeze your Python application into executables. The supported +platforms are Linux, macOS, Windows, FreeBSD, among others. You can read the `official documentation <https://cx-freeze.readthedocs.io/en/latest/index.html>`_ to clarify any further question, and remember to contribute to @@ -15,7 +14,7 @@ if you find any, or contributing to `their development <https://bitbucket.org/an Preparation =========== -Installing `cx_Freeze` can be done via **pip**:: +Installing `cx_Freeze` can be done using **pip**:: pip install cx_freeze @@ -34,7 +33,7 @@ There are three options to work with `cx_Freeze`: 2. Creating `setup.py` script to build the project. 3. Using the module classes directly (for advanced purposes). -We will cover the first two uses cases. +The following sections cover the first two use cases. Creating an example ------------------- @@ -83,15 +82,16 @@ Now, consider the following simple script, named `hello.py`:: Using `cxfreeze` executable --------------------------- -The command line to proceed will look like this:: +Now that we have an application, try freezing it with the following +command:: cxfreeze hello.py -This command will create a `dist/` directory that will contain the -executable and a `lib/` directory including all the shared libraries. +This command creates a `dist/` directory containing the executable. +and a `lib/` directory containing all the shared libraries. -To launch the application, you need to just go to the `dist/` directory -and execute the file:: +To launch the application, go to the `dist/` directory and execute +the file:: cd dist/ ./main @@ -100,7 +100,7 @@ and execute the file:: Using a setuptools script ------------------------- -For this process, you will need an additional script called `setup.py`:: +For this process, you need an additional script called `setup.py`:: import sys from cx_Freeze import setup, Executable @@ -110,18 +110,18 @@ For this process, you will need an additional script called `setup.py`:: description = "My GUI App", executables = [Executable("hello.py")]) -After that, you need to build the project using it:: +Now, build the project using it:: python setup.py build -This step will create a `build/` directory with the following structure:: +This step creates a `build/` directory with the following structure:: build └── exe.linux-x86_64-3.7 └── lib └── main -The first directory inside `build/` will depend on the platform +The first directory inside `build/` depends on the platform you are using, in this case a `x86_64` Linux using Python 3.7. The structure is the same as previously described, and you can simply enter the directory and execute the file:: diff --git a/sources/pyside2/doc/deployment-fbs.rst b/sources/pyside2/doc/deployment-fbs.rst index 94c52a08b..6375da61e 100644 --- a/sources/pyside2/doc/deployment-fbs.rst +++ b/sources/pyside2/doc/deployment-fbs.rst @@ -3,8 +3,8 @@ =============== `fbs <https://build-system.fman.io>`_ provides a powerful environment for packaging, -creating installers, and signing your application, but also for managing the application's updates. -Since it is based on PyInstaller, it currently supports Linux, macOS, and Windows. +creating installers, and signing your application. It also lets you manage updates to +your application. As it is based on PyInstaller, it supports Linux, macOS, and Windows. You can read the `official tutorial <https://github.com/mherrmann/fbs-tutorial>`_ for more details on how to use `fbs`, or check the @@ -14,9 +14,9 @@ options. Preparation =========== -Installing `fbs` can be done via **pip**:: +Installing `fbs` (>= 0.7.6) can be done via **pip**:: - pip install fbs pyinstaller==3.4 + pip install fbs If you are using a virtual environment, remember to activate it before installing it. @@ -26,12 +26,12 @@ After the installation, you will be able to use the `fbs` executable. Starting a new project ====================== -`fbs` provides nice features that allow you to create a base +`fbs` provides nice features that lets you create a base project structure by executing the following command:: fbs startproject -This process will prompt you to answer many questions to configure the details +This command prompts you to answer a few questions to configure the details of your project, like: * Application name @@ -39,8 +39,8 @@ of your project, like: * Qt bindings (PySide2 or PyQt5) * Bundle indentified (for macOS) -After the process finishes, you will have a `src/` directory that -will contain the following structure:: +After it finishes, you will have a `src/` directory that +contains the following structure:: └── src ├── build @@ -52,31 +52,27 @@ will contain the following structure:: │ └── mac └── python -Inside the `settings` directory you can find a couple of `json` files -that you can edit to include more information about your project. +Inside the `settings` directory, you will find a couple of `json` files +that can be edited to include more information about your project. -The main file will be under the `python` directory, and its content by default is:: +The `main` file will be under the `python` directory, and its content +by default is:: from fbs_runtime.application_context import ApplicationContext from PySide2.QtWidgets import QMainWindow import sys - class AppContext(ApplicationContext): # 1. Subclass ApplicationContext - def run(self): # 2. Implement run() - window = QMainWindow() - version = self.build_settings['version'] - window.setWindowTitle("MyApp v" + version) - window.resize(250, 150) - window.show() - return self.app.exec_() # 3. End run() with this line - if __name__ == '__main__': - appctxt = AppContext() # 4. Instantiate the subclass - exit_code = appctxt.run() # 5. Invoke run() + appctxt = ApplicationContext() # 1. Instantiate ApplicationContext + window = QMainWindow() + window.resize(250, 150) + window.show() + exit_code = appctxt.app.exec_() # 2. Invoke appctxt.app.exec_() sys.exit(exit_code) -The example will show an empty `QMainWindow`, and you can execute it by running:: +This example shows an empty `QMainWindow`. You can run it using the +following command:: fbs run @@ -84,23 +80,24 @@ Freezing the application ======================== Once you verify that the application is properly working, -you can continue with the freezing process:: +you can continue with the freezing process using the following +command:: fbs freeze After the process finishes, you will get a message stating the location -of your executable, e.g.:: +of your executable. For example:: Done. You can now run `target/MyApp/MyApp`. If that doesn't work, see https://build-system.fman.io/troubleshooting. -Then executing the application will result in the same window -you saw with the `fbs run` command:: +You can now try running the application, which will result in the same +window that you saw with the `fbs run` command:: cd target/MyApp/ ./MyApp -.. note:: This is the case for Linux. For other platforms like macOS, you will need to - enter the directory: `target/MyApp.app/Contents/MacOS`, and for - Windows you will find a `MyApp.exe` executable. +.. note:: This is the case for Linux. For other platforms like macOS, + you need to enter the directory: `target/MyApp.app/Contents/macOS`, + and for Windows find the `MyApp.exe` executable. diff --git a/sources/pyside2/doc/deployment-pyinstaller.rst b/sources/pyside2/doc/deployment-pyinstaller.rst index f361daf4a..7a720f558 100644 --- a/sources/pyside2/doc/deployment-pyinstaller.rst +++ b/sources/pyside2/doc/deployment-pyinstaller.rst @@ -2,12 +2,12 @@ |project| & PyInstaller ======================= -`PyInstaller <https://www.pyinstaller.org/>`_ allows you to freeze your python +`PyInstaller <https://www.pyinstaller.org/>`_ lets you freeze your python application into a stand-alone executable. The supported platforms are Linux, macOS, Windows, FreeBSD, and others. One of the main goals of `PyInstaller` is to be compatible with 3rd-party -Python modules, e.g.: |pymodname|. +Python modules, for example: |pymodname|. You can read the `official documentation <https://www.pyinstaller.org/documentation.html>`_ to clarify any further question, and remember to contribute to @@ -17,7 +17,7 @@ by filing issues if you find any, or contributing to their development. Preparation =========== -Installing `PyInstaller` can be done via **pip**:: +Installing `PyInstaller` can be done using **pip**:: pip install pyinstaller @@ -26,12 +26,11 @@ installing `PyInstaller` into it. After the installation, the `pyinstaller` binary will be located in the `bin/` directory of your virtual environment, or where your Python executable is located. +If that directory is not in your `PATH`, include the whole path when executing `pyinstaller`. -If that directory is not in your `PATH`, you need to include the whole path -when executing `pyinstaller`. - -.. warning:: If you already have PySide2 or Shiboken2 installed in your system, PyInstaller will pick them - instead of your virtual environment ones. +.. warning:: If you already have a PySide2 or Shiboken2 version installed in your + system path, PyInstaller will pick them instead of your virtual environment + version. Freezing an application ======================= @@ -41,13 +40,12 @@ To learn more about them you can just run `pyinstaller -h`. Two main features are the option to package the whole project (including the shared libraries) into one executable file (`--onefile`), -and to prepare a directory that will contain -an executable next to all the used libraries. +and to place it in a directory containing the libraries. Additionally, for Windows you can enable opening a console during the -execution with the option `-c` (or equivalent `--console` or `--nowindowed`). +execution with the option, `-c` (or equivalent `--console` or `--nowindowed`). Further, you can specify to not open such console window -on macOS and Windows with the option `-w` (or equivalent `--windowed` or `--noconsole`). +on macOS and Windows with the option, `-w` (or equivalent `--windowed` or `--noconsole`). Creating an example ------------------- @@ -93,32 +91,33 @@ Now, consider the following simple script, named `hello.py`:: sys.exit(app.exec_()) -Since it has a UI, we will use the `--windowed` option. +As it has a UI, you will use the `--windowed` option. -The command line to proceed will look like this:: +The command line to proceed looks like this:: pyinstaller --name="MyApplication" --windowed hello.py -This process will create a `dist/` and `build/` directory. -The executable and all the shared libraries required by your application -will be placed inside `dist/MyApplication`. +This process creates a `dist/` and `build/` directory. +The application executable and the required shared libraries are +placed in `dist/MyApplication`. -To execute the frozen application you can go inside `dist/MyApplication` and +To run the application you can go to `dist/MyApplication` and execute the program:: cd dist/MyApplication/ ./MyApplication -.. note:: The directory inside `dist/` and the executable will have the same name. +.. note:: The directory inside `dist/` and the executable will have +the same name. -If you prefer to have everything bundled into one executable, i.e.: -no shared libraries next to the executable, you can use the option +If you prefer to have everything bundled into one executable, +without the shared libraries next to it, you can use the option `--onefile`:: pyinstaller --name="MyApplication" --windowed --onefile hello.py -This process will take a bit longer, but in the end you will discover -an executable inside the `dist/` directory that you can execute:: +This process takes a bit longer, but in the end you will have one +executable in the `dist/` directory:: cd dist/ ./MyApplication @@ -131,26 +130,29 @@ Current Caveats To Be Aware Of PyInstaller Problem ------------------- -As already mentioned, `PyInstaller` will pick a system installation of PySide2 or -Shiboken2 instead of your virtualenv version without notice, if it exists. -This may be no problem if those PySide2 or shiboken2 versions are the same. - -If you are working with different versions, this can result in frustrating sessions, -when you think you are testing a new version, but `PyInstaller` -is silently working with a different, older version. +As already mentioned, `PyInstaller` will pick a system installation +of PySide2 or Shiboken2 instead of your virtualenv version without +notice, if it exists. This may not be a problem if those two +versions are the same. +If you are working with different versions, this can result in +frustrating debugging sessions. You could think you are testing the +latest version, but `PyInstaller` could be working with an older +version. Problem with numpy in Python 2.7.16 ----------------------------------- -A recent problem of PyInstaller is the appearance of Python 2.7.16 . -This Python version creates a problem that is known from Python 3 as a `Tcl/Tk` problem. -This does rarely show up in Python 3 because `Tcl/Tk` is seldom used with `PyInstaller. +A recent problem of PyInstaller is the appearance of Python 2.7.16. +This Python version creates a problem that is known from Python 3 +as a `Tcl/Tk` problem. This does rarely show up in Python 3 because +`Tcl/Tk` is seldom used with `PyInstaller. -On Python 2.7.16, this problem is very much visible, since many people are using numpy. -For some reason, installing `numpy` creates a dependency of `Tcl/Tk`, which can -be circumvented only by explicitly excluding `Tcl/Tk` related things by adding -this line to the analysis section of the spec-file:: +On Python 2.7.16, this problem is very much visible, as many are +using numpy. For some reason, installing `numpy` creates a +dependency to `Tcl/Tk`, which can be circumvented only by explicitly +excluding `Tcl/Tk` related things by adding this line to the analysis +section of the spec-file:: excludes=['FixTk', 'tcl', 'tk', '_tkinter', 'tkinter', 'Tkinter'], @@ -162,12 +164,12 @@ o When using `PyInstaller` with `virtualenv`, make sure that there is no system installation of PySide2 or shiboken2. o Before compiling, use `pip -uninstall pyside2 shiboken2 -y` multiple times, until - none of the programs is found anymore. + none of the programs are found anymore. o Pip is usually a good tool. But to be 100 % sure, you should directly remove the PySide2 and shiboken2 folders from site-packages. o Be sure to use the right version of pip. The safest way to really run the right - pip, use the Python that you mean: Instead of the pip command, better use:: + pip, is to use the Python that you mean: Instead of the pip command, better use:: <path/to/your/>python -m pip diff --git a/sources/pyside2/doc/deployment.rst b/sources/pyside2/doc/deployment.rst index 582e38992..eb8d77b0d 100644 --- a/sources/pyside2/doc/deployment.rst +++ b/sources/pyside2/doc/deployment.rst @@ -6,65 +6,60 @@ Deploying or freezing an application is a crucial part of many Python projects. Most large projects are not based on a single Python file, so the distribution of these applications becomes more difficult. -The options for a project are: +Here are a few distribution options that you could use: 1. Sending a normal zip-file with the application's content. 2. Building a proper `Python package (wheel) <https://packaging.python.org/>`_. - 3. Freezing the application in a single binary file, or into a directory. + 3. Freezing the application into a single binary file or a directory. -For the **third** option, there are many available tools: +If you choose the **third** option, consider using one of these tools: + * `fbs <https://build-system.fman.io/>`_, * `PyInstaller <https://www.pyinstaller.org/>`_, * `cx_Freeze <https://anthony-tuininga.github.io/cx_Freeze/>`_, * `py2exe <http://www.py2exe.org/>`_, * `py2app <https://py2app.readthedocs.io/en/latest/>`_, -Since |project| is a cross-platform framework, -we would like to focus on solutions that at least work on -the three major platform supported by Qt: Linux, macOS, and Windows. - -The following table summarizes the above mentioned tools support: +|project| is a cross-platform framework, +so we would like to focus on solutions that work on the three +major platforms supported by Qt: Linux, macOS, and Windows. +The following table summarizes the platform support for those packaging +tools: =========== ======= ===== ===== ======= Name License Linux macOS Windows =========== ======= ===== ===== ======= +fbs GPL yes yes yes +PyInstaller GPL yes yes yes +cx_Freeze MIT yes yes yes py2exe MIT no no yes py2app MIT no yes no -cx_Freeze MIT yes yes yes -PyInstaller GPL yes yes yes =========== ======= ===== ===== ======= -From the table we can see that only *cx_Freeze* and *PyInstaller* -meet our requirements. +According to this table, only *fbs*, *cx_Freeze*, and *PyInstaller* +meets our cross-platform requirement. -All tools are command-line based, and it could become -a hard task to include more resources to your application, such as -images, icons, and meta-information, because you will need to create -special hooks or separate scripts to handle them. -Additionally, since this only -allows you to freeze your current application, you don't have -any mechanism to update your application. +As these are command-line tools, it could be hard to include +resources to your application, such as images, icons, and +meta-information. This means, you will need special hooks +or scripts to handle them before adding to the package. +In addition to this, these tools does not offer a mechanism +to update your application packages. -To cover the update part, there is a tool built around PyInstaller -called `PyUpdater <https://www.pyupdater.org/>`_ which enables -a simple mechanism to ship applications updates. +To create update packages, use the `PyUpdater <https://www.pyupdater.org/>`_, +which is built around PyInstaller. -On top of all these features, including also a nice interface -that allows the user to install the application step by step, -or even better, provide templates to create new projects to easily -freeze-them-up is something really beneficial for both developers -and end-users. -This is where `fbs <https://build-system.fman.io>`_ enters the -game, being based on PyInstaller, but including all the nice features -we previously mentioned. +The `fbs <https://build-system.fman.io>`_ tool offers a nice UI +that allows the user to install the application step-by-step. Here you can find a set of tutorials on how to use the previously described tools. -.. note:: Deployment is possible only in Qt for Python 5.12.2 +.. note:: Deployment is supported only from Qt for Python 5.12.2 and +later. .. toctree:: :name: mastertoc :maxdepth: 2 + deployment-fbs.rst deployment-pyinstaller.rst deployment-cxfreeze.rst - deployment-fbs.rst diff --git a/sources/pyside2/doc/pysideversion.rst b/sources/pyside2/doc/pysideversion.rst deleted file mode 100644 index bde48b39e..000000000 --- a/sources/pyside2/doc/pysideversion.rst +++ /dev/null @@ -1,31 +0,0 @@ -Printing |project| and Qt version -********************************* - -|project| exports its version numbers in a pythonic way. You can print these -numbers using the following python constructs: - - :: - - import PySide2.QtCore - - # Prints PySide2 version - # e.g. 5.11.1a1 - print(PySide2.__version__) - - # Gets a tuple with each version component - # e.g. (5, 11, 1, 'a', 1) - print(PySide2.__version_info__) - - # Prints the Qt version used to compile PySide2 - # e.g. "5.11.2" - print(PySide2.QtCore.__version__) - - # Gets a tuple with each version components of Qt used to compile PySide2 - # e.g. (5, 11, 2) - print(PySide2.QtCore.__version_info__) - - -Note that the Qt version used to compile |project| may differ from the version used to -run |project|. To print the current running Qt version number, you can use:: - - print(PySide2.QtCore.qVersion()) diff --git a/sources/pyside2/doc/tutorials/datavisualize/add_chart.rst b/sources/pyside2/doc/tutorials/datavisualize/add_chart.rst new file mode 100644 index 000000000..0c9803269 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/add_chart.rst @@ -0,0 +1,20 @@ +Chapter 5 - Add a chart view +============================= + +A table is nice to present data, but a chart is even better. For this, you +need the QtCharts module that provides many types of plots and options to +graphically represent data. + +The placeholder for a plot is a QChartView, and inside that Widget you can +place a QChart. As a first step, try including only this without any data to +plot. + +Make the following highlighted changes to :code:`main_widget.py` from the +previous chapter to add a QChartView: + +.. literalinclude:: datavisualize5/main_widget.py + :linenos: + :lines: 40- + :emphasize-lines: 2-3,6,22-37,48-51 + + diff --git a/sources/pyside2/doc/tutorials/datavisualize/add_mainwindow.rst b/sources/pyside2/doc/tutorials/datavisualize/add_mainwindow.rst new file mode 100644 index 000000000..a9ff38a30 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/add_mainwindow.rst @@ -0,0 +1,32 @@ +Chapter 3 - Create an empty QMainWindow +========================================== + +You can now think of presenting your data in a UI. A QMainWindow provides a +convenient structure for GUI applications, such as a menu bar and status bar. +The following image shows the layout that QMainWindow offers out-of-the box: + +.. image:: images/QMainWindow-layout.png + :alt: QMainWindow layout + :align: right + +In this case, let your application inherit from QMainWindow, and add the +following UI elements: + +* A "File" menu to open a File dialog. +* An "Exit" menu close the window. +* A status message on the status bar when the application starts. + +In addition, you can define a fixed size for the window or adjust it based on +the resolution you currently have. In the following snippet, you will see how +window size is defined based on available screen width (80%) and height (70%). + +.. note:: You can achieve a similar structure using other Qt elements like + QMenuBar, QWidget, and QStatusBar. Refer the QMainWindow layout for + guidance. + +.. literalinclude:: datavisualize3/main_window.py + :language: python + :linenos: + :lines: 40- + +Try running the script to see what output you get with it. diff --git a/sources/pyside2/doc/tutorials/datavisualize/add_tableview.rst b/sources/pyside2/doc/tutorials/datavisualize/add_tableview.rst new file mode 100644 index 000000000..bbf27f2da --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/add_tableview.rst @@ -0,0 +1,68 @@ +Chapter 4 - Add a QTableView +============================= + +Now that you have a QMainWindow, you can include a centralWidget to your +interface. Usually, a QWidget is used to display data in most data-driven +applications. Use a table view to display your data. + +The first step is to add a horizontal layout with just a QTableView. You +can create a QTableView object and place it inside a QHBoxLayout. Once the +QWidget is properly built, pass the object to the QMainWindow as its central +widget. + +Remember that a QTableView needs a model to display information. In this case, +you can use a QAbstractTableModel instance. + +.. note:: You could also use the default item model that comes with a + QTableWidget instead. QTableWidget is a convenience class that reduces + your codebase considerably as you don't need to implement a data model. + However, it's less flexible than a QTableView, as QTableWidget cannot be + used with just any data. For more insight about Qt's model-view framework, + refer to the + `Model View Programming <http://doc.qt.io/qt-5/model-view-programming.html>` + documentation. + +Implementing the model for your QTableView, allows you to: +- set the headers, +- manipulate the formats of the cell values (remember we have UTC time and float +numbers), +- set style properties like text alignment, +- and even set color properties for the cell or its content. + +To subclass the QAbstractTable, you must reimplement its virtual methods, +rowCount(), columnCount(), and data(). This way, you can ensure that the data +is handled properly. In addition, reimplement the headerData() method to +provide the header information to the view. + +Here is a script that implements the CustomTableModel: + +.. literalinclude:: datavisualize4/table_model.py + :language: python + :linenos: + :lines: 40- + +Now, create a QWidget that has a QTableView, and connect it to your +CustomTableModel. + +.. literalinclude:: datavisualize4/main_widget.py + :language: python + :linenos: + :emphasize-lines: 12-17 + :lines: 40- + +You also need minor changes to the :code:`main_window.py` and +:code:`main.py` from chapter 3 to include the Widget inside the +MainWindow. + +In the following snippets you'll see those changes highlighted: + +.. literalinclude:: datavisualize4/main_window.py + :language: python + :linenos: + :emphasize-lines: 8,11 + +.. literalinclude:: datavisualize4/main.py + :language: python + :linenos: + :emphasize-lines: 46-47 + diff --git a/sources/pyside2/doc/tutorials/datavisualize/all_hour.csv b/sources/pyside2/doc/tutorials/datavisualize/all_hour.csv new file mode 100644 index 000000000..400947c3c --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/all_hour.csv @@ -0,0 +1,8 @@ +time,latitude,longitude,depth,mag,magType,nst,gap,dmin,rms,net,id,updated,place,type,horizontalError,depthError,magError,magNst,status,locationSource,magSource +2019-01-10T12:11:24.810Z,34.1281662,-117.7754974,4.46,1.18,ml,22,69,0.04475,0.13,ci,ci38421072,2019-01-10T12:13:30.138Z,"3km NNW of La Verne, CA",earthquake,0.3,0.55,0.246,6,automatic,ci,ci +2019-01-10T12:04:26.320Z,19.4433327,-155.6159973,0.72,1.79,md,22,99,0.04026,0.3,hv,hv70763571,2019-01-10T12:07:28.690Z,"26km E of Honaunau-Napoopoo, Hawaii",earthquake,0.6,1.79,0.28,6,automatic,hv,hv +2019-01-10T11:57:48.980Z,33.3225,-116.3931667,4.84,0.62,ml,15,211,0.05776,0.16,ci,ci38421064,2019-01-10T12:01:29.166Z,"8km NNW of Borrego Springs, CA",earthquake,0.71,0.68,0.111,11,automatic,ci,ci +2019-01-10T11:52:09.490Z,38.8356667,-122.8366699,1.28,2.74,md,25,77,0.003061,0.04,nc,nc73131566,2019-01-10T12:14:02.757Z,"10km NW of The Geysers, CA",earthquake,0.19,0.29,0.06,7,automatic,nc,nc +2019-01-10T11:25:44.854Z,65.1082,-149.3701,20.6,2.1,ml,,,,1.02,ak,ak019gq2oer,2019-01-10T11:37:07.060Z,"60km NNW of North Nenana, Alaska",earthquake,,0.3,,,automatic,ak,ak +2019-01-10T11:25:23.786Z,69.1518,-144.4977,10.4,3.7,ml,,,,0.74,ak,ak019gq2ndz,2019-01-10T11:47:11.284Z,"114km SSW of Kaktovik, Alaska",earthquake,,1.6,,,reviewed,ak,ak +2019-01-10T11:16:11.761Z,61.3318,-150.0708,20.1,2.7,ml,,,,0.83,ak,ak019gq0ozj,2019-01-10T11:29:24.610Z,"15km NW of Anchorage, Alaska",earthquake,,0.4,,,automatic,ak,ak diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize.tar.bz2 b/sources/pyside2/doc/tutorials/datavisualize/datavisualize.tar.bz2 Binary files differnew file mode 100644 index 000000000..5fe12769a --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize.tar.bz2 diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize1/main.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize1/main.py new file mode 100644 index 000000000..8a8a1dfda --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize1/main.py @@ -0,0 +1,55 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import argparse +import pandas as pd + + +def read_data(fname): + return pd.read_csv(fname) + + +if __name__ == "__main__": + options = argparse.ArgumentParser() + options.add_argument("-f", "--file", type=str, required=True) + args = options.parse_args() + data = read_data(args.file) + print(data) + diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize2/main.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize2/main.py new file mode 100644 index 000000000..33bd34723 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize2/main.py @@ -0,0 +1,78 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import argparse +import pandas as pd + +from PySide2.QtCore import QDateTime, QTimeZone + + +def transform_date(utc, timezone=None): + utc_fmt = "yyyy-MM-ddTHH:mm:ss.zzzZ" + new_date = QDateTime().fromString(utc, utc_fmt) + if timezone: + new_date.setTimeZone(timezone) + return new_date + + +def read_data(fname): + # Read the CSV content + df = pd.read_csv(fname) + + # Remove wrong magnitudes + df = df.drop(df[df.mag < 0].index) + magnitudes = df["mag"] + + # My local timezone + timezone = QTimeZone(b"Europe/Berlin") + + # Get timestamp transformed to our timezone + times = df["time"].apply(lambda x: transform_date(x, timezone)) + + return times, magnitudes + + +if __name__ == "__main__": + options = argparse.ArgumentParser() + options.add_argument("-f", "--file", type=str, required=True) + args = options.parse_args() + data = read_data(args.file) + print(data) + diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize3/main.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize3/main.py new file mode 100644 index 000000000..dd07a689f --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize3/main.py @@ -0,0 +1,88 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +import argparse +import pandas as pd + +from PySide2.QtCore import QDateTime, QTimeZone +from PySide2.QtWidgets import QApplication +from main_window import MainWindow + + +def transform_date(utc, timezone=None): + utc_fmt = "yyyy-MM-ddTHH:mm:ss.zzzZ" + new_date = QDateTime().fromString(utc, utc_fmt) + if timezone: + new_date.setTimeZone(timezone) + return new_date + + +def read_data(fname): + # Read the CSV content + df = pd.read_csv(fname) + + # Remove wrong magnitudes + df = df.drop(df[df.mag < 0].index) + magnitudes = df["mag"] + + # My local timezone + timezone = QTimeZone(b"Europe/Berlin") + + # Get timestamp transformed to our timezone + times = df["time"].apply(lambda x: transform_date(x, timezone)) + + return times, magnitudes + + +if __name__ == "__main__": + options = argparse.ArgumentParser() + options.add_argument("-f", "--file", type=str, required=True) + args = options.parse_args() + data = read_data(args.file) + + # Qt Application + app = QApplication(sys.argv) + + window = MainWindow() + window.show() + + sys.exit(app.exec_()) + diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize3/main_window.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize3/main_window.py new file mode 100644 index 000000000..64f831e5d --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize3/main_window.py @@ -0,0 +1,69 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtCore import Slot, qApp +from PySide2.QtGui import QKeySequence +from PySide2.QtWidgets import QMainWindow, QAction + + +class MainWindow(QMainWindow): + def __init__(self): + QMainWindow.__init__(self) + self.setWindowTitle("Eartquakes information") + + # Menu + self.menu = self.menuBar() + self.file_menu = self.menu.addMenu("File") + + # Exit QAction + exit_action = QAction("Exit", self) + exit_action.setShortcut(QKeySequence.Quit) + exit_action.triggered.connect(self.close) + + self.file_menu.addAction(exit_action) + + # Status Bar + self.status = self.statusBar() + self.status.showMessage("Data loaded and plotted") + + # Window dimensions + geometry = qApp.desktop().availableGeometry(self) + self.setFixedSize(geometry.width() * 0.8, geometry.height() * 0.7) + diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize4/main.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize4/main.py new file mode 100644 index 000000000..43c5cd521 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize4/main.py @@ -0,0 +1,90 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +import argparse +import pandas as pd + +from PySide2.QtCore import QDateTime, QTimeZone +from PySide2.QtWidgets import QApplication +from main_window import MainWindow +from main_widget import Widget + + +def transform_date(utc, timezone=None): + utc_fmt = "yyyy-MM-ddTHH:mm:ss.zzzZ" + new_date = QDateTime().fromString(utc, utc_fmt) + if timezone: + new_date.setTimeZone(timezone) + return new_date + + +def read_data(fname): + # Read the CSV content + df = pd.read_csv(fname) + + # Remove wrong magnitudes + df = df.drop(df[df.mag < 0].index) + magnitudes = df["mag"] + + # My local timezone + timezone = QTimeZone(b"Europe/Berlin") + + # Get timestamp transformed to our timezone + times = df["time"].apply(lambda x: transform_date(x, timezone)) + + return times, magnitudes + + +if __name__ == "__main__": + options = argparse.ArgumentParser() + options.add_argument("-f", "--file", type=str, required=True) + args = options.parse_args() + data = read_data(args.file) + + # Qt Application + app = QApplication(sys.argv) + + widget = Widget(data) + window = MainWindow(widget) + window.show() + + sys.exit(app.exec_()) + diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize4/main_widget.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize4/main_widget.py new file mode 100644 index 000000000..0c780241a --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize4/main_widget.py @@ -0,0 +1,80 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtWidgets import (QHBoxLayout, QHeaderView, QSizePolicy, + QTableView, QWidget) + +from table_model import CustomTableModel + + +class Widget(QWidget): + def __init__(self, data): + QWidget.__init__(self) + + # Getting the Model + self.model = CustomTableModel(data) + + # Creating a QTableView + self.table_view = QTableView() + self.table_view.setModel(self.model) + + # QTableView Headers + self.horizontal_header = self.table_view.horizontalHeader() + self.vertical_header = self.table_view.verticalHeader() + self.horizontal_header.setSectionResizeMode( + QHeaderView.ResizeToContents + ) + self.vertical_header.setSectionResizeMode( + QHeaderView.ResizeToContents + ) + self.horizontal_header.setStretchLastSection(True) + + # QWidget Layout + self.main_layout = QHBoxLayout() + size = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) + + ## Left layout + size.setHorizontalStretch(1) + self.table_view.setSizePolicy(size) + self.main_layout.addWidget(self.table_view) + + # Set the layout to the QWidget + self.setLayout(self.main_layout) + diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize4/main_window.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize4/main_window.py new file mode 100644 index 000000000..9f7c6814f --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize4/main_window.py @@ -0,0 +1,69 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtCore import Slot, qApp +from PySide2.QtGui import QKeySequence +from PySide2.QtWidgets import QMainWindow, QAction + + +class MainWindow(QMainWindow): + def __init__(self, widget): + QMainWindow.__init__(self) + self.setWindowTitle("Eartquakes information") + self.setCentralWidget(widget) + # Menu + self.menu = self.menuBar() + self.file_menu = self.menu.addMenu("File") + + ## Exit QAction + exit_action = QAction("Exit", self) + exit_action.setShortcut(QKeySequence.Quit) + exit_action.triggered.connect(self.close) + + self.file_menu.addAction(exit_action) + + # Status Bar + self.status = self.statusBar() + self.status.showMessage("Data loaded and plotted") + + # Window dimensions + geometry = qApp.desktop().availableGeometry(self) + self.setFixedSize(geometry.width() * 0.8, geometry.height() * 0.7) + diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize4/table_model.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize4/table_model.py new file mode 100644 index 000000000..d2eafb244 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize4/table_model.py @@ -0,0 +1,88 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtCore import Qt, QAbstractTableModel, QModelIndex +from PySide2.QtGui import QColor + + +class CustomTableModel(QAbstractTableModel): + def __init__(self, data=None): + QAbstractTableModel.__init__(self) + self.load_data(data) + + def load_data(self, data): + self.input_dates = data[0].values + self.input_magnitudes = data[1].values + + self.column_count = 2 + self.row_count = len(self.input_magnitudes) + + def rowCount(self, parent=QModelIndex()): + return self.row_count + + def columnCount(self, parent=QModelIndex()): + return self.column_count + + def headerData(self, section, orientation, role): + if role != Qt.DisplayRole: + return None + if orientation == Qt.Horizontal: + return ("Date", "Magnitude")[section] + else: + return "{}".format(section) + + def data(self, index, role=Qt.DisplayRole): + column = index.column() + row = index.row() + + if role == Qt.DisplayRole: + if column == 0: + raw_date = self.input_dates[row] + date = "{}".format(raw_date.toPython()) + return date[:-3] + elif column == 1: + return "{:.2f}".format(self.input_magnitudes[row]) + elif role == Qt.BackgroundRole: + return QColor(Qt.white) + elif role == Qt.TextAlignmentRole: + return Qt.AlignRight + + return None + diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize5/main.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize5/main.py new file mode 100644 index 000000000..43c5cd521 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize5/main.py @@ -0,0 +1,90 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +import argparse +import pandas as pd + +from PySide2.QtCore import QDateTime, QTimeZone +from PySide2.QtWidgets import QApplication +from main_window import MainWindow +from main_widget import Widget + + +def transform_date(utc, timezone=None): + utc_fmt = "yyyy-MM-ddTHH:mm:ss.zzzZ" + new_date = QDateTime().fromString(utc, utc_fmt) + if timezone: + new_date.setTimeZone(timezone) + return new_date + + +def read_data(fname): + # Read the CSV content + df = pd.read_csv(fname) + + # Remove wrong magnitudes + df = df.drop(df[df.mag < 0].index) + magnitudes = df["mag"] + + # My local timezone + timezone = QTimeZone(b"Europe/Berlin") + + # Get timestamp transformed to our timezone + times = df["time"].apply(lambda x: transform_date(x, timezone)) + + return times, magnitudes + + +if __name__ == "__main__": + options = argparse.ArgumentParser() + options.add_argument("-f", "--file", type=str, required=True) + args = options.parse_args() + data = read_data(args.file) + + # Qt Application + app = QApplication(sys.argv) + + widget = Widget(data) + window = MainWindow(widget) + window.show() + + sys.exit(app.exec_()) + diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize5/main_widget.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize5/main_widget.py new file mode 100644 index 000000000..08406d341 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize5/main_widget.py @@ -0,0 +1,91 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtCore import QDateTime, Qt +from PySide2.QtGui import QPainter +from PySide2.QtWidgets import (QWidget, QHeaderView, QHBoxLayout, QTableView, + QSizePolicy) +from PySide2.QtCharts import QtCharts + +from table_model import CustomTableModel + + +class Widget(QWidget): + def __init__(self, data): + QWidget.__init__(self) + + # Getting the Model + self.model = CustomTableModel(data) + + # Creating a QTableView + self.table_view = QTableView() + self.table_view.setModel(self.model) + + # QTableView Headers + self.horizontal_header = self.table_view.horizontalHeader() + self.vertical_header = self.table_view.verticalHeader() + self.horizontal_header.setSectionResizeMode(QHeaderView.ResizeToContents) + self.vertical_header.setSectionResizeMode(QHeaderView.ResizeToContents) + self.horizontal_header.setStretchLastSection(True) + + # Creating QChart + self.chart = QtCharts.QChart() + self.chart.setAnimationOptions(QtCharts.QChart.AllAnimations) + + # Creating QChartView + self.chart_view = QtCharts.QChartView(self.chart) + self.chart_view.setRenderHint(QPainter.Antialiasing) + + # QWidget Layout + self.main_layout = QHBoxLayout() + size = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) + + ## Left layout + size.setHorizontalStretch(1) + self.table_view.setSizePolicy(size) + self.main_layout.addWidget(self.table_view) + + ## Right Layout + size.setHorizontalStretch(4) + self.chart_view.setSizePolicy(size) + self.main_layout.addWidget(self.chart_view) + + # Set the layout to the QWidget + self.setLayout(self.main_layout) diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize5/main_window.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize5/main_window.py new file mode 100644 index 000000000..4786365e8 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize5/main_window.py @@ -0,0 +1,69 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtCore import Slot, qApp +from PySide2.QtGui import QKeySequence +from PySide2.QtWidgets import QMainWindow, QAction + + +class MainWindow(QMainWindow): + def __init__(self, widget): + QMainWindow.__init__(self) + self.setWindowTitle("Eartquakes information") + self.setCentralWidget(widget) + # Menu + self.menu = self.menuBar() + self.file_menu = self.menu.addMenu("File") + + # Exit QAction + exit_action = QAction("Exit", self) + exit_action.setShortcut(QKeySequence.Quit) + exit_action.triggered.connect(self.close) + + self.file_menu.addAction(exit_action) + + # Status Bar + self.status = self.statusBar() + self.status.showMessage("Data loaded and plotted") + + # Window dimensions + geometry = qApp.desktop().availableGeometry(self) + self.setFixedSize(geometry.width() * 0.8, geometry.height() * 0.7) + diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize5/table_model.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize5/table_model.py new file mode 100644 index 000000000..d2eafb244 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize5/table_model.py @@ -0,0 +1,88 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtCore import Qt, QAbstractTableModel, QModelIndex +from PySide2.QtGui import QColor + + +class CustomTableModel(QAbstractTableModel): + def __init__(self, data=None): + QAbstractTableModel.__init__(self) + self.load_data(data) + + def load_data(self, data): + self.input_dates = data[0].values + self.input_magnitudes = data[1].values + + self.column_count = 2 + self.row_count = len(self.input_magnitudes) + + def rowCount(self, parent=QModelIndex()): + return self.row_count + + def columnCount(self, parent=QModelIndex()): + return self.column_count + + def headerData(self, section, orientation, role): + if role != Qt.DisplayRole: + return None + if orientation == Qt.Horizontal: + return ("Date", "Magnitude")[section] + else: + return "{}".format(section) + + def data(self, index, role=Qt.DisplayRole): + column = index.column() + row = index.row() + + if role == Qt.DisplayRole: + if column == 0: + raw_date = self.input_dates[row] + date = "{}".format(raw_date.toPython()) + return date[:-3] + elif column == 1: + return "{:.2f}".format(self.input_magnitudes[row]) + elif role == Qt.BackgroundRole: + return QColor(Qt.white) + elif role == Qt.TextAlignmentRole: + return Qt.AlignRight + + return None + diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize6/main.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize6/main.py new file mode 100644 index 000000000..441d81a32 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize6/main.py @@ -0,0 +1,92 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +import argparse +import pandas as pd + +from PySide2.QtCore import QDateTime, QTimeZone +from PySide2.QtWidgets import QApplication + +from main_window import MainWindow +from main_widget import Widget + + +def transform_date(utc, timezone=None): + utc_fmt = "yyyy-MM-ddTHH:mm:ss.zzzZ" + new_date = QDateTime().fromString(utc, utc_fmt) + if timezone: + new_date.setTimeZone(timezone) + return new_date + + +def read_data(fname): + # Read the CSV content + df = pd.read_csv(fname) + + # Remove wrong magnitudes + df = df.drop(df[df.mag < 0].index) + magnitudes = df["mag"] + + # My local timezone + timezone = QTimeZone(b"Europe/Berlin") + + # Get timestamp transformed to our timezone + times = df["time"].apply(lambda x: transform_date(x, timezone)) + + return times, magnitudes + + +if __name__ == "__main__": + options = argparse.ArgumentParser() + options.add_argument("-f", "--file", type=str, required=True) + args = options.parse_args() + data = read_data(args.file) + + # Qt Application + app = QApplication(sys.argv) + + # QWidget + widget = Widget(data) + # QMainWindow using QWidget as central widget + window = MainWindow(widget) + + window.show() + sys.exit(app.exec_()) diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize6/main_widget.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize6/main_widget.py new file mode 100644 index 000000000..2d2452bf9 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize6/main_widget.py @@ -0,0 +1,131 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtCore import QDateTime, Qt +from PySide2.QtGui import QPainter +from PySide2.QtWidgets import (QWidget, QHeaderView, QHBoxLayout, QTableView, + QSizePolicy) +from PySide2.QtCharts import QtCharts + +from table_model import CustomTableModel + + +class Widget(QWidget): + def __init__(self, data): + QWidget.__init__(self) + + # Getting the Model + self.model = CustomTableModel(data) + + # Creating a QTableView + self.table_view = QTableView() + self.table_view.setModel(self.model) + + # QTableView Headers + resize = QHeaderView.ResizeToContents + self.horizontal_header = self.table_view.horizontalHeader() + self.vertical_header = self.table_view.verticalHeader() + self.horizontal_header.setSectionResizeMode(resize) + self.vertical_header.setSectionResizeMode(resize) + self.horizontal_header.setStretchLastSection(True) + + # Creating QChart + self.chart = QtCharts.QChart() + self.chart.setAnimationOptions(QtCharts.QChart.AllAnimations) + self.add_series("Magnitude (Column 1)", [0, 1]) + + # Creating QChartView + self.chart_view = QtCharts.QChartView(self.chart) + self.chart_view.setRenderHint(QPainter.Antialiasing) + + # QWidget Layout + self.main_layout = QHBoxLayout() + size = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) + + # Left layout + size.setHorizontalStretch(1) + self.table_view.setSizePolicy(size) + self.main_layout.addWidget(self.table_view) + + # Right Layout + size.setHorizontalStretch(4) + self.chart_view.setSizePolicy(size) + self.main_layout.addWidget(self.chart_view) + + # Set the layout to the QWidget + self.setLayout(self.main_layout) + + def add_series(self, name, columns): + # Create QLineSeries + self.series = QtCharts.QLineSeries() + self.series.setName(name) + + # Filling QLineSeries + for i in range(self.model.rowCount()): + # Getting the data + t = self.model.index(i, 0).data() + date_fmt = "yyyy-MM-dd HH:mm:ss.zzz" + + x = QDateTime().fromString(t, date_fmt).toSecsSinceEpoch() + y = float(self.model.index(i, 1).data()) + + if x > 0 and y > 0: + self.series.append(x, y) + + self.chart.addSeries(self.series) + + # Setting X-axis + self.axis_x = QtCharts.QDateTimeAxis() + self.axis_x.setTickCount(10) + self.axis_x.setFormat("dd.MM (h:mm)") + self.axis_x.setTitleText("Date") + self.chart.addAxis(self.axis_x, Qt.AlignBottom) + self.series.attachAxis(self.axis_x) + # Setting Y-axis + self.axis_y = QtCharts.QValueAxis() + self.axis_y.setTickCount(10) + self.axis_y.setLabelFormat("%.2f") + self.axis_y.setTitleText("Magnitude") + self.chart.addAxis(self.axis_y, Qt.AlignLeft) + self.series.attachAxis(self.axis_y) + + # Getting the color from the QChart to use it on the QTableView + self.model.color = "{}".format(self.series.pen().color().name()) + diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize6/main_window.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize6/main_window.py new file mode 100644 index 000000000..c223aa69b --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize6/main_window.py @@ -0,0 +1,70 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtCore import Slot, qApp +from PySide2.QtGui import QKeySequence +from PySide2.QtWidgets import QMainWindow, QAction + + +class MainWindow(QMainWindow): + def __init__(self, widget): + QMainWindow.__init__(self) + self.setWindowTitle("Eartquakes information") + + # Menu + self.menu = self.menuBar() + self.file_menu = self.menu.addMenu("File") + + # Exit QAction + exit_action = QAction("Exit", self) + exit_action.setShortcut(QKeySequence.Quit) + exit_action.triggered.connect(self.close) + + self.file_menu.addAction(exit_action) + + # Status Bar + self.status = self.statusBar() + self.status.showMessage("Data loaded and plotted") + + # Window dimensions + geometry = qApp.desktop().availableGeometry(self) + self.setFixedSize(geometry.width() * 0.8, geometry.height() * 0.7) + self.setCentralWidget(widget) + diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize6/table_model.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize6/table_model.py new file mode 100644 index 000000000..99e1cf19b --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize6/table_model.py @@ -0,0 +1,88 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtCore import Qt, QAbstractTableModel, QModelIndex +from PySide2.QtGui import QColor + + +class CustomTableModel(QAbstractTableModel): + def __init__(self, data=None): + QAbstractTableModel.__init__(self) + self.color = None + self.load_data(data) + + def load_data(self, data): + self.input_dates = data[0].values + self.input_magnitudes = data[1].values + + self.column_count = 2 + self.row_count = len(self.input_magnitudes) + + def rowCount(self, parent=QModelIndex()): + return self.row_count + + def columnCount(self, parent=QModelIndex()): + return self.column_count + + def headerData(self, section, orientation, role): + if role != Qt.DisplayRole: + return None + if orientation == Qt.Horizontal: + return ("Date", "Magnitude")[section] + else: + return "{}".format(section) + + def data(self, index, role=Qt.DisplayRole): + column = index.column() + row = index.row() + + if role == Qt.DisplayRole: + if column == 0: + raw_date = self.input_dates[row] + date = "{}".format(raw_date.toPython()) + return date[:-3] + elif column == 1: + return "{:.2f}".format(self.input_magnitudes[row]) + elif role == Qt.BackgroundRole: + return (QColor(Qt.white), QColor(self.color))[column] + elif role == Qt.TextAlignmentRole: + return Qt.AlignRight + + return None diff --git a/sources/pyside2/doc/tutorials/datavisualize/filter_data.rst b/sources/pyside2/doc/tutorials/datavisualize/filter_data.rst new file mode 100644 index 000000000..f54ba217c --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/filter_data.rst @@ -0,0 +1,30 @@ +Chapter 2 - Filtering data +=========================== + +In the previous chapter, you learned how to read and print data that is a +bit raw. Now, try to select a few columns and handle them properly. + +Start with these two columns: Time (time) and Magnitude (mag). After getting +the information from these columns, filter and adapt the data. Try formatting +the date to Qt types. + +There is not much to do for the Magnitude column, as it's just a floating point +number. You could take special care to check if the data is correct. This could +be done by filtering the data that follows the condition, "magnitude > 0", to +avoid faulty data or unexpected behavior. + +The Date column provides data in UTC format (for example, +2018-12-11T21:14:44.682Z), so you could easily map it to a QDateTime object +defining the structure of the string. Additionally, you can adapt the time +based on the timezone you are in, using QTimeZone. + +The following script filters and formats the CSV data as described earlier: + +.. literalinclude:: datavisualize2/main.py + :language: python + :linenos: + :emphasize-lines: 44,47-69 + :lines: 40- + +Now that you have a tuple of QDateTime and float data, try improving the +output further. That's what you'll learn in the following chapters. diff --git a/sources/pyside2/doc/tutorials/datavisualize/images/QMainWindow-layout.png b/sources/pyside2/doc/tutorials/datavisualize/images/QMainWindow-layout.png Binary files differnew file mode 100644 index 000000000..075d796b8 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/images/QMainWindow-layout.png diff --git a/sources/pyside2/doc/tutorials/datavisualize/images/datavisualization_app.png b/sources/pyside2/doc/tutorials/datavisualize/images/datavisualization_app.png Binary files differnew file mode 100644 index 000000000..ddac43fc3 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/images/datavisualization_app.png diff --git a/sources/pyside2/doc/tutorials/datavisualize/index.rst b/sources/pyside2/doc/tutorials/datavisualize/index.rst new file mode 100644 index 000000000..750012d84 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/index.rst @@ -0,0 +1,22 @@ +Data Visualization Tool Tutorial +********************************* + +In this tutorial, you'll learn about the data visualization capabilities +of |project|. To start with, find some open data to visualize. For example, +data about the magnitude of earthquakes during the last hour published on the +US Geological Survey website. You could download the +`All earthquakes <https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.csv>`_ +open data in a CSV format for this tutorial. + +In the following chapters of this tutorial you'll learn how to +visualize data from a CSV in a line chart. + +.. toctree:: + :glob: + :titlesonly: + :reversed: + + * + +You can download the sources from :download:`here <datavisualize.tar.bz2>`. + diff --git a/sources/pyside2/doc/tutorials/datavisualize/plot_datapoints.rst b/sources/pyside2/doc/tutorials/datavisualize/plot_datapoints.rst new file mode 100644 index 000000000..8ebdd2b08 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/plot_datapoints.rst @@ -0,0 +1,25 @@ +Chapter 6 - Plot the data in the ChartView +=========================================== + +The last step of this tutorial is to plot the CSV data inside our QChart. For +this, you need to go over our data and include the data on a QLineSeries. + +After adding the data to the series, you can modify the axis to properly +display the QDateTime on the X-axis, and the magnitude values on the Y-axis. + +Here is the updated :code:`main_widget.py` that includes an additional +function to plot data using a QLineSeries: + +.. literalinclude:: datavisualize6/main_widget.py + :language: python + :linenos: + :lines: 40- + :emphasize-lines: 33,56-91 + +Now, run the application to visualize the earthquake magnitudes +data at different times. + +.. image:: images/datavisualization_app.png + +Try modifying the sources to get different output. For example, you could try +to plot more data from the CSV. diff --git a/sources/pyside2/doc/tutorials/datavisualize/read_data.rst b/sources/pyside2/doc/tutorials/datavisualize/read_data.rst new file mode 100644 index 000000000..f7bf9337a --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/read_data.rst @@ -0,0 +1,41 @@ +Chapter 1 - Reading data from a CSV +=================================== + +There are several ways to read data from a CSV file. The following are the most +common ways: + +- Native reading +- the `CSV module <https://docs.python.org/3/library/csv.html>`_ +- the `numpy module <https://www.numpy.org>`_ +- the `pandas module <https://pandas.pydata.org/>`_ + +In this chapter, you will learn to use pandas to read and filter CSV data. +In addition, you could pass the data file through a command-line option to your +script. + +The following python script, :code:`main.py`, demonstrates how to do it: + +.. literalinclude:: datavisualize1/main.py + :language: python + :linenos: + :lines: 40- + +The Python script uses the :code:`argparse` module to accept and parse input +from the command line. It then uses the input, which in this case is the filename, +to read and print data to the prompt. + +Try running the script in the following way to check if you get desired output: + +:: + + $python datavisualize1/main.py -f all_hour.csv + time latitude longitude depth ... magNst status locationSource magSource + 0 2019-01-10T12:11:24.810Z 34.128166 -117.775497 4.46 ... 6.0 automatic ci ci + 1 2019-01-10T12:04:26.320Z 19.443333 -155.615997 0.72 ... 6.0 automatic hv hv + 2 2019-01-10T11:57:48.980Z 33.322500 -116.393167 4.84 ... 11.0 automatic ci ci + 3 2019-01-10T11:52:09.490Z 38.835667 -122.836670 1.28 ... 7.0 automatic nc nc + 4 2019-01-10T11:25:44.854Z 65.108200 -149.370100 20.60 ... NaN automatic ak ak + 5 2019-01-10T11:25:23.786Z 69.151800 -144.497700 10.40 ... NaN reviewed ak ak + 6 2019-01-10T11:16:11.761Z 61.331800 -150.070800 20.10 ... NaN automatic ak ak + + [7 rows x 22 columns] diff --git a/sources/pyside2/doc/tutorials/expenses/expenses.rst b/sources/pyside2/doc/tutorials/expenses/expenses.rst new file mode 100644 index 000000000..c34d18669 --- /dev/null +++ b/sources/pyside2/doc/tutorials/expenses/expenses.rst @@ -0,0 +1,313 @@ +###################### +Expenses Tool Tutorial +###################### + +In this tutorial you will learn the following concepts: +* creating user interfaces programatically, +* layouts and widgets, +* overloading Qt classes, +* connecting signal and slots, +* interacting with QWidgets, +* and building your own application. + +The requirements: + * A simple window for the application + (`QMainWindow <https://doc.qt.io/qtforpython/PySide2/QtWidgets/QMainWindow.html>`_). + * A table to keep track of the expenses + (`QTableWidget <https://doc.qt.io/qtforpython/PySide2/QtWidgets/QTableWidget.html>`_). + * Two input fields to add expense information + (`QLineEdit <https://doc.qt.io/qtforpython/PySide2/QtWidgets/QLineEdit.html>`_). + * Buttons to add information to the table, plot data, clear table, and exit the application + (`QPushButton <https://doc.qt.io/qtforpython/PySide2/QtWidgets/QPushButton.html>`_). + * A verification step to avoid invalid data entry. + * A chart to visualize the expense data + (`QChart <https://doc.qt.io/qtforpython/PySide2/QtCharts/QtCharts.QChart.html>`_) that will + be embedded in a chart view + (`QChartView <https://doc.qt.io/qtforpython/PySide2/QtCharts/QtCharts.QChartView.html>`_). + +Empty window +------------ + +The base structure for a `QApplication` is located inside the `if __name__ == "__main__":` +code block. + + .. code:: + + if __name__ == "__main__": + app = QApplication([]) + # ... + sys.exit(app.exec_()) + +Now, to start the development, create an empty window called `MainWindow`. +You could do that by defining a class that inherits from `QMainWindow`. + + .. literalinclude:: steps/01-expenses.py + :linenos: + :lines: 45-59 + :emphasize-lines: 45-48 + +Now that our class is defined, create an instance of it and call `show()`. + + .. literalinclude:: steps/01-expenses.py + :linenos: + :lines: 45-59 + :emphasize-lines: 54-56 + +Menu bar +-------- + +Using a `QMainWindow` gives some features for free, among them a *menu bar*. To use it, you need +to call the method `menuBar()` and populate it inside the `MainWindow` class. + + .. literalinclude:: steps/02-expenses.py + :linenos: + :lines: 46-58 + :emphasize-lines: 51 + +Notice that the code snippet adds a *File* menu with the *Exit* option only. + +First signal/slot connection +---------------------------- + +The *Exit* option must be connected to a slot that triggers the application to exit. The main +idea to achieve this, is the following: + + .. code:: + + element.signal_name.connect(slot_name) + +All the interface's elements could be connected through signals to certain slots, +in the case of a `QAction`, the signal `triggered` can be used: + + .. code:: + + exit_action.triggered.connect(slot_name) + +.. note:: Now a *slot* needs to be defined to exit the application, which can be done using + `QApplication.quit()`. If we put all these concepts together you will end up with the + following code: + + .. literalinclude:: steps/03-expenses.py + :linenos: + :lines: 56-65 + :emphasize-lines: 59, 63-65 + +Notice that the decorator `@Slot()` is required for each slot you declare to properly +register them. Slots are normal functions, but the main difference is that they +will be invokable from `Signals` of QObjects when connected. + +Empty widget and data +--------------------- + +The `QMainWindow` enables us to set a central widget that will be displayed when showing the window +(`read more <https://doc.qt.io/qt-5/qmainwindow.html#details>`_). +This central widget could be another class derived from `QWidget`. + +Additionally, you will define example data to visualize later. + + .. literalinclude:: steps/04-expenses.py + :linenos: + :lines: 46-53 + +With the `Widget` class in place, modify `MainWindow`'s initialization code + + .. literalinclude:: steps/04-expenses.py + :linenos: + :lines: 80-84 + +Window layout +------------- + +Now that the main empty window is in place, you need to start adding widgets to achieve the main +goal of creating an expenses application. + +After declaring the example data, you can visualize it on a simple `QTableWidget`. To do so, you +will add this procedure to the `Widget` constructor. + + .. warning:: Only for the example purpose a QTableWidget will be used, + but for more performance-critical applications the combination + of a model and a QTableView is encouraged. + + .. literalinclude:: steps/05-expenses.py + :linenos: + :lines: 48-73 + +As you can see, the code also includes a `QHBoxLayout` that provides the container to place widgets +horizontally. + +Additionally, the `QTableWidget` allows for customizing it, like adding the labels for the two +columns that will be used, and to *stretch* the content to use the whole `Widget` space. + +The last line of code refers to *filling the table**, and the code to perform that task is +displayed below. + + .. literalinclude:: steps/05-expenses.py + :linenos: + :lines: 75-81 + +Having this process on a separate method is a good practice to leave the constructor more readable, +and to split the main functions of the class in independent processes. + + +Right side layout +----------------- + +Because the data that is being used is just an example, you are required to include a mechanism to +input items to the table, and extra buttons to clear the table's content, and also quit the +application. + +To distribute these input lines and buttons, you will use a `QVBoxLayout` that allows you to place +elements vertically inside a layout. + + .. literalinclude:: steps/06-expenses.py + :linenos: + :lines: 64-80 + +Leaving the table on the left side and these newly included widgets to the right side +will be just a matter to add a layout to our main `QHBoxLayout` as you saw in the previous +example: + + .. literalinclude:: steps/06-expenses.py + :linenos: + :lines: 42-47 + +The next step will be connecting those new buttons to slots. + + +Adding elements +--------------- + +Each `QPushButton` have a signal called *clicked*, that is emitted when you click on the button. +This will be more than enough for this example, but you can see other signals in the `official +documentation <https://doc.qt.io/qtforpython/PySide2/QtWidgets/QAbstractButton.html#signals>`_. + + .. literalinclude:: steps/07-expenses.py + :linenos: + :lines: 92-95 + +As you can see on the previous lines, we are connecting each *clicked* signal to different slots. +In this example slots are normal class methods in charge of perform a determined task associated +with our buttons. It is really important to decorate each method declaration with a `@Slot()`, in +that way PySide2 knows internally how to register them into Qt. + + .. literalinclude:: steps/07-expenses.py + :linenos: + :lines: 1000-129 + :emphasize-lines: 101,115,127 + +Since these slots are methods, we can access the class variables, like our `QTableWidget` to +interact with it. + +The mechanism to add elements into the table is described as the following: + + * get the *description* and *price* from the fields, + * insert a new empty row to the table, + * set the values for the empty row in each column, + * clear the input text fields, + * include the global count of table rows. + +To exit the application you can use the `quit()` method of the unique `QApplication` instance, and +to clear the content of the table you can just set the table *row count*, and the internal count to +zero. + +Verification step +----------------- + +Adding information to the table needs to be a critical action that require a verification step +to avoid adding invalid information, for example, empty information. + +You can use a signal from `QLineEdit` called *textChanged[str]* which will be emitted every +time something inside changes, i.e.: each key stroke. +Notice that this time, there is a *[str]* section on the signal, this means that the signal +will also emit the value of the text that was changed, which will be really useful to verify +the current content of the `QLineEdit`. + +You can connect two different object's signal to the same slot, and this will be the case +for your current application: + + .. literalinclude:: steps/08-expenses.py + :linenos: + :lines: 99-100 + +The content of the *check_disable* slot will be really simple: + + .. literalinclude:: steps/08-expenses.py + :linenos: + :lines: 119-124 + +You have two options, write a verification based on the current value +of the string you retrieve, or manually get the whole content of both +`QLineEdit`. The second is preferred in this case, so you can verify +if the two inputs are not empty to enable the button *Add*. + +.. note:: Qt also provides a special class called + `QValidator <https://doc.qt.io/qtforpython/PySide2/QtGui/QValidator.html?highlight=qvalidator>`_ + that you can use to validate any input. + +Empty chart view +---------------- + +New items can be added to the table, and the visualization is so far +OK, but you can accomplish more by representing the data graphically. + +First you will include an empty `QChartView` placeholder into the right +side of your application. + + .. literalinclude:: steps/09-expenses.py + :linenos: + :lines: 66-68 + +Additionally the order of how you include widgets to the right +`QVBoxLayout` will also change. + + .. literalinclude:: steps/09-expenses.py + :linenos: + :lines: 81-91 + :emphasize-lines: 89 + +Notice that before we had a line with `self.right.addStretch()` +to fill up the vertical space between the *Add* and the *Clear* buttons, +but now, with the `QChartView` it will not be necessary. + +Also, you need include a *Plot* button if you want to do it on-demand. + +Full application +---------------- + +For the final step, you will need to connect the *Plot* button +to a slot that creates a chart and includes it into your `QChartView`. + + .. literalinclude:: steps/10-expenses.py + :linenos: + :lines: 103-109 + :emphasize-lines: 106 + +That is nothing new, since you already did it for the other buttons, +but now take a look at how to create a chart and include it into +your `QChartView`. + + .. literalinclude:: steps/10-expenses.py + :linenos: + :lines: 139-151 + +The following steps show how to fill a `QPieSeries`: + + * create a `QPieSeries`, + * iterate over the table row IDs, + * get the items at the *i* position, + * add those values to the *series*. + +Once the series has been populated with our data, you create a new `QChart`, +add the series on it, and optionally set an alignment for the legend. + +The final line `self.chart_view.setChart(chart)` is in charge of bringing +your newly created chart to the `QChartView`. + +The application will look like this: + + .. image:: expenses_tool.png + +And now you can see the whole code: + + .. literalinclude:: main.py + :linenos: diff --git a/sources/pyside2/doc/tutorials/expenses/expenses_tool.png b/sources/pyside2/doc/tutorials/expenses/expenses_tool.png Binary files differnew file mode 100644 index 000000000..7a6f6d1f0 --- /dev/null +++ b/sources/pyside2/doc/tutorials/expenses/expenses_tool.png diff --git a/sources/pyside2/doc/tutorials/expenses/main.py b/sources/pyside2/doc/tutorials/expenses/main.py new file mode 100644 index 000000000..6cc911671 --- /dev/null +++ b/sources/pyside2/doc/tutorials/expenses/main.py @@ -0,0 +1,207 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +from PySide2.QtCore import Qt, Slot +from PySide2.QtGui import QPainter +from PySide2.QtWidgets import (QAction, QApplication, QHeaderView, QHBoxLayout, QLabel, QLineEdit, + QMainWindow, QPushButton, QTableWidget, QTableWidgetItem, + QVBoxLayout, QWidget) +from PySide2.QtCharts import QtCharts + + +class Widget(QWidget): + def __init__(self): + QWidget.__init__(self) + self.items = 0 + + # Example data + self._data = {"Water": 24.5, "Electricity": 55.1, "Rent": 850.0, + "Supermarket": 230.4, "Internet": 29.99, "Bars": 21.85, + "Public transportation": 60.0, "Coffee": 22.45, "Restaurants": 120} + + # Left + self.table = QTableWidget() + self.table.setColumnCount(2) + self.table.setHorizontalHeaderLabels(["Description", "Price"]) + self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) + + # Chart + self.chart_view = QtCharts.QChartView() + self.chart_view.setRenderHint(QPainter.Antialiasing) + + # Right + self.description = QLineEdit() + self.price = QLineEdit() + self.add = QPushButton("Add") + self.clear = QPushButton("Clear") + self.quit = QPushButton("Quit") + self.plot = QPushButton("Plot") + + # Disabling 'Add' button + self.add.setEnabled(False) + + self.right = QVBoxLayout() + self.right.setMargin(10) + self.right.addWidget(QLabel("Description")) + self.right.addWidget(self.description) + self.right.addWidget(QLabel("Price")) + self.right.addWidget(self.price) + self.right.addWidget(self.add) + self.right.addWidget(self.plot) + self.right.addWidget(self.chart_view) + self.right.addWidget(self.clear) + self.right.addWidget(self.quit) + + # QWidget Layout + self.layout = QHBoxLayout() + + #self.table_view.setSizePolicy(size) + self.layout.addWidget(self.table) + self.layout.addLayout(self.right) + + # Set the layout to the QWidget + self.setLayout(self.layout) + + # Signals and Slots + self.add.clicked.connect(self.add_element) + self.quit.clicked.connect(self.quit_application) + self.plot.clicked.connect(self.plot_data) + self.clear.clicked.connect(self.clear_table) + self.description.textChanged[str].connect(self.check_disable) + self.price.textChanged[str].connect(self.check_disable) + + # Fill example data + self.fill_table() + + @Slot() + def add_element(self): + des = self.description.text() + price = self.price.text() + + self.table.insertRow(self.items) + description_item = QTableWidgetItem(des) + price_item = QTableWidgetItem("{:.2f}".format(float(price))) + price_item.setTextAlignment(Qt.AlignRight) + + self.table.setItem(self.items, 0, description_item) + self.table.setItem(self.items, 1, price_item) + + self.description.setText("") + self.price.setText("") + + self.items += 1 + + @Slot() + def check_disable(self, s): + if not self.description.text() or not self.price.text(): + self.add.setEnabled(False) + else: + self.add.setEnabled(True) + + @Slot() + def plot_data(self): + # Get table information + series = QtCharts.QPieSeries() + for i in range(self.table.rowCount()): + text = self.table.item(i, 0).text() + number = float(self.table.item(i, 1).text()) + series.append(text, number) + + chart = QtCharts.QChart() + chart.addSeries(series) + chart.legend().setAlignment(Qt.AlignLeft) + self.chart_view.setChart(chart) + + @Slot() + def quit_application(self): + QApplication.quit() + + def fill_table(self, data=None): + data = self._data if not data else data + for desc, price in data.items(): + description_item = QTableWidgetItem(desc) + price_item = QTableWidgetItem("{:.2f}".format(price)) + price_item.setTextAlignment(Qt.AlignRight) + self.table.insertRow(self.items) + self.table.setItem(self.items, 0, description_item) + self.table.setItem(self.items, 1, price_item) + self.items += 1 + + @Slot() + def clear_table(self): + self.table.setRowCount(0) + self.items = 0 + + +class MainWindow(QMainWindow): + def __init__(self, widget): + QMainWindow.__init__(self) + self.setWindowTitle("Tutorial") + + # Menu + self.menu = self.menuBar() + self.file_menu = self.menu.addMenu("File") + + # Exit QAction + exit_action = QAction("Exit", self) + exit_action.setShortcut("Ctrl+Q") + exit_action.triggered.connect(self.exit_app) + + self.file_menu.addAction(exit_action) + self.setCentralWidget(widget) + + @Slot() + def exit_app(self, checked): + QApplication.quit() + + +if __name__ == "__main__": + # Qt Application + app = QApplication(sys.argv) + # QWidget + widget = Widget() + # QMainWindow using QWidget as central widget + window = MainWindow(widget) + window.resize(800, 600) + window.show() + + # Execute application + sys.exit(app.exec_()) diff --git a/sources/pyside2/doc/tutorials/expenses/steps/01-expenses.py b/sources/pyside2/doc/tutorials/expenses/steps/01-expenses.py new file mode 100644 index 000000000..12d5f0b1a --- /dev/null +++ b/sources/pyside2/doc/tutorials/expenses/steps/01-expenses.py @@ -0,0 +1,59 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +from PySide2.QtWidgets import QApplication, QMainWindow + + +class MainWindow(QMainWindow): + def __init__(self): + QMainWindow.__init__(self) + self.setWindowTitle("Tutorial") + +if __name__ == "__main__": + # Qt Application + app = QApplication(sys.argv) + + window = MainWindow() + window.resize(800, 600) + window.show() + + # Execute application + sys.exit(app.exec_()) diff --git a/sources/pyside2/doc/tutorials/expenses/steps/02-expenses.py b/sources/pyside2/doc/tutorials/expenses/steps/02-expenses.py new file mode 100644 index 000000000..0546bc9f3 --- /dev/null +++ b/sources/pyside2/doc/tutorials/expenses/steps/02-expenses.py @@ -0,0 +1,70 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +from PySide2.QtWidgets import QAction, QApplication, QMainWindow + + +class MainWindow(QMainWindow): + def __init__(self): + QMainWindow.__init__(self) + self.setWindowTitle("Tutorial") + + # Menu + self.menu = self.menuBar() + self.file_menu = self.menu.addMenu("File") + + # Exit QAction + exit_action = QAction("Exit", self) + exit_action.setShortcut("Ctrl+Q") + + self.file_menu.addAction(exit_action) + + +if __name__ == "__main__": + # Qt Application + app = QApplication(sys.argv) + + window = MainWindow() + window.resize(800, 600) + window.show() + + # Execute application + sys.exit(app.exec_()) diff --git a/sources/pyside2/doc/tutorials/expenses/steps/03-expenses.py b/sources/pyside2/doc/tutorials/expenses/steps/03-expenses.py new file mode 100644 index 000000000..bc753309f --- /dev/null +++ b/sources/pyside2/doc/tutorials/expenses/steps/03-expenses.py @@ -0,0 +1,77 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +from PySide2.QtCore import Slot +from PySide2.QtWidgets import QAction, QApplication, QMainWindow +from PySide2.QtCharts import QtCharts + + +class MainWindow(QMainWindow): + def __init__(self): + QMainWindow.__init__(self) + self.setWindowTitle("Tutorial") + + # Menu + self.menu = self.menuBar() + self.file_menu = self.menu.addMenu("File") + + # Exit QAction + exit_action = QAction("Exit", self) + exit_action.setShortcut("Ctrl+Q") + exit_action.triggered.connect(self.exit_app) + + self.file_menu.addAction(exit_action) + + @Slot() + def exit_app(self, checked): + QApplication.quit() + + +if __name__ == "__main__": + # Qt Application + app = QApplication(sys.argv) + + window = MainWindow() + window.resize(800, 600) + window.show() + + # Execute application + sys.exit(app.exec_()) diff --git a/sources/pyside2/doc/tutorials/expenses/steps/04-expenses.py b/sources/pyside2/doc/tutorials/expenses/steps/04-expenses.py new file mode 100644 index 000000000..78e9b1d1d --- /dev/null +++ b/sources/pyside2/doc/tutorials/expenses/steps/04-expenses.py @@ -0,0 +1,89 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +from PySide2.QtCore import Slot +from PySide2.QtWidgets import QAction, QApplication, QMainWindow, QWidget + + +class Widget(QWidget): + def __init__(self): + QWidget.__init__(self) + + # Example data + self._data = {"Water": 24.5, "Electricity": 55.1, "Rent": 850.0, + "Supermarket": 230.4, "Internet": 29.99, "Bars": 21.85, + "Public transportation": 60.0, "Coffee": 22.45, "Restaurants": 120} + + +class MainWindow(QMainWindow): + def __init__(self, widget): + QMainWindow.__init__(self) + self.setWindowTitle("Tutorial") + + # Menu + self.menu = self.menuBar() + self.file_menu = self.menu.addMenu("File") + + # Exit QAction + exit_action = QAction("Exit", self) + exit_action.setShortcut("Ctrl+Q") + exit_action.triggered.connect(self.exit_app) + + self.file_menu.addAction(exit_action) + self.setCentralWidget(widget) + + @Slot() + def exit_app(self, checked): + QApplication.quit() + + +if __name__ == "__main__": + # Qt Application + app = QApplication(sys.argv) + # QWidget + widget = Widget() + # QMainWindow using QWidget as central widget + window = MainWindow(widget) + window.resize(800, 600) + window.show() + + # Execute application + sys.exit(app.exec_()) diff --git a/sources/pyside2/doc/tutorials/expenses/steps/05-expenses.py b/sources/pyside2/doc/tutorials/expenses/steps/05-expenses.py new file mode 100644 index 000000000..6fd515f40 --- /dev/null +++ b/sources/pyside2/doc/tutorials/expenses/steps/05-expenses.py @@ -0,0 +1,117 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +from PySide2.QtCore import Slot +from PySide2.QtWidgets import (QAction, QApplication, QHeaderView, QHBoxLayout, QMainWindow, + QTableWidget, QTableWidgetItem, QWidget) + + +class Widget(QWidget): + def __init__(self): + QWidget.__init__(self) + self.items = 0 + + # Example data + self._data = {"Water": 24.5, "Electricity": 55.1, "Rent": 850.0, + "Supermarket": 230.4, "Internet": 29.99, "Bars": 21.85, + "Public transportation": 60.0, "Coffee": 22.45, "Restaurants": 120} + + # Left + self.table = QTableWidget() + self.table.setColumnCount(2) + self.table.setHorizontalHeaderLabels(["Description", "Price"]) + self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) + + # QWidget Layout + self.layout = QHBoxLayout() + + #self.table_view.setSizePolicy(size) + self.layout.addWidget(self.table) + + # Set the layout to the QWidget + self.setLayout(self.layout) + + # Fill example data + self.fill_table() + + def fill_table(self, data=None): + data = self._data if not data else data + for desc, price in data.items(): + self.table.insertRow(self.items) + self.table.setItem(self.items, 0, QTableWidgetItem(desc)) + self.table.setItem(self.items, 1, QTableWidgetItem(str(price))) + self.items += 1 + + +class MainWindow(QMainWindow): + def __init__(self, widget): + QMainWindow.__init__(self) + self.setWindowTitle("Tutorial") + + # Menu + self.menu = self.menuBar() + self.file_menu = self.menu.addMenu("File") + + # Exit QAction + exit_action = QAction("Exit", self) + exit_action.setShortcut("Ctrl+Q") + exit_action.triggered.connect(self.exit_app) + + self.file_menu.addAction(exit_action) + self.setCentralWidget(widget) + + @Slot() + def exit_app(self, checked): + QApplication.quit() + + +if __name__ == "__main__": + # Qt Application + app = QApplication(sys.argv) + # QWidget + widget = Widget() + # QMainWindow using QWidget as central widget + window = MainWindow(widget) + window.resize(800, 600) + window.show() + + # Execute application + sys.exit(app.exec_()) diff --git a/sources/pyside2/doc/tutorials/expenses/steps/06-expenses.py b/sources/pyside2/doc/tutorials/expenses/steps/06-expenses.py new file mode 100644 index 000000000..38fa881bf --- /dev/null +++ b/sources/pyside2/doc/tutorials/expenses/steps/06-expenses.py @@ -0,0 +1,137 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +from PySide2.QtCore import Slot +from PySide2.QtWidgets import (QAction, QApplication, QHeaderView, QHBoxLayout, QLabel, QLineEdit, + QMainWindow, QPushButton, QTableWidget, QTableWidgetItem, + QVBoxLayout, QWidget) + + +class Widget(QWidget): + def __init__(self): + QWidget.__init__(self) + self.items = 0 + + # Example data + self._data = {"Water": 24.5, "Electricity": 55.1, "Rent": 850.0, + "Supermarket": 230.4, "Internet": 29.99, "Bars": 21.85, + "Public transportation": 60.0, "Coffee": 22.45, "Restaurants": 120} + + # Left + self.table = QTableWidget() + self.table.setColumnCount(2) + self.table.setHorizontalHeaderLabels(["Description", "Price"]) + self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) + + # Right + self.description = QLineEdit() + self.price = QLineEdit() + self.add = QPushButton("Add") + self.clear = QPushButton("Clear") + self.quit = QPushButton("Quit") + + self.right = QVBoxLayout() + self.right.setMargin(10) + self.right.addWidget(QLabel("Description")) + self.right.addWidget(self.description) + self.right.addWidget(QLabel("Price")) + self.right.addWidget(self.price) + self.right.addWidget(self.add) + self.right.addStretch() + self.right.addWidget(self.clear) + self.right.addWidget(self.quit) + + # QWidget Layout + self.layout = QHBoxLayout() + + #self.table_view.setSizePolicy(size) + self.layout.addWidget(self.table) + self.layout.addLayout(self.right) + + # Set the layout to the QWidget + self.setLayout(self.layout) + + # Fill example data + self.fill_table() + + def fill_table(self, data=None): + data = self._data if not data else data + for desc, price in data.items(): + self.table.insertRow(self.items) + self.table.setItem(self.items, 0, QTableWidgetItem(desc)) + self.table.setItem(self.items, 1, QTableWidgetItem(str(price))) + self.items += 1 + + +class MainWindow(QMainWindow): + def __init__(self, widget): + QMainWindow.__init__(self) + self.setWindowTitle("Tutorial") + + # Menu + self.menu = self.menuBar() + self.file_menu = self.menu.addMenu("File") + + # Exit QAction + exit_action = QAction("Exit", self) + exit_action.setShortcut("Ctrl+Q") + exit_action.triggered.connect(self.exit_app) + + self.file_menu.addAction(exit_action) + self.setCentralWidget(widget) + + @Slot() + def exit_app(self, checked): + QApplication.quit() + + +if __name__ == "__main__": + # Qt Application + app = QApplication(sys.argv) + # QWidget + widget = Widget() + # QMainWindow using QWidget as central widget + window = MainWindow(widget) + window.resize(800, 600) + window.show() + + # Execute application + sys.exit(app.exec_()) diff --git a/sources/pyside2/doc/tutorials/expenses/steps/07-expenses.py b/sources/pyside2/doc/tutorials/expenses/steps/07-expenses.py new file mode 100644 index 000000000..6b915806d --- /dev/null +++ b/sources/pyside2/doc/tutorials/expenses/steps/07-expenses.py @@ -0,0 +1,164 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +from PySide2.QtCore import Slot +from PySide2.QtWidgets import (QAction, QApplication, QHeaderView, QHBoxLayout, QLabel, QLineEdit, + QMainWindow, QPushButton, QTableWidget, QTableWidgetItem, + QVBoxLayout, QWidget) + + +class Widget(QWidget): + def __init__(self): + QWidget.__init__(self) + self.items = 0 + + # Example data + self._data = {"Water": 24.5, "Electricity": 55.1, "Rent": 850.0, + "Supermarket": 230.4, "Internet": 29.99, "Bars": 21.85, + "Public transportation": 60.0, "Coffee": 22.45, "Restaurants": 120} + + # Left + self.table = QTableWidget() + self.table.setColumnCount(2) + self.table.setHorizontalHeaderLabels(["Description", "Price"]) + self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) + + # Right + self.description = QLineEdit() + self.price = QLineEdit() + self.add = QPushButton("Add") + self.clear = QPushButton("Clear") + self.quit = QPushButton("Quit") + + self.right = QVBoxLayout() + self.right.setMargin(10) + self.right.addWidget(QLabel("Description")) + self.right.addWidget(self.description) + self.right.addWidget(QLabel("Price")) + self.right.addWidget(self.price) + self.right.addWidget(self.add) + self.right.addStretch() + self.right.addWidget(self.quit) + + # QWidget Layout + self.layout = QHBoxLayout() + + #self.table_view.setSizePolicy(size) + self.layout.addWidget(self.table) + self.layout.addLayout(self.right) + + # Set the layout to the QWidget + self.setLayout(self.layout) + + # Signals and Slots + self.add.clicked.connect(self.add_element) + self.quit.clicked.connect(self.quit_application) + self.clear.clicked.connect(self.clear_table) + + # Fill example data + self.fill_table() + + @Slot() + def add_element(self): + des = self.description.text() + price = self.price.text() + + self.table.insertRow(self.items) + self.table.setItem(self.items, 0, QTableWidgetItem(des)) + self.table.setItem(self.items, 1, QTableWidgetItem(price)) + + self.description.setText("") + self.price.setText("") + + self.items += 1 + + @Slot() + def quit_application(self): + QApplication.quit() + + def fill_table(self, data=None): + data = self._data if not data else data + for desc, price in data.items(): + self.table.insertRow(self.items) + self.table.setItem(self.items, 0, QTableWidgetItem(desc)) + self.table.setItem(self.items, 1, QTableWidgetItem(str(price))) + self.items += 1 + + @Slot() + def clear_table(self): + self.table.setRowCount(0) + self.items = 0 + + +class MainWindow(QMainWindow): + def __init__(self, widget): + QMainWindow.__init__(self) + self.setWindowTitle("Tutorial") + + # Menu + self.menu = self.menuBar() + self.file_menu = self.menu.addMenu("File") + + # Exit QAction + exit_action = QAction("Exit", self) + exit_action.setShortcut("Ctrl+Q") + exit_action.triggered.connect(self.exit_app) + + self.file_menu.addAction(exit_action) + self.setCentralWidget(widget) + + @Slot() + def exit_app(self, checked): + QApplication.quit() + + +if __name__ == "__main__": + # Qt Application + app = QApplication(sys.argv) + # QWidget + widget = Widget() + # QMainWindow using QWidget as central widget + window = MainWindow(widget) + window.resize(800, 600) + window.show() + + # Execute application + sys.exit(app.exec_()) diff --git a/sources/pyside2/doc/tutorials/expenses/steps/08-expenses.py b/sources/pyside2/doc/tutorials/expenses/steps/08-expenses.py new file mode 100644 index 000000000..2f18dff9f --- /dev/null +++ b/sources/pyside2/doc/tutorials/expenses/steps/08-expenses.py @@ -0,0 +1,177 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +from PySide2.QtCore import Slot +from PySide2.QtWidgets import (QAction, QApplication, QHeaderView, QHBoxLayout, QLabel, QLineEdit, + QMainWindow, QPushButton, QTableWidget, QTableWidgetItem, + QVBoxLayout, QWidget) + + +class Widget(QWidget): + def __init__(self): + QWidget.__init__(self) + self.items = 0 + + # Example data + self._data = {"Water": 24.5, "Electricity": 55.1, "Rent": 850.0, + "Supermarket": 230.4, "Internet": 29.99, "Bars": 21.85, + "Public transportation": 60.0, "Coffee": 22.45, "Restaurants": 120} + + # Left + self.table = QTableWidget() + self.table.setColumnCount(2) + self.table.setHorizontalHeaderLabels(["Description", "Price"]) + self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) + + # Right + self.description = QLineEdit() + self.price = QLineEdit() + self.add = QPushButton("Add") + self.clear = QPushButton("Clear") + self.quit = QPushButton("Quit") + + # Disabling 'Add' button + self.add.setEnabled(False) + + self.right = QVBoxLayout() + self.right.setMargin(10) + self.right.addWidget(QLabel("Description")) + self.right.addWidget(self.description) + self.right.addWidget(QLabel("Price")) + self.right.addWidget(self.price) + self.right.addWidget(self.add) + self.right.addStretch() + self.right.addWidget(self.clear) + self.right.addWidget(self.quit) + + # QWidget Layout + self.layout = QHBoxLayout() + + #self.table_view.setSizePolicy(size) + self.layout.addWidget(self.table) + self.layout.addLayout(self.right) + + # Set the layout to the QWidget + self.setLayout(self.layout) + + # Signals and Slots + self.add.clicked.connect(self.add_element) + self.quit.clicked.connect(self.quit_application) + self.clear.clicked.connect(self.clear_table) + self.description.textChanged[str].connect(self.check_disable) + self.price.textChanged[str].connect(self.check_disable) + + # Fill example data + self.fill_table() + + @Slot() + def add_element(self): + des = self.description.text() + price = self.price.text() + + self.table.insertRow(self.items) + self.table.setItem(self.items, 0, QTableWidgetItem(des)) + self.table.setItem(self.items, 1, QTableWidgetItem(price)) + + self.description.setText("") + self.price.setText("") + + self.items += 1 + + @Slot() + def check_disable(self, s): + if not self.description.text() or not self.price.text(): + self.add.setEnabled(False) + else: + self.add.setEnabled(True) + + @Slot() + def quit_application(self): + QApplication.quit() + + def fill_table(self, data=None): + data = self._data if not data else data + for desc, price in data.items(): + self.table.insertRow(self.items) + self.table.setItem(self.items, 0, QTableWidgetItem(desc)) + self.table.setItem(self.items, 1, QTableWidgetItem(str(price))) + self.items += 1 + + @Slot() + def clear_table(self): + self.table.setRowCount(0) + self.items = 0 + + +class MainWindow(QMainWindow): + def __init__(self, widget): + QMainWindow.__init__(self) + self.setWindowTitle("Tutorial") + + # Menu + self.menu = self.menuBar() + self.file_menu = self.menu.addMenu("File") + + # Exit QAction + exit_action = QAction("Exit", self) + exit_action.setShortcut("Ctrl+Q") + exit_action.triggered.connect(self.exit_app) + + self.file_menu.addAction(exit_action) + self.setCentralWidget(widget) + + @Slot() + def exit_app(self, checked): + QApplication.quit() + + +if __name__ == "__main__": + # Qt Application + app = QApplication(sys.argv) + # QWidget + widget = Widget() + # QMainWindow using QWidget as central widget + window = MainWindow(widget) + window.resize(800, 600) + window.show() + + # Execute application + sys.exit(app.exec_()) diff --git a/sources/pyside2/doc/tutorials/expenses/steps/09-expenses.py b/sources/pyside2/doc/tutorials/expenses/steps/09-expenses.py new file mode 100644 index 000000000..6b5d87e2e --- /dev/null +++ b/sources/pyside2/doc/tutorials/expenses/steps/09-expenses.py @@ -0,0 +1,185 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +from PySide2.QtCore import Slot +from PySide2.QtGui import QPainter +from PySide2.QtWidgets import (QAction, QApplication, QHeaderView, QHBoxLayout, QLabel, QLineEdit, + QMainWindow, QPushButton, QTableWidget, QTableWidgetItem, + QVBoxLayout, QWidget) +from PySide2.QtCharts import QtCharts + + +class Widget(QWidget): + def __init__(self): + QWidget.__init__(self) + self.items = 0 + + # Example data + self._data = {"Water": 24.5, "Electricity": 55.1, "Rent": 850.0, + "Supermarket": 230.4, "Internet": 29.99, "Bars": 21.85, + "Public transportation": 60.0, "Coffee": 22.45, "Restaurants": 120} + + # Left + self.table = QTableWidget() + self.table.setColumnCount(2) + self.table.setHorizontalHeaderLabels(["Description", "Price"]) + self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) + + # Chart + self.chart_view = QtCharts.QChartView() + self.chart_view.setRenderHint(QPainter.Antialiasing) + + # Right + self.description = QLineEdit() + self.price = QLineEdit() + self.add = QPushButton("Add") + self.clear = QPushButton("Clear") + self.quit = QPushButton("Quit") + self.plot = QPushButton("Plot") + + # Disabling 'Add' button + self.add.setEnabled(False) + + self.right = QVBoxLayout() + self.right.setMargin(10) + self.right.addWidget(QLabel("Description")) + self.right.addWidget(self.description) + self.right.addWidget(QLabel("Price")) + self.right.addWidget(self.price) + self.right.addWidget(self.add) + self.right.addWidget(self.plot) + self.right.addWidget(self.chart_view) + self.right.addWidget(self.clear) + self.right.addWidget(self.quit) + + # QWidget Layout + self.layout = QHBoxLayout() + + #self.table_view.setSizePolicy(size) + self.layout.addWidget(self.table) + self.layout.addLayout(self.right) + + # Set the layout to the QWidget + self.setLayout(self.layout) + + # Signals and Slots + self.add.clicked.connect(self.add_element) + self.quit.clicked.connect(self.quit_application) + self.clear.clicked.connect(self.clear_table) + self.description.textChanged[str].connect(self.check_disable) + self.price.textChanged[str].connect(self.check_disable) + + # Fill example data + self.fill_table() + + @Slot() + def add_element(self): + des = self.description.text() + price = self.price.text() + + self.table.insertRow(self.items) + self.table.setItem(self.items, 0, QTableWidgetItem(des)) + self.table.setItem(self.items, 1, QTableWidgetItem(price)) + + self.description.setText("") + self.price.setText("") + + self.items += 1 + + @Slot() + def check_disable(self, s): + if not self.description.text() or not self.price.text(): + self.add.setEnabled(False) + else: + self.add.setEnabled(True) + + @Slot() + def quit_application(self): + QApplication.quit() + + def fill_table(self, data=None): + data = self._data if not data else data + for desc, price in data.items(): + self.table.insertRow(self.items) + self.table.setItem(self.items, 0, QTableWidgetItem(desc)) + self.table.setItem(self.items, 1, QTableWidgetItem(str(price))) + self.items += 1 + + @Slot() + def clear_table(self): + self.table.setRowCount(0) + self.items = 0 + + +class MainWindow(QMainWindow): + def __init__(self, widget): + QMainWindow.__init__(self) + self.setWindowTitle("Tutorial") + + # Menu + self.menu = self.menuBar() + self.file_menu = self.menu.addMenu("File") + + # Exit QAction + exit_action = QAction("Exit", self) + exit_action.setShortcut("Ctrl+Q") + exit_action.triggered.connect(self.exit_app) + + self.file_menu.addAction(exit_action) + self.setCentralWidget(widget) + + @Slot() + def exit_app(self, checked): + QApplication.quit() + + +if __name__ == "__main__": + # Qt Application + app = QApplication(sys.argv) + # QWidget + widget = Widget() + # QMainWindow using QWidget as central widget + window = MainWindow(widget) + window.resize(800, 600) + window.show() + + # Execute application + sys.exit(app.exec_()) diff --git a/sources/pyside2/doc/tutorials/expenses/steps/10-expenses.py b/sources/pyside2/doc/tutorials/expenses/steps/10-expenses.py new file mode 100644 index 000000000..6cc911671 --- /dev/null +++ b/sources/pyside2/doc/tutorials/expenses/steps/10-expenses.py @@ -0,0 +1,207 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +from PySide2.QtCore import Qt, Slot +from PySide2.QtGui import QPainter +from PySide2.QtWidgets import (QAction, QApplication, QHeaderView, QHBoxLayout, QLabel, QLineEdit, + QMainWindow, QPushButton, QTableWidget, QTableWidgetItem, + QVBoxLayout, QWidget) +from PySide2.QtCharts import QtCharts + + +class Widget(QWidget): + def __init__(self): + QWidget.__init__(self) + self.items = 0 + + # Example data + self._data = {"Water": 24.5, "Electricity": 55.1, "Rent": 850.0, + "Supermarket": 230.4, "Internet": 29.99, "Bars": 21.85, + "Public transportation": 60.0, "Coffee": 22.45, "Restaurants": 120} + + # Left + self.table = QTableWidget() + self.table.setColumnCount(2) + self.table.setHorizontalHeaderLabels(["Description", "Price"]) + self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) + + # Chart + self.chart_view = QtCharts.QChartView() + self.chart_view.setRenderHint(QPainter.Antialiasing) + + # Right + self.description = QLineEdit() + self.price = QLineEdit() + self.add = QPushButton("Add") + self.clear = QPushButton("Clear") + self.quit = QPushButton("Quit") + self.plot = QPushButton("Plot") + + # Disabling 'Add' button + self.add.setEnabled(False) + + self.right = QVBoxLayout() + self.right.setMargin(10) + self.right.addWidget(QLabel("Description")) + self.right.addWidget(self.description) + self.right.addWidget(QLabel("Price")) + self.right.addWidget(self.price) + self.right.addWidget(self.add) + self.right.addWidget(self.plot) + self.right.addWidget(self.chart_view) + self.right.addWidget(self.clear) + self.right.addWidget(self.quit) + + # QWidget Layout + self.layout = QHBoxLayout() + + #self.table_view.setSizePolicy(size) + self.layout.addWidget(self.table) + self.layout.addLayout(self.right) + + # Set the layout to the QWidget + self.setLayout(self.layout) + + # Signals and Slots + self.add.clicked.connect(self.add_element) + self.quit.clicked.connect(self.quit_application) + self.plot.clicked.connect(self.plot_data) + self.clear.clicked.connect(self.clear_table) + self.description.textChanged[str].connect(self.check_disable) + self.price.textChanged[str].connect(self.check_disable) + + # Fill example data + self.fill_table() + + @Slot() + def add_element(self): + des = self.description.text() + price = self.price.text() + + self.table.insertRow(self.items) + description_item = QTableWidgetItem(des) + price_item = QTableWidgetItem("{:.2f}".format(float(price))) + price_item.setTextAlignment(Qt.AlignRight) + + self.table.setItem(self.items, 0, description_item) + self.table.setItem(self.items, 1, price_item) + + self.description.setText("") + self.price.setText("") + + self.items += 1 + + @Slot() + def check_disable(self, s): + if not self.description.text() or not self.price.text(): + self.add.setEnabled(False) + else: + self.add.setEnabled(True) + + @Slot() + def plot_data(self): + # Get table information + series = QtCharts.QPieSeries() + for i in range(self.table.rowCount()): + text = self.table.item(i, 0).text() + number = float(self.table.item(i, 1).text()) + series.append(text, number) + + chart = QtCharts.QChart() + chart.addSeries(series) + chart.legend().setAlignment(Qt.AlignLeft) + self.chart_view.setChart(chart) + + @Slot() + def quit_application(self): + QApplication.quit() + + def fill_table(self, data=None): + data = self._data if not data else data + for desc, price in data.items(): + description_item = QTableWidgetItem(desc) + price_item = QTableWidgetItem("{:.2f}".format(price)) + price_item.setTextAlignment(Qt.AlignRight) + self.table.insertRow(self.items) + self.table.setItem(self.items, 0, description_item) + self.table.setItem(self.items, 1, price_item) + self.items += 1 + + @Slot() + def clear_table(self): + self.table.setRowCount(0) + self.items = 0 + + +class MainWindow(QMainWindow): + def __init__(self, widget): + QMainWindow.__init__(self) + self.setWindowTitle("Tutorial") + + # Menu + self.menu = self.menuBar() + self.file_menu = self.menu.addMenu("File") + + # Exit QAction + exit_action = QAction("Exit", self) + exit_action.setShortcut("Ctrl+Q") + exit_action.triggered.connect(self.exit_app) + + self.file_menu.addAction(exit_action) + self.setCentralWidget(widget) + + @Slot() + def exit_app(self, checked): + QApplication.quit() + + +if __name__ == "__main__": + # Qt Application + app = QApplication(sys.argv) + # QWidget + widget = Widget() + # QMainWindow using QWidget as central widget + window = MainWindow(widget) + window.resize(800, 600) + window.show() + + # Execute application + sys.exit(app.exec_()) diff --git a/sources/pyside2/doc/tutorials/index.rst b/sources/pyside2/doc/tutorials/index.rst index e394c4d24..5a97aecb9 100644 --- a/sources/pyside2/doc/tutorials/index.rst +++ b/sources/pyside2/doc/tutorials/index.rst @@ -26,7 +26,7 @@ Tutorials basictutorial/clickablebutton.rst basictutorial/dialog.rst basictutorial/uifiles.rst - qmltutorial/index.rst - qmladvancedtutorial/index.rst datavisualize/index.rst + expenses/expenses.rst qmlapp/qmlapplication.rst + qmlintegration/qmlintegration.rst diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/declarative-adv-tutorial1.png b/sources/pyside2/doc/tutorials/qmladvancedtutorial/declarative-adv-tutorial1.png Binary files differdeleted file mode 100644 index 1699ab0e4..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/declarative-adv-tutorial1.png +++ /dev/null diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/declarative-adv-tutorial2.png b/sources/pyside2/doc/tutorials/qmladvancedtutorial/declarative-adv-tutorial2.png Binary files differdeleted file mode 100644 index ba27c442c..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/declarative-adv-tutorial2.png +++ /dev/null diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/declarative-adv-tutorial3.png b/sources/pyside2/doc/tutorials/qmladvancedtutorial/declarative-adv-tutorial3.png Binary files differdeleted file mode 100644 index d500434d1..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/declarative-adv-tutorial3.png +++ /dev/null diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/declarative-adv-tutorial4.gif b/sources/pyside2/doc/tutorials/qmladvancedtutorial/declarative-adv-tutorial4.gif Binary files differdeleted file mode 100644 index 827458daa..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/declarative-adv-tutorial4.gif +++ /dev/null diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/declarative-samegame.png b/sources/pyside2/doc/tutorials/qmladvancedtutorial/declarative-samegame.png Binary files differdeleted file mode 100644 index 2232df204..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/declarative-samegame.png +++ /dev/null diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/index.rst b/sources/pyside2/doc/tutorials/qmladvancedtutorial/index.rst deleted file mode 100644 index d40af59d7..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/index.rst +++ /dev/null @@ -1,35 +0,0 @@ -.. _qmladvancedtutorial: - -QML Advanced Tutorial -********************* - -This tutorial walks you through the steps of creating an application using QML. -It assumes that you already know the basics of QML (for example, from reading the -:ref:`qmltutorial`. - -In this tutorial, you will develop the game, *Same Game*. It is based on the -Same Game application included in the declarative demos directory, and looks -like this: - -.. figure:: declarative-samegame.png - :align: center - -The tutorial covers concepts related to producing a fully functional application, -including JavaScript integration, using QML states and behaviors to manage -components and enhance your interface, and storing persistent application data. - -Prior knowledge of JavaScript is useful to understand parts of this -tutorial, but if you don't know it, you can still get a feel of -integrating the backend logic that creates and controls QML items. - -Tutorial chapters: - -.. toctree:: - :maxdepth: 1 - - samegame1.rst - samegame2.rst - samegame3.rst - samegame4.rst - -All the code in this tutorial can be found :download:`here <samegame.tar.bz2>`. diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame.tar.bz2 b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame.tar.bz2 Binary files differdeleted file mode 100644 index f33983d0a..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame.tar.bz2 +++ /dev/null diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame1/Block.qml b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame1/Block.qml deleted file mode 100644 index 18d0c2e9e..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame1/Block.qml +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of Qt for Python. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//![0] -import QtQuick 2.0 - -Item { - id: block - - Image { - id: img - anchors.fill: parent - source: "../shared/pics/redStone.png" - } -} -//![0] diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame1/Button.qml b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame1/Button.qml deleted file mode 100644 index 0c07904ab..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame1/Button.qml +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of Qt for Python. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//![0] -import QtQuick 2.0 - -Rectangle { - id: container - - property string text: "Button" - - signal clicked - - width: buttonLabel.width + 20; height: buttonLabel.height + 5 - border { width: 1; color: Qt.darker(activePalette.button) } - smooth: true - radius: 8 - - // color the button with a gradient - gradient: Gradient { - GradientStop { - position: 0.0 - color: { - if (mouseArea.pressed) - return activePalette.dark - else - return activePalette.light - } - } - GradientStop { position: 1.0; color: activePalette.button } - } - - MouseArea { - id: mouseArea - anchors.fill: parent - onClicked: container.clicked(); - } - - Text { - id: buttonLabel - anchors.centerIn: container - color: activePalette.buttonText - text: container.text - } -} -//![0] diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame1/samegame.qml b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame1/samegame.qml deleted file mode 100644 index 36b087d40..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame1/samegame.qml +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of Qt for Python. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//![0] -import QtQuick 2.0 - -Rectangle { - id: screen - - width: 490; height: 720 - - SystemPalette { id: activePalette } - - Item { - width: parent.width - anchors { top: parent.top; bottom: toolBar.top } - - Image { - id: background - anchors.fill: parent - source: "../shared/pics/background.jpg" - fillMode: Image.PreserveAspectCrop - } - } - - Rectangle { - id: toolBar - width: parent.width; height: 30 - color: activePalette.window - anchors.bottom: screen.bottom - - Button { - anchors { left: parent.left; verticalCenter: parent.verticalCenter } - text: "New Game" - onClicked: console.log("This doesn't do anything yet...") - } - - Text { - id: score - anchors { right: parent.right; verticalCenter: parent.verticalCenter } - text: "Score: Who knows?" - } - } -} -//![0] diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame1/samegame1.qmlproject b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame1/samegame1.qmlproject deleted file mode 100644 index d4909f868..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame1/samegame1.qmlproject +++ /dev/null @@ -1,16 +0,0 @@ -import QmlProject 1.0 - -Project { - /* Include .qml, .js, and image files from current directory and subdirectories */ - QmlFiles { - directory: "." - } - JavaScriptFiles { - directory: "." - } - ImageFiles { - directory: "." - } - /* List of plugin directories passed to QML runtime */ - // importPaths: [ " ../exampleplugin " ] -} diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame2/Block.qml b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame2/Block.qml deleted file mode 100644 index fbbf6a983..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame2/Block.qml +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of Qt for Python. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -Item { - id: block - - Image { - id: img - anchors.fill: parent - source: "../shared/pics/redStone.png" - } -} diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame2/Button.qml b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame2/Button.qml deleted file mode 100644 index ffdd2d46e..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame2/Button.qml +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of Qt for Python. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -Rectangle { - id: container - - property string text: "Button" - - signal clicked - - width: buttonLabel.width + 20; height: buttonLabel.height + 5 - border { width: 1; color: Qt.darker(activePalette.button) } - smooth: true - radius: 8 - - // color the button with a gradient - gradient: Gradient { - GradientStop { - position: 0.0 - color: { - if (mouseArea.pressed) - return activePalette.dark - else - return activePalette.light - } - } - GradientStop { position: 1.0; color: activePalette.button } - } - - MouseArea { - id: mouseArea - anchors.fill: parent - onClicked: container.clicked(); - } - - Text { - id: buttonLabel - anchors.centerIn: container - color: activePalette.buttonText - text: container.text - } -} diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame2/samegame.js b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame2/samegame.js deleted file mode 100644 index c749dc17b..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame2/samegame.js +++ /dev/null @@ -1,63 +0,0 @@ -//![0] -var blockSize = 40; -var maxColumn = 10; -var maxRow = 15; -var maxIndex = maxColumn * maxRow; -var board = new Array(maxIndex); -var component; - -//Index function used instead of a 2D array -function index(column, row) { - return column + (row * maxColumn); -} - -function startNewGame() { - //Delete blocks from previous game - for (var i = 0; i < maxIndex; i++) { - if (board[i] != null) - board[i].destroy(); - } - - //Calculate board size - maxColumn = Math.floor(background.width / blockSize); - maxRow = Math.floor(background.height / blockSize); - maxIndex = maxRow * maxColumn; - - //Initialize Board - board = new Array(maxIndex); - for (var column = 0; column < maxColumn; column++) { - for (var row = 0; row < maxRow; row++) { - board[index(column, row)] = null; - createBlock(column, row); - } - } -} - -function createBlock(column, row) { - if (component == null) - component = Qt.createComponent("Block.qml"); - - // Note that if Block.qml was not a local file, component.status would be - // Loading and we should wait for the component's statusChanged() signal to - // know when the file is downloaded and ready before calling createObject(). - if (component.status == Component.Ready) { - var dynamicObject = component.createObject(background); - if (dynamicObject == null) { - console.log("error creating block"); - console.log(component.errorString()); - return false; - } - dynamicObject.x = column * blockSize; - dynamicObject.y = row * blockSize; - dynamicObject.width = blockSize; - dynamicObject.height = blockSize; - board[index(column, row)] = dynamicObject; - } else { - console.log("error loading block component"); - console.log(component.errorString()); - return false; - } - return true; -} -//![0] - diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame2/samegame.qml b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame2/samegame.qml deleted file mode 100644 index 6ed5bca1b..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame2/samegame.qml +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of Qt for Python. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 -//![2] -import "samegame.js" as SameGame -//![2] - -Rectangle { - id: screen - - width: 490; height: 720 - - SystemPalette { id: activePalette } - - Item { - width: parent.width - anchors { top: parent.top; bottom: toolBar.top } - - Image { - id: background - anchors.fill: parent - source: "../shared/pics/background.jpg" - fillMode: Image.PreserveAspectCrop - } - } - - Rectangle { - id: toolBar - width: parent.width; height: 32 - color: activePalette.window - anchors.bottom: screen.bottom - -//![1] - Button { - anchors { left: parent.left; verticalCenter: parent.verticalCenter } - text: "New Game" - onClicked: SameGame.startNewGame() - } -//![1] - - Text { - id: score - anchors { right: parent.right; verticalCenter: parent.verticalCenter } - text: "Score: Who knows?" - } - } -} diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame2/samegame2.qmlproject b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame2/samegame2.qmlproject deleted file mode 100644 index d4909f868..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame2/samegame2.qmlproject +++ /dev/null @@ -1,16 +0,0 @@ -import QmlProject 1.0 - -Project { - /* Include .qml, .js, and image files from current directory and subdirectories */ - QmlFiles { - directory: "." - } - JavaScriptFiles { - directory: "." - } - ImageFiles { - directory: "." - } - /* List of plugin directories passed to QML runtime */ - // importPaths: [ " ../exampleplugin " ] -} diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame3/Block.qml b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame3/Block.qml deleted file mode 100644 index 33a58688c..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame3/Block.qml +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of Qt for Python. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//![0] -import QtQuick 2.0 - -Item { - id: block - - property int type: 0 - - Image { - id: img - - anchors.fill: parent - source: { - if (type == 0) - return "../shared/pics/redStone.png"; - else if (type == 1) - return "../shared/pics/blueStone.png"; - else - return "../shared/pics/greenStone.png"; - } - } -} -//![0] diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame3/Button.qml b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame3/Button.qml deleted file mode 100644 index ffdd2d46e..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame3/Button.qml +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of Qt for Python. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -Rectangle { - id: container - - property string text: "Button" - - signal clicked - - width: buttonLabel.width + 20; height: buttonLabel.height + 5 - border { width: 1; color: Qt.darker(activePalette.button) } - smooth: true - radius: 8 - - // color the button with a gradient - gradient: Gradient { - GradientStop { - position: 0.0 - color: { - if (mouseArea.pressed) - return activePalette.dark - else - return activePalette.light - } - } - GradientStop { position: 1.0; color: activePalette.button } - } - - MouseArea { - id: mouseArea - anchors.fill: parent - onClicked: container.clicked(); - } - - Text { - id: buttonLabel - anchors.centerIn: container - color: activePalette.buttonText - text: container.text - } -} diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame3/Dialog.qml b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame3/Dialog.qml deleted file mode 100644 index bb4c362cd..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame3/Dialog.qml +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of Qt for Python. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//![0] -import QtQuick 2.0 - -Rectangle { - id: container - - function show(text) { - dialogText.text = text; - container.opacity = 1; - } - - function hide() { - container.opacity = 0; - } - - width: dialogText.width + 20 - height: dialogText.height + 20 - opacity: 0 - - Text { - id: dialogText - anchors.centerIn: parent - text: "" - } - - MouseArea { - anchors.fill: parent - onClicked: hide(); - } -} -//![0] diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame3/samegame.js b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame3/samegame.js deleted file mode 100644 index df5bdfb04..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame3/samegame.js +++ /dev/null @@ -1,174 +0,0 @@ -/* This script file handles the game logic */ -var maxColumn = 10; -var maxRow = 15; -var maxIndex = maxColumn * maxRow; -var board = new Array(maxIndex); -var component; - -//Index function used instead of a 2D array -function index(column, row) { - return column + (row * maxColumn); -} - -function startNewGame() { - //Calculate board size - maxColumn = Math.floor(gameCanvas.width / gameCanvas.blockSize); - maxRow = Math.floor(gameCanvas.height / gameCanvas.blockSize); - maxIndex = maxRow * maxColumn; - - //Close dialogs - dialog.hide(); - - //Initialize Board - board = new Array(maxIndex); - gameCanvas.score = 0; - for (var column = 0; column < maxColumn; column++) { - for (var row = 0; row < maxRow; row++) { - board[index(column, row)] = null; - createBlock(column, row); - } - } -} - -function createBlock(column, row) { - if (component == null) - component = Qt.createComponent("Block.qml"); - - // Note that if Block.qml was not a local file, component.status would be - // Loading and we should wait for the component's statusChanged() signal to - // know when the file is downloaded and ready before calling createObject(). - if (component.status == Component.Ready) { - var dynamicObject = component.createObject(gameCanvas); - if (dynamicObject == null) { - console.log("error creating block"); - console.log(component.errorString()); - return false; - } - dynamicObject.type = Math.floor(Math.random() * 3); - dynamicObject.x = column * gameCanvas.blockSize; - dynamicObject.y = row * gameCanvas.blockSize; - dynamicObject.width = gameCanvas.blockSize; - dynamicObject.height = gameCanvas.blockSize; - board[index(column, row)] = dynamicObject; - } else { - console.log("error loading block component"); - console.log(component.errorString()); - return false; - } - return true; -} - -var fillFound; //Set after a floodFill call to the number of blocks found -var floodBoard; //Set to 1 if the floodFill reaches off that node - -//![1] -function handleClick(xPos, yPos) { - var column = Math.floor(xPos / gameCanvas.blockSize); - var row = Math.floor(yPos / gameCanvas.blockSize); - if (column >= maxColumn || column < 0 || row >= maxRow || row < 0) - return; - if (board[index(column, row)] == null) - return; - //If it's a valid block, remove it and all connected (does nothing if it's not connected) - floodFill(column, row, -1); - if (fillFound <= 0) - return; - gameCanvas.score += (fillFound - 1) * (fillFound - 1); - shuffleDown(); - victoryCheck(); -} -//![1] - -function floodFill(column, row, type) { - if (board[index(column, row)] == null) - return; - var first = false; - if (type == -1) { - first = true; - type = board[index(column, row)].type; - - //Flood fill initialization - fillFound = 0; - floodBoard = new Array(maxIndex); - } - if (column >= maxColumn || column < 0 || row >= maxRow || row < 0) - return; - if (floodBoard[index(column, row)] == 1 || (!first && type != board[index(column, row)].type)) - return; - floodBoard[index(column, row)] = 1; - floodFill(column + 1, row, type); - floodFill(column - 1, row, type); - floodFill(column, row + 1, type); - floodFill(column, row - 1, type); - if (first == true && fillFound == 0) - return; //Can't remove single blocks - board[index(column, row)].opacity = 0; - board[index(column, row)] = null; - fillFound += 1; -} - -function shuffleDown() { - //Fall down - for (var column = 0; column < maxColumn; column++) { - var fallDist = 0; - for (var row = maxRow - 1; row >= 0; row--) { - if (board[index(column, row)] == null) { - fallDist += 1; - } else { - if (fallDist > 0) { - var obj = board[index(column, row)]; - obj.y += fallDist * gameCanvas.blockSize; - board[index(column, row + fallDist)] = obj; - board[index(column, row)] = null; - } - } - } - } - //Fall to the left - var fallDist = 0; - for (var column = 0; column < maxColumn; column++) { - if (board[index(column, maxRow - 1)] == null) { - fallDist += 1; - } else { - if (fallDist > 0) { - for (var row = 0; row < maxRow; row++) { - var obj = board[index(column, row)]; - if (obj == null) - continue; - obj.x -= fallDist * gameCanvas.blockSize; - board[index(column - fallDist, row)] = obj; - board[index(column, row)] = null; - } - } - } - } -} - -//![2] -function victoryCheck() { - //Award bonus points if no blocks left - var deservesBonus = true; - for (var column = maxColumn - 1; column >= 0; column--) - if (board[index(column, maxRow - 1)] != null) - deservesBonus = false; - if (deservesBonus) - gameCanvas.score += 500; - - //Check whether game has finished - if (deservesBonus || !(floodMoveCheck(0, maxRow - 1, -1))) - dialog.show("Game Over. Your score is " + gameCanvas.score); -} -//![2] - -//only floods up and right, to see if it can find adjacent same-typed blocks -function floodMoveCheck(column, row, type) { - if (column >= maxColumn || column < 0 || row >= maxRow || row < 0) - return false; - if (board[index(column, row)] == null) - return false; - var myType = board[index(column, row)].type; - if (type == myType) - return true; - return floodMoveCheck(column + 1, row, myType) || floodMoveCheck(column, row - 1, board[index(column, row)].type); -} - diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame3/samegame.qml b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame3/samegame.qml deleted file mode 100644 index 18a938302..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame3/samegame.qml +++ /dev/null @@ -1,119 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of Qt for Python. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//![0] -import QtQuick 2.0 -import "samegame.js" as SameGame - -Rectangle { - id: screen - - width: 490; height: 720 - - SystemPalette { id: activePalette } - - Item { - width: parent.width - anchors { top: parent.top; bottom: toolBar.top } - - Image { - id: background - anchors.fill: parent - source: "../shared/pics/background.jpg" - fillMode: Image.PreserveAspectCrop - } - -//![1] - Item { - id: gameCanvas - - property int score: 0 - property int blockSize: 40 - - width: parent.width - (parent.width % blockSize) - height: parent.height - (parent.height % blockSize) - anchors.centerIn: parent - - MouseArea { - anchors.fill: parent - onClicked: SameGame.handleClick(mouse.x, mouse.y) - } - } -//![1] - } - -//![2] - Dialog { - id: dialog - anchors.centerIn: parent - z: 100 - } -//![2] - - Rectangle { - id: toolBar - width: parent.width; height: 30 - color: activePalette.window - anchors.bottom: screen.bottom - - Button { - anchors { left: parent.left; verticalCenter: parent.verticalCenter } - text: "New Game" - onClicked: SameGame.startNewGame() - } - - Text { - id: score - anchors { right: parent.right; verticalCenter: parent.verticalCenter } - text: "Score: Who knows?" - } - } -} -//![0] diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame3/samegame3.qmlproject b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame3/samegame3.qmlproject deleted file mode 100644 index d4909f868..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame3/samegame3.qmlproject +++ /dev/null @@ -1,16 +0,0 @@ -import QmlProject 1.0 - -Project { - /* Include .qml, .js, and image files from current directory and subdirectories */ - QmlFiles { - directory: "." - } - JavaScriptFiles { - directory: "." - } - ImageFiles { - directory: "." - } - /* List of plugin directories passed to QML runtime */ - // importPaths: [ " ../exampleplugin " ] -} diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/content/BoomBlock.qml b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/content/BoomBlock.qml deleted file mode 100644 index d400fa402..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/content/BoomBlock.qml +++ /dev/null @@ -1,132 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of Qt for Python. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 -import Qt.labs.particles 1.0 - -Item { - id: block - - property int type: 0 - property bool dying: false - - //![1] - property bool spawned: false - - Behavior on x { - enabled: spawned; - SpringAnimation{ spring: 2; damping: 0.2 } - } - Behavior on y { - SpringAnimation{ spring: 2; damping: 0.2 } - } - //![1] - - //![2] - Image { - id: img - - anchors.fill: parent - source: { - if (type == 0) - return "../../shared/pics/redStone.png"; - else if (type == 1) - return "../../shared/pics/blueStone.png"; - else - return "../../shared/pics/greenStone.png"; - } - opacity: 0 - - Behavior on opacity { - NumberAnimation { properties:"opacity"; duration: 200 } - } - } - //![2] - - //![3] - Particles { - id: particles - - width: 1; height: 1 - anchors.centerIn: parent - - emissionRate: 0 - lifeSpan: 700; lifeSpanDeviation: 600 - angle: 0; angleDeviation: 360; - velocity: 100; velocityDeviation: 30 - source: { - if (type == 0) - return "../../shared/pics/redStar.png"; - else if (type == 1) - return "../../shared/pics/blueStar.png"; - else - return "../../shared/pics/greenStar.png"; - } - } - //![3] - - //![4] - states: [ - State { - name: "AliveState" - when: spawned == true && dying == false - PropertyChanges { target: img; opacity: 1 } - }, - - State { - name: "DeathState" - when: dying == true - StateChangeScript { script: particles.burst(50); } - PropertyChanges { target: img; opacity: 0 } - StateChangeScript { script: block.destroy(1000); } - } - ] - //![4] -} diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/content/Button.qml b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/content/Button.qml deleted file mode 100644 index ffdd2d46e..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/content/Button.qml +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of Qt for Python. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -Rectangle { - id: container - - property string text: "Button" - - signal clicked - - width: buttonLabel.width + 20; height: buttonLabel.height + 5 - border { width: 1; color: Qt.darker(activePalette.button) } - smooth: true - radius: 8 - - // color the button with a gradient - gradient: Gradient { - GradientStop { - position: 0.0 - color: { - if (mouseArea.pressed) - return activePalette.dark - else - return activePalette.light - } - } - GradientStop { position: 1.0; color: activePalette.button } - } - - MouseArea { - id: mouseArea - anchors.fill: parent - onClicked: container.clicked(); - } - - Text { - id: buttonLabel - anchors.centerIn: container - color: activePalette.buttonText - text: container.text - } -} diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/content/Dialog.qml b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/content/Dialog.qml deleted file mode 100644 index 0cdb04f7d..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/content/Dialog.qml +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of Qt for Python. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -//![0] -Rectangle { - id: container -//![0] - -//![1] - property string inputText: textInput.text - signal closed - - function show(text) { - dialogText.text = text; - container.opacity = 1; - textInput.opacity = 0; - } - - function showWithInput(text) { - show(text); - textInput.opacity = 1; - textInput.focus = true; - textInput.text = "" - } - - function hide() { - textInput.focus = false; - container.opacity = 0; - container.closed(); - } -//![1] - - width: dialogText.width + textInput.width + 20 - height: dialogText.height + 20 - opacity: 0 - visible: opacity > 0 - - Text { - id: dialogText - anchors { verticalCenter: parent.verticalCenter; left: parent.left; leftMargin: 10 } - text: "" - } - -//![2] - TextInput { - id: textInput - anchors { verticalCenter: parent.verticalCenter; left: dialogText.right } - width: 80 - text: "" - - onAccepted: container.hide() // close dialog when Enter is pressed - } -//![2] - - MouseArea { - anchors.fill: parent - - onClicked: { - if (textInput.text == "" && textInput.opacity > 0) - textInput.openSoftwareInputPanel(); - else - hide(); - } - } - -//![3] -} -//![3] diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/content/samegame.js b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/content/samegame.js deleted file mode 100755 index 79ff0c19b..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/content/samegame.js +++ /dev/null @@ -1,225 +0,0 @@ -/* This script file handles the game logic */ -var maxColumn = 10; -var maxRow = 15; -var maxIndex = maxColumn * maxRow; -var board = new Array(maxIndex); -var component; -var scoresURL = ""; -var gameDuration; - -//Index function used instead of a 2D array -function index(column, row) { - return column + (row * maxColumn); -} - -function startNewGame() { - //Delete blocks from previous game - for (var i = 0; i < maxIndex; i++) { - if (board[i] != null) - board[i].destroy(); - } - - //Calculate board size - maxColumn = Math.floor(gameCanvas.width / gameCanvas.blockSize); - maxRow = Math.floor(gameCanvas.height / gameCanvas.blockSize); - maxIndex = maxRow * maxColumn; - - //Close dialogs - nameInputDialog.hide(); - dialog.hide(); - - //Initialize Board - board = new Array(maxIndex); - gameCanvas.score = 0; - for (var column = 0; column < maxColumn; column++) { - for (var row = 0; row < maxRow; row++) { - board[index(column, row)] = null; - createBlock(column, row); - } - } - - gameDuration = new Date(); -} - -function createBlock(column, row) { - if (component == null) - component = Qt.createComponent("content/BoomBlock.qml"); - - // Note that if Block.qml was not a local file, component.status would be - // Loading and we should wait for the component's statusChanged() signal to - // know when the file is downloaded and ready before calling createObject(). - if (component.status == Component.Ready) { - var dynamicObject = component.createObject(gameCanvas); - if (dynamicObject == null) { - console.log("error creating block"); - console.log(component.errorString()); - return false; - } - dynamicObject.type = Math.floor(Math.random() * 3); - dynamicObject.x = column * gameCanvas.blockSize; - dynamicObject.y = row * gameCanvas.blockSize; - dynamicObject.width = gameCanvas.blockSize; - dynamicObject.height = gameCanvas.blockSize; - dynamicObject.spawned = true; - board[index(column, row)] = dynamicObject; - } else { - console.log("error loading block component"); - console.log(component.errorString()); - return false; - } - return true; -} - -var fillFound; //Set after a floodFill call to the number of blocks found -var floodBoard; //Set to 1 if the floodFill reaches off that node - -function handleClick(xPos, yPos) { - var column = Math.floor(xPos / gameCanvas.blockSize); - var row = Math.floor(yPos / gameCanvas.blockSize); - if (column >= maxColumn || column < 0 || row >= maxRow || row < 0) - return; - if (board[index(column, row)] == null) - return; - //If it's a valid block, remove it and all connected (does nothing if it's not connected) - floodFill(column, row, -1); - if (fillFound <= 0) - return; - gameCanvas.score += (fillFound - 1) * (fillFound - 1); - shuffleDown(); - victoryCheck(); -} - -function floodFill(column, row, type) { - if (board[index(column, row)] == null) - return; - var first = false; - if (type == -1) { - first = true; - type = board[index(column, row)].type; - - //Flood fill initialization - fillFound = 0; - floodBoard = new Array(maxIndex); - } - if (column >= maxColumn || column < 0 || row >= maxRow || row < 0) - return; - if (floodBoard[index(column, row)] == 1 || (!first && type != board[index(column, row)].type)) - return; - floodBoard[index(column, row)] = 1; - floodFill(column + 1, row, type); - floodFill(column - 1, row, type); - floodFill(column, row + 1, type); - floodFill(column, row - 1, type); - if (first == true && fillFound == 0) - return; //Can't remove single blocks - board[index(column, row)].dying = true; - board[index(column, row)] = null; - fillFound += 1; -} - -function shuffleDown() { - //Fall down - for (var column = 0; column < maxColumn; column++) { - var fallDist = 0; - for (var row = maxRow - 1; row >= 0; row--) { - if (board[index(column, row)] == null) { - fallDist += 1; - } else { - if (fallDist > 0) { - var obj = board[index(column, row)]; - obj.y = (row + fallDist) * gameCanvas.blockSize; - board[index(column, row + fallDist)] = obj; - board[index(column, row)] = null; - } - } - } - } - //Fall to the left - fallDist = 0; - for (column = 0; column < maxColumn; column++) { - if (board[index(column, maxRow - 1)] == null) { - fallDist += 1; - } else { - if (fallDist > 0) { - for (row = 0; row < maxRow; row++) { - obj = board[index(column, row)]; - if (obj == null) - continue; - obj.x = (fallDist - column) * gameCanvas.blockSize; - board[index(column - fallDist, row)] = obj; - board[index(column, row)] = null; - } - } - } - } -} - -//![3] -function victoryCheck() { -//![3] - //Award bonus points if no blocks left - var deservesBonus = true; - for (var column = maxColumn - 1; column >= 0; column--) - if (board[index(column, maxRow - 1)] != null) - deservesBonus = false; - if (deservesBonus) - gameCanvas.score += 500; - -//![4] - //Check whether game has finished - if (deservesBonus || !(floodMoveCheck(0, maxRow - 1, -1))) { - gameDuration = new Date() - gameDuration; - nameInputDialog.showWithInput("You won! Please enter your name: "); - } -} -//![4] - -//only floods up and right, to see if it can find adjacent same-typed blocks -function floodMoveCheck(column, row, type) { - if (column >= maxColumn || column < 0 || row >= maxRow || row < 0) - return false; - if (board[index(column, row)] == null) - return false; - var myType = board[index(column, row)].type; - if (type == myType) - return true; - return floodMoveCheck(column + 1, row, myType) || floodMoveCheck(column, row - 1, board[index(column, row)].type); -} - -//![2] -function saveHighScore(name) { - if (scoresURL != "") - sendHighScore(name); - - var db = openDatabaseSync("SameGameScores", "1.0", "Local SameGame High Scores", 100); - var dataStr = "INSERT INTO Scores VALUES(?, ?, ?, ?)"; - var data = [name, gameCanvas.score, maxColumn + "x" + maxRow, Math.floor(gameDuration / 1000)]; - db.transaction(function(tx) { - tx.executeSql('CREATE TABLE IF NOT EXISTS Scores(name TEXT, score NUMBER, gridSize TEXT, time NUMBER)'); - tx.executeSql(dataStr, data); - - var rs = tx.executeSql('SELECT * FROM Scores WHERE gridSize = "12x17" ORDER BY score desc LIMIT 10'); - var r = "\nHIGH SCORES for a standard sized grid\n\n" - for (var i = 0; i < rs.rows.length; i++) { - r += (i + 1) + ". " + rs.rows.item(i).name + ' got ' + rs.rows.item(i).score + ' points in ' + rs.rows.item(i).time + ' seconds.\n'; - } - dialog.show(r); - }); -} -//![2] - -//![1] -function sendHighScore(name) { - var postman = new XMLHttpRequest() - var postData = "name=" + name + "&score=" + gameCanvas.score + "&gridSize=" + maxColumn + "x" + maxRow + "&time=" + Math.floor(gameDuration / 1000); - postman.open("POST", scoresURL, true); - postman.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); - postman.onreadystatechange = function() { - if (postman.readyState == postman.DONE) { - dialog.show("Your score has been uploaded."); - } - } - postman.send(postData); -} -//![1] - diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/highscores/README b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/highscores/README deleted file mode 100644 index eaa00fae3..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/highscores/README +++ /dev/null @@ -1 +0,0 @@ -The SameGame example can interface with a simple PHP script to store XML high score data on a remote server. We do not have a publically accessible server available for this use, but if you have access to a PHP capable webserver you can copy the files (score_data.xml, score.php, score_style.xsl) to it and alter the highscore_server variable at the top of the samegame.js file to point to it. diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/highscores/score_data.xml b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/highscores/score_data.xml deleted file mode 100755 index c3fd90d9c..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/highscores/score_data.xml +++ /dev/null @@ -1,2 +0,0 @@ -<record><score>1000000</score><name>Alan the Tester</name><gridSize>0x0</gridSize><seconds>0</seconds></record> -<record><score>6213</score><name>Alan</name><gridSize>12x17</gridSize><seconds>51</seconds></record> diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/highscores/score_style.xsl b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/highscores/score_style.xsl deleted file mode 100755 index 670354c96..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/highscores/score_style.xsl +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1"?> -<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> -<xsl:template match="/"> - <html> - <head><title>SameGame High Scores</title></head> - <body> - <h2>SameGame High Scores</h2> - <table border="1"> - <tr bgcolor="lightsteelblue"> - <th>Name</th> - <th>Score</th> - <th>Grid Size</th> - <th>Time, s</th> - </tr> - <xsl:for-each select="records/record"> - <xsl:sort select="score" data-type="number" order="descending"/> - <tr> - <td><xsl:value-of select="name"/></td> - <td><xsl:value-of select="score"/></td> - <td><xsl:value-of select="gridSize"/></td> - <td><xsl:value-of select="seconds"/></td> - </tr> - </xsl:for-each> - </table> - </body> - </html> -</xsl:template> -</xsl:stylesheet> diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/highscores/scores.php b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/highscores/scores.php deleted file mode 100755 index daf480e21..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/highscores/scores.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php - $score = $_POST["score"]; - echo "<html>"; - echo "<head><title>SameGame High Scores</title></head><body>"; - if($score > 0){#Sending in a new high score - $name = $_POST["name"]; - $grid = $_POST["gridSize"]; - $time = $_POST["time"]; - if($name == "") - $name = "Anonymous"; - $file = fopen("score_data.xml", "a"); - $ret = fwrite($file, "<record><score>". $score . "</score><name>" - . $name . "</name><gridSize>" . $grid . "</gridSize><seconds>" - . $time . "</seconds></record>\n"); - echo "Your score has been recorded. Thanks for playing!"; - if($ret == False) - echo "<br/> There was an error though, so don't expect to see that score again."; - }else{#Read high score list - #Now uses XSLT to display. So just print the file. With XML cruft added. - #Note that firefox at least won't apply the XSLT on a php file. So redirecting - $file = fopen("scores.xml", "w"); - $ret = fwrite($file, '<?xml version="1.0" encoding="ISO-8859-1"?>' . "\n" - . '<?xml-stylesheet type="text/xsl" href="score_style.xsl"?>' . "\n" - . "<records>\n" . file_get_contents("score_data.xml") . "</records>\n"); - if($ret == False) - echo "There was an internal error. Sorry."; - else - echo '<script type="text/javascript">window.location.replace("scores.xml")</script>'; - } - echo "</body></html>"; -?> diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/samegame.qml b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/samegame.qml deleted file mode 100644 index 3e514f86a..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/samegame.qml +++ /dev/null @@ -1,125 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of Qt for Python. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 -import "content" -import "content/samegame.js" as SameGame - -Rectangle { - id: screen - - width: 490; height: 720 - - SystemPalette { id: activePalette } - - Item { - width: parent.width - anchors { top: parent.top; bottom: toolBar.top } - - Image { - id: background - anchors.fill: parent - source: "../shared/pics/background.jpg" - fillMode: Image.PreserveAspectCrop - } - - Item { - id: gameCanvas - property int score: 0 - property int blockSize: 40 - - anchors.centerIn: parent - width: parent.width - (parent.width % blockSize); - height: parent.height - (parent.height % blockSize); - - MouseArea { - anchors.fill: parent; onClicked: SameGame.handleClick(mouse.x,mouse.y); - } - } - } - - Dialog { - id: dialog - anchors.centerIn: parent - z: 100 - } - - //![0] - Dialog { - id: nameInputDialog - anchors.centerIn: parent - z: 100 - - onClosed: { - if (nameInputDialog.inputText != "") - SameGame.saveHighScore(nameInputDialog.inputText); - } - } - //![0] - - Rectangle { - id: toolBar - width: parent.width; height: 30 - color: activePalette.window - anchors.bottom: screen.bottom - - Button { - anchors { left: parent.left; verticalCenter: parent.verticalCenter } - text: "New Game" - onClicked: SameGame.startNewGame() - } - - Text { - id: score - anchors { right: parent.right; verticalCenter: parent.verticalCenter } - text: "Score: " + gameCanvas.score - } - } -} diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/samegame4.qmlproject b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/samegame4.qmlproject deleted file mode 100644 index d4909f868..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/samegame4/samegame4.qmlproject +++ /dev/null @@ -1,16 +0,0 @@ -import QmlProject 1.0 - -Project { - /* Include .qml, .js, and image files from current directory and subdirectories */ - QmlFiles { - directory: "." - } - JavaScriptFiles { - directory: "." - } - ImageFiles { - directory: "." - } - /* List of plugin directories passed to QML runtime */ - // importPaths: [ " ../exampleplugin " ] -} diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/shared/pics/background.jpg b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/shared/pics/background.jpg Binary files differdeleted file mode 100644 index 903d395c8..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/shared/pics/background.jpg +++ /dev/null diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/shared/pics/blueStar.png b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/shared/pics/blueStar.png Binary files differdeleted file mode 100644 index ff9588f80..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/shared/pics/blueStar.png +++ /dev/null diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/shared/pics/blueStone.png b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/shared/pics/blueStone.png Binary files differdeleted file mode 100644 index 20e43c75b..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/shared/pics/blueStone.png +++ /dev/null diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/shared/pics/greenStar.png b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/shared/pics/greenStar.png Binary files differdeleted file mode 100644 index cd0685471..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/shared/pics/greenStar.png +++ /dev/null diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/shared/pics/greenStone.png b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/shared/pics/greenStone.png Binary files differdeleted file mode 100644 index b568a1900..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/shared/pics/greenStone.png +++ /dev/null diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/shared/pics/redStar.png b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/shared/pics/redStar.png Binary files differdeleted file mode 100644 index 0a4dffe58..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/shared/pics/redStar.png +++ /dev/null diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/shared/pics/redStone.png b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/shared/pics/redStone.png Binary files differdeleted file mode 100644 index 36b09a268..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/shared/pics/redStone.png +++ /dev/null diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/shared/pics/star.png b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/shared/pics/star.png Binary files differdeleted file mode 100644 index defbde53c..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/shared/pics/star.png +++ /dev/null diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/shared/pics/yellowStone.png b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/shared/pics/yellowStone.png Binary files differdeleted file mode 100644 index b1ce76212..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame/shared/pics/yellowStone.png +++ /dev/null diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame1.rst b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame1.rst deleted file mode 100644 index f48c0672b..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame1.rst +++ /dev/null @@ -1,71 +0,0 @@ -.. _samegame1: - -QML Advanced Tutorial 1 - Creating the Game Canvas and Blocks -************************************************************* - -Creating the application screen -=============================== - -The first step is to create the basic QML items in your application. - -To begin with, create a main screen like this: - -.. figure:: declarative-adv-tutorial1.png - :align: center - -This is defined by the main application file, ``samegame.qml``, which looks like this: - -.. pysideinclude:: samegame/samegame1/samegame.qml - :snippet: 0 - -It gives a basic game window that includes the main canvas for the -blocks, a "New Game" button, and a score display. - -One item you may not recognize here is the SystemPalette item. This provides -access to the Qt system palette and is used to give the button a more native -look-and-feel. - -Notice the anchors for the ``Item``, ``Button``, and ``Text`` items are set using -group notation for readability. - -Adding button and block components -================================== - -The ``Button`` item in the code above is defined in a separate component file named ``Button.qml``. -To create a functional button, use the Text and MouseArea QML types inside a Rectangle. -Here is the ``Button.qml`` code: - -.. pysideinclude:: samegame/samegame1/Button.qml - :snippet: 0 - -This essentially defines a rectangle that contains text and can be clicked. The MouseArea -has an ``onClicked()`` handler that is implemented to emit the ``clicked()`` signal of the -``container`` when the area is clicked. - -In Same Game, the screen is filled with small blocks when the game begins. -Each block is an item that contains an image. The block -is defined in the ``Block.qml`` file: - -.. pysideinclude:: samegame/samegame1/Block.qml - :snippet: 0 - -At the moment, the block doesn't do anything; it is just an image. As the -tutorial progresses, you will animate and give behaviors to the blocks. -You have not added any code yet to create the blocks; this -will be done in the next chapter. - -You have set the image to be the size of its parent Item using ``anchors.fill: parent``. -This means that when you dynamically create and resize the block items -later on in the tutorial, the image will be scaled automatically to the -correct size. - -Notice the relative path for the Image item's ``source`` property. -It is relative to the location of the file that contains the Image item. -Alternatively, you could set the Image source to an absolute file path or a URL -that contains an image. - -You should be familiar with the code so far, as you have created some basic -items to get started. In the next chapter, you will populate the game canvas -with some blocks. - -[Previous :ref:`qmladvancedtutorial`] [Next :ref:`samegame2`] diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame2.rst b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame2.rst deleted file mode 100644 index 7f3ee8845..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame2.rst +++ /dev/null @@ -1,70 +0,0 @@ -.. _samegame2: - -QML Advanced Tutorial 2 - Populating the Game Canvas -**************************************************** - -Generating the blocks in JavaScript -=================================== - -Now that the basic elements are in place, start writing the game. - -The first task is to generate the game blocks. Each time the New Game button -is clicked, the game canvas is populated with a new, random set of -blocks that are generated dynamically. You can achieve this by creating -the blocks using JavaScript intead of a Repeater. - -Here is the JavaScript code for generating the blocks, contained in a new -file, ``samegame.js``. The code is explained below. - -.. pysideinclude:: samegame/samegame2/samegame.js - :snippet: 0 - -The ``startNewGame()`` function deletes the blocks created in the previous game and -calculates the number of rows and columns of blocks required to fill the game window for the new game. -Then, it creates an array to store all the game -blocks, and calls ``createBlock()`` to create enough blocks to fill the game window. - -The ``createBlock()`` function creates a block from the ``Block.qml`` file -and moves the new block to its position on the game canvas. This involves several steps: - -* ``Qt.createComponent()`` is called to - generate an instance of ``Block.qml``. If the component is ready, - we can call ``createObject()`` to create an instance of the ``Block`` - item. - -* If ``createObject()`` returned null (that is, if there was an error - while loading the object), print the error information. - -* Place the block in its position on the board and set its width and - height. Also, store it in the blocks array for future reference. - -* Finally, print error information to the console if the component - could not be loaded for some reason (for example, if the file is - missing). - -Connecting JavaScript components to QML -======================================= - -Now, call the JavaScript code in ``samegame.js`` from your QML files. -To do this, add the following line to ``samegame.qml`` to import -the JavaScript file as a module: - -.. pysideinclude:: samegame/samegame2/samegame.qml - :snippet: 2 - -This lets you to refer to any functions within ``samegame.js`` using "SameGame" -as a prefix: for example, ``SameGame.startNewGame()`` or ``SameGame.createBlock()``. -This means you can now connect the New Game button's ``onClicked`` handler to the ``startNewGame()`` -function, like this: - -.. pysideinclude:: samegame/samegame2/samegame.qml - :snippet: 1 - -So, when you click the New Game button, ``startNewGame()`` is called to generate a field of blocks, like this: - -.. figure:: declarative-adv-tutorial2.png - :align: center - -Now that the screen of blocks is ready, you can start adding the game mechanics. - -[Previous :ref:`samegame1`] [Next :ref:`samegame3`] diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame3.rst b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame3.rst deleted file mode 100644 index b3c794ec2..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame3.rst +++ /dev/null @@ -1,124 +0,0 @@ -.. _samegame3: - -QML Advanced Tutorial 3 - Implementing the Game Logic -***************************************************** - -Making a playable game -====================== - -Now that all the UI components are ready, add the game logic that -dictates how a player interacts with the blocks and plays the game, -until it is won or lost. - -To achieve this, add the following functions to ``samegame.js``: - - -* ``handleClick(x,y)`` -* ``floodFill(xIdx,yIdx,type)`` -* ``shuffleDown()`` -* ``victoryCheck()`` -* ``floodMoveCheck(xIdx, yIdx, type)`` - -As this is a tutorial about QML, not game design, only the ``handleClick()`` -and ``victoryCheck()`` functions that interface directly with the QML items -are discussed. - -.. Note:: Although the game logic here is written in JavaScript, - it could have been written in Python and then exposed to QML. - -Enabling mouse click interaction -================================ - -To make it easier for the JavaScript code to interface with the QML items, -an Item called ``gameCanvas`` is added to ``samegame.qml``. It replaces the -background as the item which contains the blocks. It also accepts mouse input -from the user. Here is the item code: - -.. pysideinclude:: samegame/samegame3/samegame.qml - :snippet: 1 - -The ``gameCanvas`` item is of the same size as the board, and has a ``score`` -property and a MouseArea to handle mouse clicks. The blocks are now created as -its children, and its dimensions are used to determine the board size -so that the application scales to the available screen size. As the item's size -is bound to a multiple of ``blockSize``, ``blockSize`` is moved into ``samegame.qml`` -from ``samegame.js``, as a QML property. - -.. Note:: The ``blockSize`` can still be accessed from the script. - -When clicked, the MouseArea calls ``handleClick()`` in ``samegame.js``, which -determines whether the player's click should cause any blocks to be removed, -and updates ``gameCanvas.score`` with the current score if necessary. Here is -the ``handleClick()`` function: - -.. pysideinclude:: samegame/samegame3/samegame.js - :snippet: 1 - -.. Note:: If ``score`` was a global variable in the ``samegame.js`` file, - you would not be able to bind to it. You can only bind to QML properties. - -Updating the score -================== - -When the player clicks a block and triggers \c handleClick(), \c handleClick() -also calls \c victoryCheck() to update the score and to check whether the -player has completed the game. Here is the \c victoryCheck() code: - -.. pysideinclude:: samegame/samegame3/samegame.js - :snippet: 2 - -This updates the ``gameCanvas.score`` value and displays a "Game Over" dialog -if the game is finished. - -The Game Over dialog is created using a ``Dialog`` item that is defined in -``Dialog.qml``. Here is the ``Dialog.qml`` code: - -.. pysideinclude:: samegame/samegame3/Dialog.qml - :snippet: 0 - -Notice how it is designed to be usable imperatively from the script file, via -the functions and signals. And this is how it is used in the main -``samegame.qml`` file: - -.. pysideinclude:: samegame/samegame3/samegame.qml - :snippet: 2 - -Give the dialog a ``z`` value of 100 to ensure it is displayed on top of our -other components. The default ``z`` value for an item is 0. - - -A dash of color ---------------- - -It's not much fun to play Same Game if all the blocks are of the same color, so -the ``createBlock()`` function in ``samegame.js`` randomly changes the color -to create a different type of block (for either red, green or blue) each time -it is called. ``Block.qml`` has also changed so that each block contains a -different image depending on its type: - -.. pysideinclude:: samegame/samegame3/Block.qml - :snippet: 0 - - -A working game -============== - -You now have a working game! The blocks can be clicked, the player can -score, and the game can end (and then you can start a new one). -Here is a screenshot of what has been accomplished so far: - -.. figure:: declarative-adv-tutorial3.png - :align: center - -This is what ``samegame.qml`` looks like now: - -.. pysideinclude:: samegame/samegame3/samegame.qml - :snippet: 0 - -The game works, but it's a little boring right now. Where are the smooth -animated transitions? Where are the high scores? -If you were a QML expert, you could have written these in the first -iteration, but in this tutorial they've been saved until the next chapter -- where your application becomes alive! - -[Previous :ref:`samegame2`] [Next :ref:`samegame4`] diff --git a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame4.rst b/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame4.rst deleted file mode 100644 index 5ea38a5ad..000000000 --- a/sources/pyside2/doc/tutorials/qmladvancedtutorial/samegame4.rst +++ /dev/null @@ -1,233 +0,0 @@ -.. _samegame4: - -QML Advanced Tutorial 4 - Finishing Touches -******************************************* - -Adding some flair -================= - -In this chapter, you are going to do two things to enhance the game -experience: animate the blocks and add a High Score system. - -You should clean up the directory structure, now that there are a -lot of files. Move all the JavaScript and QML files outside of ``samegame.qml`` -into a new sub-directory named "content". - -In anticipation of the new block animations, ``Block.qml`` file is now renamed -to ``BoomBlock.qml``. - -Animating block movement ------------------------- - -First, you will animate the blocks so that they move in a fluid manner. QML has -a number of methods for adding fluid movement, and in this case you are going to -use the Behavior type to add a SpringAnimation. In ``BoomBlock.qml``, apply a -SpringAnimation behavior to the ``x`` and ``y`` properties so that the -block follows and animate its movement in a spring-like fashion towards the -specified position (whose values are set by ``samegame.js``). Here is the code -added to ``BoomBlock.qml``: - -.. pysideinclude:: samegame/samegame4/content/BoomBlock.qml - :snippet: 1 - -The ``spring`` and ``damping`` values can be changed to modify the spring-like -effect of the animation. - -The ``enabled: spawned`` setting refers to the ``spawned`` value that comes from -the ``createBlock()`` function in ``samegame.js``. This ensures that the -SpringAnimation on ``x`` is only enabled after ``createBlock()`` has set the -block to the correct position. Otherwise, the blocks will slide out of the -corner (0,0) when a game begins, instead of falling from the top in rows. -Try commenting out the line, ``enabled: spawned``, and see the effect for -yourself. - -Animating block opacity changes -------------------------------- - -Next, add a smooth exit animation. For this, use a Behavior type, which -allows us to specify a default animation when a property change occurs. In this -case, when the ``opacity`` of a Block changes, animate the opacity value so that -it gradually fades in and out, instead of abruptly changing between fully -visible and invisible. To do this, apply a Behavior on the ``opacity`` property -of the ``Image`` item in ``BoomBlock.qml``: - -.. pysideinclude:: samegame/samegame4/content/BoomBlock.qml - :snippet: 2 - -Note the ``opacity: 0``, which means the block is transparent when it is first -created. You could set the opacity in ``samegame.js`` when we create and -destroy the blocks, but use states instead, as this is useful for the next -animation you are going to add. Initially, add these States to the root -item of ``BoomBlock.qml``: - -:: - - property bool dying: false - states: [ - State{ name: "AliveState"; when: spawned == true && dying == false - PropertyChanges { target: img; opacity: 1 } - }, - State{ name: "DeathState"; when: dying == true - PropertyChanges { target: img; opacity: 0 } - } - ] - -Now blocks will automatically fade in, as ``spawned`` is set to true when -you implemented the block animations. To fade out, set ``dying`` to true -instead of setting opacity to 0 when a block is destroyed (in the -``floodFill()`` function). - -Adding particle effects ------------------------ - -Finally, add a cool-looking particle effect to the blocks when they are -destroyed. To do this, first add a Particles item in -``BoomBlock.qml``, like this: - -.. pysideinclude:: samegame/samegame4/content/BoomBlock.qml - :snippet: 3 - -To fully understand this you should read the Particles documentation, -but it's important to note that ``emissionRate`` is set to zero so that -particles are not emitted normally. Also, extend the ``dying`` State, -which creates a burst of particles by calling the ``burst()`` method on the -particles item. The code for the states now look like this: - -.. pysideinclude:: samegame/samegame4/content/BoomBlock.qml - :snippet: 4 - -Now the gaming experience is pleasing with these animations. With a few -more simple animations for all of the player's actions, it will look even better. -The end result is shown below, with a different set of images to demonstrate -the basic theme: - -.. figure:: declarative-adv-tutorial4.gif - :align: center - -The theme change here is produced simply by replacing the block images. This -can be done at runtime by changing the ``source`` property of the Image. You -could go a step further and add a button that toggles between themes with -different images. - -Keeping a high scores table -=========================== - -Another feature you might want to add to the game is a method of storing and -retrieving high scores. - -To do this, show a dialog when the game is over to request the player's name -and add it to a High Scores table. This requires a few changes to -``Dialog.qml``. In addition to a ``Text`` item, it now has a ``TextInput`` -child item for receiving keyboard text input: - -.. pysideinclude:: samegame/samegame4/content/Dialog.qml - :snippet: 2 - :prepend: Rectangle { - ... - :append: ... - } - - -Also, add a ``showWithInput()`` function. The text input will only be visible if -this function is called instead of ``show()``. When the dialog is closed, it -emits a ``closed()`` signal, and other items can retrieve the text entered by -the user through the ``inputText`` property: - -.. pysideinclude:: samegame/samegame4/content/Dialog.qml - :snippet: 1 - :prepend: Rectangle { - ... - :append: ... - } - -Now the dialog can be used in ``samegame.qml``: - -.. pysideinclude:: samegame/samegame4/samegame.qml - :snippet: 0 - -When the dialog emits the ``closed`` signal, we call the new ``saveHighScore()`` -function in ``samegame.js``, to store the high score locally in an SQL database -and also send the score to an online database if possible. - -The ``nameInputDialog`` is activated in the ``victoryCheck()`` function in -``samegame.js``: - -.. pysideinclude:: samegame/samegame4/content/samegame.js - :snippet: 4 - :prepend: function vitoryCheck() { - ... - -Storing high scores offline ---------------------------- - -Now, you need to implement the functionality to actually save the High Scores table. - -Here is the ``saveHighScore()`` function in ``samegame.js``: - -.. pysideinclude:: samegame/samegame4/content/samegame.js - :snippet: 2 - -First, call ``sendHighScore()`` to send the high scores to an online database. - -Then, use the Offline Storage API to maintain a persistent SQL database, unique -to this application. Create an offline storage database for the high scores -using ``openDatabase()``, then prepare the data and SQL query that we want to use -to save it. The offline storage API uses SQL queries for data manipulation and -retrieval. The ``db.transaction()`` uses three SQL queries: - * To initialize the database, if necessary. - * To add high scores to the database. - * To retrieve the high score records. - -To use the returned records, turn it into a string with one line per row, and show -a dialog containing that string. - -This is one way of storing and displaying high scores locally, but certainly -not the only way. A more complex alternative would be to create a high score -dialog component, and pass it the results for processing and display (instead -of reusing the ``Dialog``). This allows for a more themeable dialog that could -present the high scores in a better way. If you are using QML-based UI for a -Python application, you can also pass the score to a function that stores it -locally in a variety of ways. This can be a simple format without SQL, or in -another SQL database. - -Storing high scores online --------------------------- - -You've seen how you can store high scores locally, but it is also easy to -integrate a web-enabled high score storage into your application. The -implementation we've done here is very simple: the high score data is posted to -a php script running on a server somewhere, and that server then stores it and -displays it to visitors. You could also request an XML or QML file, which -contains and displays the scores, but that's beyond the scope of this tutorial. -The php script used here is available in the ``examples`` directory. - -If the player entered their name, you can send the data to an online database -service. The following code snippet from ``samegame.js`` demonstrates this well: - -.. pysideinclude:: samegame/samegame4/content/samegame.js - :snippet: 1 - -The XMLHttpRequest in this code is the same as the ``XMLHttpRequest()`` as you'll -find in standard browser JavaScript, and can be used in the same way to -dynamically get XML or QML from the web service to display the high scores. We don't worry about the response in this case - we just post the high -score data to the web server. If it had returned a QML file (or a URL to a QML file) you could instantiate it in much the same -way as you did with the blocks. - -An alternate way to access and submit web-based data would be to use QML items designed for this purpose. XmlListModel -makes it very easy to fetch and display XML based data such as RSS in a QML application (see the Flickr demo for an example). - - -That's it! -========== - -By following this tutorial you've seen how you can write a fully functional application in QML: - -* Build your application with QML items. -* Add application logic with JavaScript code. -* Add animations with Behaviors and states. -* Store persistent application data using, for example, the Offline Storage API or XMLHttpRequest. - -There is so much more to learn about QML that we haven't been able to cover in this tutorial. Check out all the -demos and examples and the documentation to see all the things you can do with QML! - -[Previous :ref:`samegame3`] diff --git a/sources/pyside2/doc/tutorials/qmlintegration/main.py b/sources/pyside2/doc/tutorials/qmlintegration/main.py new file mode 100644 index 000000000..3451c65b5 --- /dev/null +++ b/sources/pyside2/doc/tutorials/qmlintegration/main.py @@ -0,0 +1,113 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +from os.path import abspath, dirname, join + +from PySide2.QtCore import QObject, Slot +from PySide2.QtGui import QGuiApplication +from PySide2.QtQml import QQmlApplicationEngine + +from style_rc import * + + +class Bridge(QObject): + + @Slot(str, result=str) + def getColor(self, color_name): + if color_name.lower() == "red": + return "#ef9a9a" + elif color_name.lower() == "green": + return "#a5d6a7" + elif color_name.lower() == "blue": + return "#90caf9" + else: + return "white" + + @Slot(float, result=int) + def getSize(self, s): + size = int(s * 42) # Maximum font size + if size <= 0: + return 1 + else: + return size + + @Slot(str, result=bool) + def getItalic(self, s): + if s.lower() == "italic": + return True + else: + return False + + @Slot(str, result=bool) + def getBold(self, s): + if s.lower() == "bold": + return True + else: + return False + + @Slot(str, result=bool) + def getUnderline(self, s): + if s.lower() == "underline": + return True + else: + return False + + +if __name__ == '__main__': + app = QGuiApplication(sys.argv) + engine = QQmlApplicationEngine() + + # Instance of the Python object + bridge = Bridge() + + # Expose the Python object to QML + context = engine.rootContext() + context.setContextProperty("con", bridge) + + # Get the path of the current directory, and then add the name + # of the QML file, to load it. + qmlFile = join(dirname(__file__), 'view.qml') + engine.load(abspath(qmlFile)) + + if not engine.rootObjects(): + sys.exit(-1) + + sys.exit(app.exec_()) diff --git a/sources/pyside2/doc/tutorials/qmlintegration/qmlintegration.rst b/sources/pyside2/doc/tutorials/qmlintegration/qmlintegration.rst new file mode 100644 index 000000000..36a12381d --- /dev/null +++ b/sources/pyside2/doc/tutorials/qmlintegration/qmlintegration.rst @@ -0,0 +1,111 @@ +######################## +QML Integration Tutorial +######################## + +This tutorial provides a quick walk-through of a python application that loads, and interacts with +a QML file. QML is a declarative language that lets you design UIs faster than a traditional +language, such as C++. The QtQml and QtQuick modules provides the necessary infrastructure for +QML-based UIs. + +In this tutorial, you will learn how to integrate Python with a QML application through a context +property. This mechanism will help us to understand how to use Python as a backend for certain +signals from the UI elements in the QML interface. Additionally, you will learn how to provide +a modern look to your QML application using one of the features from Qt Quick Controls 2. + +The tutorial is based on an application that allow you to set many text properties, like increasing +the font size, changing the color, changing the style, and so on. Before you begin, install the +`PySide2 <https://pypi.org/project/PySide2/>`_ Python packages. + +The following step-by-step process will guide you through the key elements of the QML based +application and PySide2 integration: + +#. First, let's start with the following QML-based UI: + + .. image:: textproperties_default.png + + The design is based on a `GridLayout`, containing two `ColumnLayout`. + Inside the UI you will find many `RadioButton`, `Button`, and a `Slider`. + +#. With the QML file in place, you can load it from Python: + + .. literalinclude:: main.py + :linenos: + :lines: 98-108 + :emphasize-lines: 103,107 + + Notice that we specify the name of the context property, **con**, + and also we explicitly load our QML file. + +#. Define the `Bridge` class, containing all the logic for the context property: + + .. literalinclude:: main.py + :linenos: + :lines: 51-91 + +#. Now, go back to the QML file and connect the signals to the slots defined in the `Bridge` class: + + .. literalinclude:: view.qml + :linenos: + :lines: 85-93 + :emphasize-lines: 89-91 + + The properties *Italic*, *Bold*, and *Underline* are mutually + exclusive, this means only one can be active at any time. + To achieve this each time we select one of these options, we + check the three properties via the context property as you can + see in the above snippet. + Only one of the three will return *True*, while the other two + will return *False*, that is how we make sure only one is being + applied to the text. + +#. Each slot verifies if the selected option contains the text associated + to the property: + + .. literalinclude:: main.py + :linenos: + :lines: 79-84 + :emphasize-lines: 82,84 + + Returning *True* or *False* allows you to activate and deactivate + the properties of the QML UI elements. + + It is also possible to return other values that are not *Boolean*, + like the slot in charge of returning the font size: + + .. literalinclude:: main.py + :linenos: + :lines: 64-70 + +#. Now, for changing the look of our application, you have two options: + + 1. Use the command line: execute the python file adding the option, `--style`:: + + python main.py --style material + + 2. Use a `qtquickcontrols2.conf` file: + + .. literalinclude:: qtquickcontrols2.conf + :linenos: + + Then add it to your `.qrc` file: + + .. literalinclude:: style.qrc + :linenos: + + Generate the *rc* file running, `pyside2-rcc style.qrc > style_rc.py` + And finally import it from your `main.py` script. + + .. literalinclude:: main.py + :linenos: + :lines: 41-48 + :emphasize-lines: 48 + + You can read more about this configuration file + `here <https://doc.qt.io/qt-5/qtquickcontrols2-configuration.html>`_. + + The final look of your application will be: + + .. image:: textproperties_material.png + +You can download `view.qml <view.qml>`_ and `main.py <main.py>`_ +to try this example. diff --git a/sources/pyside2/doc/tutorials/qmlintegration/qtquickcontrols2.conf b/sources/pyside2/doc/tutorials/qmlintegration/qtquickcontrols2.conf new file mode 100644 index 000000000..850646021 --- /dev/null +++ b/sources/pyside2/doc/tutorials/qmlintegration/qtquickcontrols2.conf @@ -0,0 +1,10 @@ +[Controls] +Style=Material + +[Universal] +Theme=System +Accent=Red + +[Material] +Theme=Dark +Accent=Red diff --git a/sources/pyside2/doc/tutorials/qmlintegration/style.qrc b/sources/pyside2/doc/tutorials/qmlintegration/style.qrc new file mode 100644 index 000000000..e313f5ed6 --- /dev/null +++ b/sources/pyside2/doc/tutorials/qmlintegration/style.qrc @@ -0,0 +1,5 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource prefix="/"> + <file>qtquickcontrols2.conf</file> +</qresource> +</RCC> diff --git a/sources/pyside2/doc/tutorials/qmlintegration/textproperties_default.png b/sources/pyside2/doc/tutorials/qmlintegration/textproperties_default.png Binary files differnew file mode 100644 index 000000000..cfeac9368 --- /dev/null +++ b/sources/pyside2/doc/tutorials/qmlintegration/textproperties_default.png diff --git a/sources/pyside2/doc/tutorials/qmlintegration/textproperties_material.png b/sources/pyside2/doc/tutorials/qmlintegration/textproperties_material.png Binary files differnew file mode 100644 index 000000000..47866c10e --- /dev/null +++ b/sources/pyside2/doc/tutorials/qmlintegration/textproperties_material.png diff --git a/sources/pyside2/doc/tutorials/qmlintegration/view.qml b/sources/pyside2/doc/tutorials/qmlintegration/view.qml new file mode 100644 index 000000000..97968d691 --- /dev/null +++ b/sources/pyside2/doc/tutorials/qmlintegration/view.qml @@ -0,0 +1,183 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +import QtQuick 2.0 +import QtQuick.Layouts 1.12 +import QtQuick.Controls 2.12 +import QtQuick.Window 2.12 +import QtQuick.Controls.Material 2.12 + +ApplicationWindow { + id: page + width: 800 + height: 400 + visible: true + + GridLayout { + id: grid + columns: 2 + rows: 3 + + ColumnLayout { + spacing: 2 + Layout.preferredWidth: 400 + + Text { + id: leftlabel + Layout.alignment: Qt.AlignHCenter + color: "white" + font.pointSize: 16 + text: "Qt for Python" + Layout.preferredHeight: 100 + Material.accent: Material.Green + } + + RadioButton { + id: italic + text: "Italic" + onToggled: { + leftlabel.font.italic = con.getItalic(italic.text) + leftlabel.font.bold = con.getBold(italic.text) + leftlabel.font.underline = con.getUnderline(italic.text) + + } + } + RadioButton { + id: bold + text: "Bold" + onToggled: { + leftlabel.font.italic = con.getItalic(bold.text) + leftlabel.font.bold = con.getBold(bold.text) + leftlabel.font.underline = con.getUnderline(bold.text) + } + } + RadioButton { + id: underline + text: "Underline" + onToggled: { + leftlabel.font.italic = con.getItalic(underline.text) + leftlabel.font.bold = con.getBold(underline.text) + leftlabel.font.underline = con.getUnderline(underline.text) + } + } + RadioButton { + id: noneradio + text: "None" + checked: true + onToggled: { + leftlabel.font.italic = con.getItalic(noneradio.text) + leftlabel.font.bold = con.getBold(noneradio.text) + leftlabel.font.underline = con.getUnderline(noneradio.text) + } + } + } + + ColumnLayout { + id: rightcolumn + spacing: 2 + Layout.columnSpan: 1 + Layout.preferredWidth: 400 + Layout.preferredHeight: 400 + Layout.fillWidth: true + + RowLayout { + Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + + + Button { + id: red + text: "Red" + highlighted: true + Material.accent: Material.Red + onClicked: { + leftlabel.color = con.getColor(red.text) + } + } + Button { + id: green + text: "Green" + highlighted: true + Material.accent: Material.Green + onClicked: { + leftlabel.color = con.getColor(green.text) + } + } + Button { + id: blue + text: "Blue" + highlighted: true + Material.accent: Material.Blue + onClicked: { + leftlabel.color = con.getColor(blue.text) + } + } + Button { + id: nonebutton + text: "None" + highlighted: true + Material.accent: Material.BlueGrey + onClicked: { + leftlabel.color = con.getColor(nonebutton.text) + } + } + } + RowLayout { + Layout.fillWidth: true + Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + Text { + id: rightlabel + color: "white" + text: "Font size" + Material.accent: Material.White + } + Slider { + width: rightcolumn.width*0.6 + Layout.alignment: Qt.AlignRight + id: slider + value: 0.5 + onValueChanged: { + leftlabel.font.pointSize = con.getSize(value) + } + } + } + } + } +} diff --git a/sources/pyside2/doc/tutorials/qmltutorial/declarative-tutorial1.png b/sources/pyside2/doc/tutorials/qmltutorial/declarative-tutorial1.png Binary files differdeleted file mode 100644 index c9d3844cb..000000000 --- a/sources/pyside2/doc/tutorials/qmltutorial/declarative-tutorial1.png +++ /dev/null diff --git a/sources/pyside2/doc/tutorials/qmltutorial/declarative-tutorial2.png b/sources/pyside2/doc/tutorials/qmltutorial/declarative-tutorial2.png Binary files differdeleted file mode 100644 index 835484aa4..000000000 --- a/sources/pyside2/doc/tutorials/qmltutorial/declarative-tutorial2.png +++ /dev/null diff --git a/sources/pyside2/doc/tutorials/qmltutorial/declarative-tutorial3_animation.gif b/sources/pyside2/doc/tutorials/qmltutorial/declarative-tutorial3_animation.gif Binary files differdeleted file mode 100644 index 80b78dea9..000000000 --- a/sources/pyside2/doc/tutorials/qmltutorial/declarative-tutorial3_animation.gif +++ /dev/null diff --git a/sources/pyside2/doc/tutorials/qmltutorial/helloworld.tar.bz2 b/sources/pyside2/doc/tutorials/qmltutorial/helloworld.tar.bz2 Binary files differdeleted file mode 100644 index 001a5258d..000000000 --- a/sources/pyside2/doc/tutorials/qmltutorial/helloworld.tar.bz2 +++ /dev/null diff --git a/sources/pyside2/doc/tutorials/qmltutorial/helloworld/Cell.qml b/sources/pyside2/doc/tutorials/qmltutorial/helloworld/Cell.qml deleted file mode 100644 index 78ff12dd5..000000000 --- a/sources/pyside2/doc/tutorials/qmltutorial/helloworld/Cell.qml +++ /dev/null @@ -1,82 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of Qt for Python. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//![0] -import QtQuick 2.0 - -//![1] -Item { - id: container -//![4] - property alias cellColor: rectangle.color -//![4] -//![5] - signal clicked(color cellColor) -//![5] - - width: 40; height: 25 -//![1] - -//![2] - Rectangle { - id: rectangle - border.color: "white" - anchors.fill: parent - } -//![2] - -//![3] - MouseArea { - anchors.fill: parent - onClicked: container.clicked(container.cellColor) - } -//![3] -} -//![0] diff --git a/sources/pyside2/doc/tutorials/qmltutorial/helloworld/tutorial1.qml b/sources/pyside2/doc/tutorials/qmltutorial/helloworld/tutorial1.qml deleted file mode 100644 index 381aeb8c4..000000000 --- a/sources/pyside2/doc/tutorials/qmltutorial/helloworld/tutorial1.qml +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of Qt for Python. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//![0] -//![3] -import QtQuick 2.0 -//![3] - -//![1] -Rectangle { - id: page - width: 500; height: 200 - color: "lightgray" -//![1] - -//![2] - Text { - id: helloText - text: "Hello world!" - y: 30 - anchors.horizontalCenter: page.horizontalCenter - font.pointSize: 24; font.bold: true - } -//![2] -} -//![0] diff --git a/sources/pyside2/doc/tutorials/qmltutorial/helloworld/tutorial2.qml b/sources/pyside2/doc/tutorials/qmltutorial/helloworld/tutorial2.qml deleted file mode 100644 index 4fd0cbf98..000000000 --- a/sources/pyside2/doc/tutorials/qmltutorial/helloworld/tutorial2.qml +++ /dev/null @@ -1,82 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of Qt for Python. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//![0] -import QtQuick 2.0 - -Rectangle { - id: page - width: 500; height: 200 - color: "lightgray" - - Text { - id: helloText - text: "Hello world!" - y: 30 - anchors.horizontalCenter: page.horizontalCenter - font.pointSize: 24; font.bold: true - } - - Grid { - id: colorPicker - x: 4; anchors.bottom: page.bottom; anchors.bottomMargin: 4 - rows: 2; columns: 3; spacing: 3 - -//![1] - Cell { cellColor: "red"; onClicked: helloText.color = cellColor } -//![1] - Cell { cellColor: "green"; onClicked: helloText.color = cellColor } - Cell { cellColor: "blue"; onClicked: helloText.color = cellColor } - Cell { cellColor: "yellow"; onClicked: helloText.color = cellColor } - Cell { cellColor: "steelblue"; onClicked: helloText.color = cellColor } - Cell { cellColor: "black"; onClicked: helloText.color = cellColor } - } -} -//![0] diff --git a/sources/pyside2/doc/tutorials/qmltutorial/helloworld/tutorial3.qml b/sources/pyside2/doc/tutorials/qmltutorial/helloworld/tutorial3.qml deleted file mode 100644 index fcd7d388c..000000000 --- a/sources/pyside2/doc/tutorials/qmltutorial/helloworld/tutorial3.qml +++ /dev/null @@ -1,101 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of Qt for Python. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//![0] -import QtQuick 2.0 - -Rectangle { - id: page - width: 500; height: 200 - color: "lightgray" - - Text { - id: helloText - text: "Hello world!" - y: 30 - anchors.horizontalCenter: page.horizontalCenter - font.pointSize: 24; font.bold: true - -//![1] - MouseArea { id: mouseArea; anchors.fill: parent } -//![1] - -//![2] - states: State { - name: "down"; when: mouseArea.pressed == true - PropertyChanges { target: helloText; y: 160; rotation: 180; color: "red" } - } -//![2] - -//![3] - transitions: Transition { - from: ""; to: "down"; reversible: true - ParallelAnimation { - NumberAnimation { properties: "y,rotation"; duration: 500; easing.type: Easing.InOutQuad } - ColorAnimation { duration: 500 } - } - } -//![3] - } - - Grid { - id: colorPicker - x: 4; anchors.bottom: page.bottom; anchors.bottomMargin: 4 - rows: 2; columns: 3; spacing: 3 - - Cell { cellColor: "red"; onClicked: helloText.color = cellColor } - Cell { cellColor: "green"; onClicked: helloText.color = cellColor } - Cell { cellColor: "blue"; onClicked: helloText.color = cellColor } - Cell { cellColor: "yellow"; onClicked: helloText.color = cellColor } - Cell { cellColor: "steelblue"; onClicked: helloText.color = cellColor } - Cell { cellColor: "black"; onClicked: helloText.color = cellColor } - } -} -//![0] diff --git a/sources/pyside2/doc/tutorials/qmltutorial/index.rst b/sources/pyside2/doc/tutorials/qmltutorial/index.rst deleted file mode 100644 index 45a6842bc..000000000 --- a/sources/pyside2/doc/tutorials/qmltutorial/index.rst +++ /dev/null @@ -1,25 +0,0 @@ - -.. _qmltutorial: - -QML Tutorial -************ - -This tutorial gives an introduction to QML, the mark up language for Qt Quick. It doesn't cover everything; -the emphasis is on teaching the key principles, and features are introduced as needed. - -Through the different steps of this tutorial you will learn about QML basic types, create our own QML component -with properties and signals, and create a simple animation with the help of states and transitions. - -Chapter one starts with a minimal "Hello world" program and the following chapters introduce new concepts. - -The tutorial's source code can be downloaded :download:`here<helloworld.tar.bz2>`. - -Tutorial chapters: - -.. toctree:: - :maxdepth: 1 - - step1.rst - step2.rst - step3.rst - diff --git a/sources/pyside2/doc/tutorials/qmltutorial/step1.rst b/sources/pyside2/doc/tutorials/qmltutorial/step1.rst deleted file mode 100644 index bca69d9f4..000000000 --- a/sources/pyside2/doc/tutorials/qmltutorial/step1.rst +++ /dev/null @@ -1,66 +0,0 @@ -.. _qmlbasictypes: - -QML Tutorial 1 - Basic Types -**************************** - -This first program is a very simple "Hello world" example that introduces some basic QML concepts. -The following image is a screenshot of this program. - -.. figure:: declarative-tutorial1.png - :align: center - -Here is the QML code for the application: - -.. pysideinclude:: helloworld/tutorial1.qml - :snippet: 0 - -Walkthrough -=========== - -Import ------- - -First, you need to import the types that are required for this example. Most QML files import the built-in QML -types (like Rectangle, Image, ...) that come with Qt, using the following statement: - -.. pysideinclude:: helloworld/tutorial1.qml - :snippet: 3 - -Rectangle element ------------------ - -.. pysideinclude:: helloworld/tutorial1.qml - :snippet: 1 - -Declare a root element using the Rectangle type, which is one of the basic building blocks to create an application in QML. -Give it an ``id`` so that you can refer to it later. For example, call it "page", and also set its ``width``, -``height``, and ``color`` properties. - -Text element ------------- - -.. pysideinclude code/tutorial1.qml - :snippet: 2 - -Add a Text element as the child of the Rectangle element to display the text, 'Hello world!'. - -Use its ``y`` property to position it at 30 pixels from the top of its parent. - -The ``anchors.horizontalCenter`` property refers to the horizontal center of an element. -In this case, specify that the text element must be horizontally centered in the *page* element. - -The ``font.pointSize`` and ``font.bold properties`` are related to fonts and use the dot notation. - - -Viewing the example -------------------- - -To view what you have created, run the ``qmlscene`` tool (located in the ``bin directory`` of your Qt installation) with your -QML filename as the first argument. For example, to run the Tutorial 1 example from the install -location, you would type: - -:: - - > [QT_INSTALL_DIR]\bin\qmlscene tutorial1.qml - -[Previous :ref:`qmltutorial`][Next :ref:`qmlcomponents`] diff --git a/sources/pyside2/doc/tutorials/qmltutorial/step2.rst b/sources/pyside2/doc/tutorials/qmltutorial/step2.rst deleted file mode 100644 index 5b48ca63f..000000000 --- a/sources/pyside2/doc/tutorials/qmltutorial/step2.rst +++ /dev/null @@ -1,81 +0,0 @@ -.. _qmlcomponents: - -QML Tutorial 2 - QML Components -******************************* - -In this chapter, you are going to add a color picker to change the color of the text. - -.. figure:: declarative-tutorial2.png - :align: center - -The color picker is made of six cells with different colors. -To avoid writing the same code multiple times for each cell, create a new ``Cell`` component. -A component provides a way of defining a new type that you can re-use in other QML files. -A QML component is like a black-box that interacts with the outside world through its properties, signals, -and functions, and is generally defined in its own QML file. -The component's filename must always start with a capital letter. - -Here is the QML code for ``Cell``: - -.. pysideinclude:: helloworld/Cell.qml - :snippet: 0 - -Walkthrough -=========== - -The Cell Component ------------------- - -.. pysideinclude:: helloworld/Cell.qml - :snippet: 1 - -The root element of the component is an Item with the ``id``, *container*. -An Item is the most basic visual element in QML and is often used as a container for other elements. - -.. pysideinclude:: helloworld/Cell.qml - :snippet: 4 - -Its ``cellColor`` property is accessible from *outside* the component, allowing you -to instantiate cells with different colors. It is an alias to the existing color property of the rectangle -that composes the cell. - -.. pysideinclude:: helloworld/Cell.qml - :snippet: 5 - -The Cell has a signal called *clicked* with the *cellColor* parameter of type *color*. -You need this signal to change the color of the text in the main QML file later. - -.. pysideinclude:: helloworld/Cell.qml - :snippet: 2 - -The cell component is basically a colored rectangle with the ``id``, *rectangle*. - -Its ``anchors.fill`` property is a convenient way to set the size of an element. -In this case the rectangle will have the same size as its parent. - -.. pysideinclude:: helloworld/Cell.qml - :snippet: 3 - -In order to change the color of the text when the cell is clicked, a MouseArea element with -the same size as its parent is used. - -A MouseArea enables you to react to mouse events such as clicked, hover, and so on. In this case, when the MouseArea *clicked* -signal is reported, the Cell's *clicked* signal is emitted. - -The main QML file ------------------ - -In the main QML file, use the ``Cell`` component to create the color picker: - -.. pysideinclude:: helloworld/tutorial2.qml - :snippet: 0 - -Create the color picker by putting 6 cells with different colors in a grid. - -.. pysideinclude:: helloworld/tutorial2.qml - :snippet: 1 - -When the *clicked* signal of a cell is triggered, set the color of the text to the *cellColor* passed as a parameter. -You can react to a signal of a component through a handler of the name, *'onSignalName'*. - -[Previous :ref:`qmlbasictypes`][Next :ref:`qmlstatesandtransitions`] diff --git a/sources/pyside2/doc/tutorials/qmltutorial/step3.rst b/sources/pyside2/doc/tutorials/qmltutorial/step3.rst deleted file mode 100644 index 6d5a72f13..000000000 --- a/sources/pyside2/doc/tutorials/qmltutorial/step3.rst +++ /dev/null @@ -1,46 +0,0 @@ -.. _qmlstatesandtransitions: - -QML Tutorial 3 - States and Transitions -*************************************** - -In this chapter, you are guided through the steps to make the example a little more dynamic by -introducing states and transitions. For example, moving the text to the bottom of the screen, -rotate, and change its color when clicked. - -.. figure:: declarative-tutorial3_animation.gif - :align: center - -Here is the QML code for such a behavior: - -.. pysideinclude:: helloworld/tutorial3.qml - :snippet: 0 - -Walkthrough -=========== - -.. pysideinclude:: helloworld/tutorial3.qml - :snippet: 2 - -First, create a new *down* state for the text element. -Pressing the MouseArea activates this new state and releasing it deactivates the state. - -The *down* state includes a set of property changes from the implicit *default state* -(the items as they were initially defined in the QML). -Specifically, set the ``y`` property of the text to ``160``, rotation to ``180``, and ``color`` to red. - -.. pysideinclude:: helloworld/tutorial3.qml - :snippet: 3 - -To make the application even better, add a transiton between the two states so that switching between these -two states look smooth and nice. - -The ``from`` and ``to`` properties of the Transition element define the states between which the transition will run. -In this case, you want a transition from the default state to the *down* state. - -To have a similar transition effect when changing back from the *down* state to the default state, -set the ``reversible`` property to ``true``. This is equivalent to writing two transitions. - -The ParallelAnimation element makes sure that the two types of animations (number and color) start at the same time. -You could also run them one after the other by using SequentialAnimation instead. - -[Previous :ref:`qmlcomponents`] |