analitics

Pages

Tuesday, June 9, 2026

Python Qt : Simple script to install the G'MIC archive to the Krita folder.

Today, this simple script will install the G'MIC archive to the Krita folder:
import sys
import os
import zipfile
import shutil
import subprocess
from PyQt6.QtWidgets import (
    QApplication, QWidget, QPushButton, QFileDialog,
    QVBoxLayout, QLabel, QMessageBox
)

class GMICInstaller(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("GMIC Installer for Krita")

        self.gmic_zip = ""
        self.krita_folder = ""

        layout = QVBoxLayout()

        self.label_zip = QLabel("GMIC archive: Not selected")
        self.label_krita = QLabel("Krita folder: Not selected")

        btn_zip = QPushButton("Select GMIC Archive (.zip)")
        btn_zip.clicked.connect(self.select_gmic_zip)

        btn_krita = QPushButton("Select Krita Folder")
        btn_krita.clicked.connect(self.select_krita_folder)

        btn_install = QPushButton("Install on Krita")
        btn_install.clicked.connect(self.install_gmic)

        layout.addWidget(self.label_zip)
        layout.addWidget(btn_zip)
        layout.addWidget(self.label_krita)
        layout.addWidget(btn_krita)
        layout.addWidget(btn_install)

        self.setLayout(layout)

    def select_gmic_zip(self):
        file, _ = QFileDialog.getOpenFileName(self, "Select GMIC ZIP", "", "ZIP Files (*.zip)")
        if file:
            self.gmic_zip = file
            self.label_zip.setText(f"GMIC archive: {file}")

    def select_krita_folder(self):
        folder = QFileDialog.getExistingDirectory(self, "Select Krita Folder")
        if folder:
            self.krita_folder = folder
            self.label_krita.setText(f"Krita folder: {folder}")

    def install_gmic(self):
        if not self.gmic_zip or not self.krita_folder:
            QMessageBox.warning(self, "Error", "Select both GMIC archive and Krita folder first.")
            return

        # Step 1: Extract GMIC ZIP
        extract_path = os.path.join(os.getcwd(), "gmic_extracted")
        if os.path.exists(extract_path):
            shutil.rmtree(extract_path)
        os.makedirs(extract_path)

        with zipfile.ZipFile(self.gmic_zip, 'r') as zip_ref:
            zip_ref.extractall(extract_path)

        # Step 2: Find GMIC folder inside extracted content
        gmic_folder = None
        for root, dirs, files in os.walk(extract_path):
            if "gmic_krita_qt.dll" in files or "gmic_qt.exe" in files:
                gmic_folder = root
                break

        if not gmic_folder:
            QMessageBox.critical(self, "Error", "GMIC plugin files not found in archive.")
            return

        # Step 3: Find Krita plugin folders
        possible_paths = [
            os.path.join(self.krita_folder, "share", "krita", "pykrita"),
            os.path.join(self.krita_folder, "lib", "krita", "plugins"),
            os.path.join(os.getenv("APPDATA"), "krita", "pykrita")
        ]

        installed = False

        for path in possible_paths:
            if os.path.exists(path):
                try:
                    shutil.copytree(gmic_folder, os.path.join(path, "gmic_qt"), dirs_exist_ok=True)
                    installed = True
                except Exception as e:
                    print("Copy error:", e)

        if not installed:
            QMessageBox.critical(self, "Error", "Could not find a valid Krita plugin folder.")
            return

        # Step 4: Launch Krita
        krita_bin = os.path.join(self.krita_folder, "bin", "krita.exe")
        if os.path.exists(krita_bin):
            subprocess.Popen([krita_bin])
        else:
            QMessageBox.warning(self, "Warning", "GMIC installed, but Krita executable not found.")

        QMessageBox.information(self, "Success", "GMIC successfully installed into Krita!")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = GMICInstaller()
    window.show()
    sys.exit(app.exec())