{"id":1844,"date":"2023-02-05T12:45:30","date_gmt":"2023-02-05T11:45:30","guid":{"rendered":"https:\/\/hannes.enjoys.it\/blog\/?p=1844"},"modified":"2023-02-05T21:26:54","modified_gmt":"2023-02-05T20:26:54","slug":"properly-setting-up-your-qgis-license","status":"publish","type":"post","link":"https:\/\/hannes.enjoys.it\/blog\/2023\/02\/properly-setting-up-your-qgis-license\/","title":{"rendered":"Properly setting up your QGIS license"},"content":{"rendered":"\n<p><a href=\"https:\/\/twitter.com\/pwramsey\/status\/1621602923376705537\">If you want your copy of QGIS display it&#8217;s legal licensing status<\/a>, this is the missing code for you.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"490\" src=\"https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/splash-1-1024x490.jpg\" alt=\"\" class=\"wp-image-1847\" srcset=\"https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/splash-1-1024x490.jpg 1024w, https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/splash-1-300x144.jpg 300w, https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/splash-1-768x367.jpg 768w, https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/splash-1-1536x735.jpg 1536w, https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/splash-1-624x299.jpg 624w, https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/splash-1.jpg 1977w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Copy this in your QGIS Python script editor (<strong>WARNING: DO NOT RUN THIS IN AN IMPORTANT USER PROFILE, I will NOT help you if it breaks something<\/strong>):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">import os\nfrom qgis.core import QgsApplication, QgsSettings\nfrom qgis.PyQt.QtGui import QColor, QImage, QPainter, QPen, QStaticText\nfrom qgis.PyQt.QtWidgets import QMessageBox\n\ndef install_qgis_license():\n    # WARNING: This fucks around with your profiles and stuff!\n    # QgsCustomization is not available from Python so just yolo here and write a fresh file if possible\n    profile_directory = QgsApplication.qgisSettingsDirPath()\n    customization_ini_filepath = profile_directory + \"QGIS\/QGISCUSTOMIZATION3.ini\"\n\n    if os.path.isfile(customization_ini_filepath):\n        # ain't gonna be touchin dat!\n        text = (\n            \"QGISCUSTOMIZATION3.ini EXISTS! UNLICENSED HACKING DETECTED!\\n\"\n            \"Or: Custom license has been installed already...\\n\"\n            \"Anyways, we are not creating a *new* license now ;)\"\n        )\n        messagebox = QMessageBox()\n        messagebox.setText(text);\n        messagebox.exec()\n        return\n\n    # get existing splash image\n    splash_path = QgsApplication.splashPath()  # :\/images\/splash\/\n    splash_image_file = splash_path + \"splash.png\"\n    splash_image = QImage(splash_image_file)\n\n    # paint new splash image\n    new_splash_image = QImage(splash_image)\n    painter = QPainter()\n    painter.begin(new_splash_image)\n\n    # white bold font plz\n    font = QgsApplication.font()\n    font.setBold(True)\n    painter.setFont(font)\n    pen = painter.pen()\n    pen.setColor(QColor(\"white\"))\n    painter.setPen(pen)\n\n    # place text at appropriate location\n    label_text = f\"This QGIS\u00a9\u00ae\u2122 is legally licensed to {os.getlogin()}\"\n    label_text_rect = painter.boundingRect(0, 0, 0, 0, 0, label_text)  # returns new rect that fits text\n    left_offset = new_splash_image.width() - label_text_rect.size().width() - 20\n    painter.drawText(left_offset, 840, label_text)\n\n    painter.end()\n\n    # create license dir if necessary\n    new_splash_dir_path = profile_directory + \"license\"\n    try:\n        os.mkdir(new_splash_dir_path)\n    except FileExistsError:\n        pass\n\n    save_success = new_splash_image.save(new_splash_dir_path + \"\/splash.png\")\n    if save_success:\n        print(f\"Initialized new QGIS license....\")\n    else:\n        print(\"Error on QGIS license initialization, this will get reported!\")\n        return\n\n    # enable license dir for splash image lookup in QGISCUSTOMIZATION3.ini\n    with open(customization_ini_filepath, \"w\") as sink:\n        sink.write(\"[Customization]\\n\")\n        sink.write(f\"splashpath={new_splash_dir_path}\/\")  # must have trailing slash\n\n    # enable loading of QGISCUSTOMIZATION3.ini in user profile\n    QgsSettings().setValue(r\"UI\/Customization\/enabled\", True)\n    \n    print(\"License installed, reboot QGIS to activate!\")\n    messagebox = QMessageBox()\n    messagebox.setText(\"License installed, restart QGIS now to activate!\");\n    messagebox.exec()\n\n#install_qgis_license()<\/code><\/pre>\n\n\n\n<p>Then (if you really want to do it), uncomment the function call in the last line and execute the script. Follow the instructions.<\/p>\n\n\n\n<p>To clean up remove or restore the <code>QGIS\/QGISCUSTOMIZATION3.ini<\/code> file in your profile and remove the <code>license<\/code> directory from your profile, restore the previous value of <code>UI\/Customization\/enabled<\/code> in your profile (just remove the line or disable <em>Settings<\/em> -&gt; <em>Interface Customization<\/em>).<\/p>\n\n\n\n<p>If you want to hate yourself in the future, put it in a file called <code>startup.py<\/code> in <code>QStandardPaths.standardLocations(QStandardPaths.AppDataLocation)<\/code> aka the directory which contains the <code>profiles<\/code> directory itself.<\/p>\n\n\n\n<p>BTW: If you end up with QGIS crashing and lines like these in the error output:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">...<br>Warning: QPaintDevice: Cannot destroy paint device that is being painted<br>QGIS died on signal 11<br>...<\/code><\/pre>\n\n\n\n<p>It is probably not a Qt issue that <em>caused<\/em> the crash. The <code>QPaintDevice<\/code> warning might just be Qt telling you about your painter being an issue during clean up of the actual crash (which might just be a wrong name or indentation somewhere in your code, <em>cough<\/em>).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you want your copy of QGIS display it&#8217;s legal licensing status, this is the missing code for you. Copy this in your QGIS Python script editor (WARNING: DO NOT RUN THIS IN AN IMPORTANT USER PROFILE, I will NOT help you if it breaks something): Then (if you really want to do it), uncomment [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[59,29,43,31,34],"tags":[],"class_list":["post-1844","post","type-post","status-publish","format-standard","hentry","category-funny","category-gis","category-python","category-qgis","category-wtf"],"_links":{"self":[{"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/posts\/1844","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/comments?post=1844"}],"version-history":[{"count":4,"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/posts\/1844\/revisions"}],"predecessor-version":[{"id":1851,"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/posts\/1844\/revisions\/1851"}],"wp:attachment":[{"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/media?parent=1844"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/categories?post=1844"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/tags?post=1844"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}