{"id":2059,"date":"2016-03-23T15:26:53","date_gmt":"2016-03-23T14:26:53","guid":{"rendered":"https:\/\/www.opengis.ch\/?p=2059"},"modified":"2020-04-29T16:05:40","modified_gmt":"2020-04-29T14:05:40","slug":"prepare-your-plugins-for-qgis-3","status":"publish","type":"post","link":"https:\/\/www.opengis.ch\/fr\/2016\/03\/23\/prepare-your-plugins-for-qgis-3\/","title":{"rendered":"Prepare your plugins for QGIS 3"},"content":{"rendered":"<p>QGIS 3 is not yet there and there is still plenty of time to prepare and migrate.<br \/>\nBut I thought I would give some advice about things that you can keep in mind while working on your plugins to make your life easier when you will have to actually do the migration. It&rsquo;s mostly about making your code prepared for Python 3 and PyQt5.<\/p>\n<h2>Do not use star imports<\/h2>\n<p>Don&rsquo;t do<\/p>\n<pre class=\"lang:default decode:true\">from PyQt4.QtCore import *<\/pre>\n<p>some things have been been moved between different modules and it is easier to rewrite the code if it is known, where classes come from. So instead do<\/p>\n<pre class=\"lang:default decode:true\">from PyQt4.QtCore import (\n    QDate,\n    QTime,\n    QDateTime,\n    QVariant\n)<\/pre>\n<p>IDE&rsquo;s make this task easier.<\/p>\n<h2>Only cast\u00a0to string where required<\/h2>\n<p>One of the things that changed between Python 2 and Python 3 is the handling of strings. Most notably the change in semantics of the type\u00a0<span class=\"lang:default decode:true crayon-inline\">str<\/span>\u00a0. In Python 3 a\u00a0<span class=\"lang:default decode:true crayon-inline\">str<\/span>\u00a0is a string. In Python 2 it is not, instead it is an array of bytes, a real string in Python 2 is <span class=\"lang:default decode:true crayon-inline\">unicode<\/span>\u00a0, the two things can often be used interchangeably, but no longer when you want to handle special characters like \u00e4, \u00f1 or even more modern characters like \u2713 (you didn&rsquo;t know that this is a character? It actually is part of modern character sets). In Python 3 there is also a pure array of bytes. It&rsquo;s called\u00a0<span class=\"lang:default decode:true crayon-inline\">bytes<\/span>\u00a0.<br \/>\nIf you want to get too much trouble, don&rsquo;t do any unrequired extra conversions to\u00a0<span class=\"lang:default decode:true crayon-inline\">unicode<\/span>\u00a0or\u00a0<span class=\"lang:default decode:true crayon-inline\">str<\/span>\u00a0. Often python converts things automatically for you and you don&rsquo;t need to be explicit about it.<br \/>\nIf you know a text will be in a variable<br \/>\ninstead of<\/p>\n<pre class=\"lang:default decode:true\">myWidget.setText(str(my_text))<\/pre>\n<p>use<\/p>\n<pre class=\"lang:default decode:true \">myWidget.setText(my_text)<\/pre>\n<p>&nbsp;<br \/>\nThere will still be situations where you need to be explicit, but in such cases you will get exceptions that tell you about it.<\/p>\n<h2>Write\u00a0unit tests<\/h2>\n<p>If you already have a good code coverage of unit tests you are in a comfortable position. Because you can easily try different tools that help to migrate the code and test the resulting code by running the unit tests in a PyQt5\/Python 3 version of QGIS. This makes trial and error much, much faster than manually testing through the whole plugin again and again and again.<br \/>\nYou will even be able to run the tests on a Python 2 and a Python 3 version of QGIS and maintain a plugin that is compatible with the old and the new world.<\/p>\n<h2>Read more about conversion from Python2 to Python3<\/h2>\n<p><a href=\"https:\/\/python3porting.com\/noconv.html\">https:\/\/python3porting.com\/noconv.html<\/a> and google for it. While reading it, forget about any python version &lt;2.7 or 3.0 &#8211; 3.3. These versions are outdated, need not be supported and just make a developers life harder.<br \/>\n&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>QGIS 3 is not yet there and there is still plenty of time to prepare and migrate. But I thought I would give some advice about things that you can keep in mind while working on your plugins to make your life easier when you will have to actually do [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_themeisle_gutenberg_block_has_review":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[161],"tags":[125],"class_list":["post-2059","post","type-post","status-publish","format-standard","hentry","category-uncategorised","tag-qgis-org"],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":2074,"url":"https:\/\/www.opengis.ch\/fr\/2016\/05\/04\/qgis-qt5-and-python3-migration-current-state\/","url_meta":{"origin":2059,"position":0},"title":"QGIS: Qt5 and Python3 migration, current state","author":"Matthias Kuhn","date":"4 mai 2016","format":false,"excerpt":"Behind the scenes a lot has happened to get ready for Qt5 and Python3. On the same codebase that is becoming the next release QGIS 2.16. This is really a great thing since we can focus work on a single master branch and I'm very happy that we got so\u2026","rel":"","context":"Dans &quot;C++&quot;","block_context":{"text":"C++","link":"https:\/\/www.opengis.ch\/fr\/category\/programming\/cpp\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":3691,"url":"https:\/\/www.opengis.ch\/fr\/2018\/04\/13\/porting-qgis-plugins-to-api-v3-strategy-and-tools\/","url_meta":{"origin":2059,"position":1},"title":"Porting QGIS plugins to API v3 &#8211; Strategy and tools","author":"Marco Bernasocchi","date":"13 avril 2018","format":false,"excerpt":"The Release of QGIS 3.0 was a great success and with the first LTR (3.4) scheduled for release this fall, it is now the perfect time to port your plugins to the new API. QGIS 3.0 is the first major release since September 2013 when QGIS 2.0 was released. During\u2026","rel":"","context":"Dans &quot;Featured&quot;","block_context":{"text":"Featured","link":"https:\/\/www.opengis.ch\/fr\/category\/featured\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2127,"url":"https:\/\/www.opengis.ch\/fr\/2016\/09\/19\/qgis2-compatibility-plugin\/","url_meta":{"origin":2059,"position":2},"title":"QGIS2 compatibility plugin","author":"Marco Bernasocchi","date":"19 septembre 2016","format":false,"excerpt":"Lately I've been spending time porting a bigger plugin from QGIS 2.8 to 3 while maintaining 2.8 compatibility. You can find it at https:\/\/github.com\/opengisch\/qgis2compat\/ and https:\/\/plugins.qgis.org\/plugins\/qgis2compat\/ One code to rule them all. My target was to have to edit the source code as little as possible to simulate a lazy\u2026","rel":"","context":"Dans &quot;PyQt&quot;","block_context":{"text":"PyQt","link":"https:\/\/www.opengis.ch\/fr\/category\/programming\/python\/pyqt\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1668,"url":"https:\/\/www.opengis.ch\/fr\/2016\/09\/07\/using-threads-in-qgis-python-plugins\/","url_meta":{"origin":2059,"position":3},"title":"Using threads in QGIS python plugins","author":"Marco Bernasocchi","date":"7 septembre 2016","format":false,"excerpt":"Here an example on how to work with threads in a consistent and clean manner in QGIS python plugins","rel":"","context":"Dans &quot;Python&quot;","block_context":{"text":"Python","link":"https:\/\/www.opengis.ch\/fr\/category\/programming\/python\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2021,"url":"https:\/\/www.opengis.ch\/fr\/2016\/02\/04\/increasing-the-stability-of-processing-algorithms\/","url_meta":{"origin":2059,"position":4},"title":"Increasing the stability of processing algorithms","author":"Matthias Kuhn","date":"4 f\u00e9vrier 2016","format":false,"excerpt":"Processing just got a new testing framework to improve\u00a0the long-term stability of this important plugin. And you can help to improve it, even if you are not a software developer! This is yet another piece in our never-stopping crusade to improve the stability and quality of the best\u00a0desktop GIS on\u2026","rel":"","context":"Dans &quot;C++&quot;","block_context":{"text":"C++","link":"https:\/\/www.opengis.ch\/fr\/category\/programming\/cpp\/"},"img":{"alt_text":"pr","src":"https:\/\/i0.wp.com\/www.opengis.ch\/wp-content\/uploads\/2016\/02\/pr.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.opengis.ch\/wp-content\/uploads\/2016\/02\/pr.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.opengis.ch\/wp-content\/uploads\/2016\/02\/pr.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/www.opengis.ch\/wp-content\/uploads\/2016\/02\/pr.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":154,"url":"https:\/\/www.opengis.ch\/fr\/2010\/12\/06\/qgis-plugins-starter-plugin\/","url_meta":{"origin":2059,"position":5},"title":"Qgis plugins starter plugin","author":"Marco Bernasocchi","date":"6 d\u00e9cembre 2010","format":false,"excerpt":"Today I published my first QGis Python plugin. It does allow to configure a list of available plugins actions to execute in one click. It is published in pyqgis contributed repository and the source is developed on My GitHub Cheers Marco","rel":"","context":"Dans &quot;GIS&quot;","block_context":{"text":"GIS","link":"https:\/\/www.opengis.ch\/fr\/category\/gis\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"jetpack_shortlink":"https:\/\/wp.me\/pbdBtI-xd","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.opengis.ch\/fr\/wp-json\/wp\/v2\/posts\/2059","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.opengis.ch\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.opengis.ch\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.opengis.ch\/fr\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.opengis.ch\/fr\/wp-json\/wp\/v2\/comments?post=2059"}],"version-history":[{"count":1,"href":"https:\/\/www.opengis.ch\/fr\/wp-json\/wp\/v2\/posts\/2059\/revisions"}],"predecessor-version":[{"id":11144,"href":"https:\/\/www.opengis.ch\/fr\/wp-json\/wp\/v2\/posts\/2059\/revisions\/11144"}],"wp:attachment":[{"href":"https:\/\/www.opengis.ch\/fr\/wp-json\/wp\/v2\/media?parent=2059"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.opengis.ch\/fr\/wp-json\/wp\/v2\/categories?post=2059"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.opengis.ch\/fr\/wp-json\/wp\/v2\/tags?post=2059"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}