2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

QtAdvent Calendar 2024

Day 9

PSD ファイルをロードする Qt 6 のモジュールを作りました

Last updated at Posted at 2024-12-08

はじめに

この記事は Qt Advent Calendar 2024 6日目の記事です。

昨日は一個空いていますね。Qt が好きな人がいましたら埋めていただければと思います。

また、この記事は Slint Advent Calendar 2024 6日目の記事でもあります。

昨日は @hermit4 さんの Slint言語入門(2) でした。

.slint は元々 QtQuick や Qt for MCU を開発していた開発者が設計/開発をしているだけあって、QML よりもいいところがたくさんありますね。


今日は、PSD を読み込んで Qt で表示するモジュール(ライブラリやそれを利用したサンプル、テスト)を開発したので、それを紹介します。

QtPsd モジュール

モチベーション

2010頃からなにかの UI を実装することが増えてきて、デザインは PSD ファイルでもらうことが多かったという記憶があります。(当時はまだ Figma とかはなく、Sketch が使われはじめたくらいだった気がします。)

その頃から、このデザインを自動で QML に変換できないかなと思って、ことあるごとに PSD の仕様 を眺めていました。

その後、Qt Design StudioPhotoshop のプラグイン を提供し、Photoshop から QML への変換が可能になりました。

image.png

が、しかし、上記のワークフローは基本的にデザイナーさんが担当するもので、プログラマーの私は「これじゃないな」と感じていました。

PSD ファイルをもらったプログラマーが、自分の思った感じの QML を出力できるといいなと思い、PSD をロードできるペイントソフト KritaQML のエクスポートまわりのコード を自分用に魔改造したこともありました。

image.png

それも物足りなかったので、もう少しちゃんと PSD を解析して、もう少しちゃんと QML を生成できるようにしたいと思っていました。

先月末にパシフィコ横浜で開催された EdgeTech+ 2024 に会社として出展することにして、そのためにデモ機をいくつか準備する必要があったので、この期を逃すわけにはいくまいと開発をしたのが、以下で公開をしている Qt 向けの PSD モジュールになります。

できること

  • PSD ファイルを解析して、レイヤー構造とレイヤーの様々な情報を Qt で扱いやすい形で提供します
  • プレビュー用のサンプルアプリがあります
    • QtQuick の形式でエクスポートができます

image.png

上記の PSD は Qt Design Studio のチュートリアルかウェビナー向けに公開 されているものです。

Qt Quick にエクスポートすると以下のようになります。
この PSD の場合、オリジナルの再現度はそこまで高くはありません。

image.png

EdgeTech+ 向けのデモを作りました

コインパーキングの精算機の UI

image.png

コインパーキングUI.psdQt Quick のコード に変換し、雑に ロジックを記載した以下の qml を追加しました。

main.qml
import QtQuick
import "ui"

Window {
    id: root
    width: ui.width
    height: ui.height
    visible: true
    title: currentPage
    property int currentPage: 0
    MainWindow {
        id: ui
        welcome.visible: root.currentPage === 0
        welcome.onClicked: root.currentPage++

        header.visible: root.currentPage > 0
        cancel.onClicked: root.currentPage = 0
        footer.visible: root.currentPage > 0

        parkingSlot.visible: root.currentPage === 1
        parkingSlot.onVisibleChanged: {
            digit1.text = ''
            digit10.text = ''
        }

        accept.onClicked: root.currentPage++
        key0.onClicked: keyClicked('0')
        key1.onClicked: keyClicked('1')
        key2.onClicked: keyClicked('2')
        key3.onClicked: keyClicked('3')
        key4.onClicked: keyClicked('4')
        key5.onClicked: keyClicked('5')
        key6.onClicked: keyClicked('6')
        key7.onClicked: keyClicked('7')
        key8.onClicked: keyClicked('8')
        key9.onClicked: keyClicked('9')
        keyC.onClicked: {
            digit1.text = ''
            digit10.text = ''
        }
        function keyClicked(key) {
            if (digit1.text === '') {
                digit1.text = key
            } else if (digit10.text === '') {
                digit10.text = digit1.text
                digit1.text = key
            }
        }

        payment.visible: root.currentPage === 2
        cash.onClicked: root.currentPage++
        card.onClicked: root.currentPage++
        ic.onClicked: root.currentPage++
        pay.onClicked: root.currentPage++

        goodBye.visible: root.currentPage === 3
        goodBye.onClicked: root.currentPage = 0

        Timer {
            repeat: false
            running: ui.goodBye.visible
            interval: 3000
            onTriggered: root.currentPage = 0
        }
    }
}

parkinglot.gif

元の PSD を完全に再現はできていないのですが、デモとしては十分な出来です。

標準的な Qt 以外の対応

同じデザイン(PSD)から、色々なフレームワークで UI を作ることにもチャレンジした結果、以下のバリエーションのサンプルアプリを生成することができました。

QtQuick(GPU なしでも動く版)

Toradex Verdin AM62 Solo で meta-qt6 を動かしてみた の環境で動かすと以下のようになります。

carpark-verdin-am62.gif

Slint

.slint 形式でもエクスポートできるように対応しました。

任意の解像度に拡大縮小をしてエクスポートができるようにもしたので、picopico2 で動く Slint のアプリケーションも作成しました。

Flutter(Experimental)

Flutter の対応も進めているところです。

投票所の投票端末のデモ

ちょうど準備期間に選挙があったのと、投票所で文字を書くのが面倒くさかったので、
タッチで投票できる感じのデモを作ってみました。

votingmachine.gif

PSD はこれ で、Slint 向けにエクスポートしたものが、以下のものです。

先日の Raspberry Pi 5 で slint を動かす で動かした UI は、実はこうやって作ったので、ソースコードが手書きに比べて構造化されていない状態でした。

現在のステータス

とりあえず公開はしましたが、まだまだアルファ版という感じで未対応の部分やバグがたくさんあります。

大きく分けて、以下の点をこれから改善していきたいです。

様々な PSD を正しく扱えるようにする

のサンプルPSDをすべてちゃんとパースできるようにしたいです。

Qt の API を改善する

とりあえず動いているけれど、理想の設計や実装からはかけ離れているところが多いので、これから改善していきたいです。

エクスポートできるフレームワークの種類を増やす

  • Qt Widgets
  • その他の宣言型 UI フレームワーク

サンプルアプリを増やす

謝辞

このプロジェクトの開発にあたり、フリーランスの日高隆博さんにたくさん協力をしていただきました。

この場を借りて御礼を伝えたいと思います。

おわりに

今回は PSD ファイルをロードしてパースする Qt 向けのモジュールの紹介でした。

Qt や PSD や、アプリケーション開発のワークフローに興味がある方がいましたら、是非開発に参加して、より効率よく GUI の開発ができるような未来を作りましょう。

明日は、Slint の方は @hermit4 さんが何かを書いてくれるようです。
Qt の方は未定ですね。

お楽しみに!

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?