ジャンル不定の日記です。

サブPC用にマウス買おうと思ったんだが・・・

サブPC用にマウス買おうと思ったんだが、
サブPCは手元からちょっと右の方に入力機器を置いているんで、距離があるので普通のマウスじゃなくてトラックボールが良い。
今使ってるのはロジクールのM570。



現行製品はM570tだが、ほぼ同じものらしく、M570はボタンの耐久性に問題があるんだよね。
実はサブPC用のM570は今ので2個目なんだが、ボタンの反応がおかしいので買い替えたいというわけ。

この手の無線トラックボールでは今でもロジクールM570が定番のようなんだが、他メーカーも探すことに。
エレコム: M-XT1DR,M-XT2DR
サンワサプライ: MA-WTB43
辺りが候補ぽい。

あと、メーカーサイトに載ってないんだが、サンワサプライの400-MA061って製品がサンワダイレクトで売ってて、
スペック見た感じはMA-WTB43とほぼ同じで、他の候補製品が実売5000円前後なのに400-MA061は2,980円でちょい安い。

ロジクールのM570チルトホイールはついてなく、サンワサプライの製品もついてないぽいが、エレコムの2製品はチルトホイールつき。
誤操作の原因になるから、チルトホイールとか多ボタンはマイナス要素。
横にボタンとかつけずに、ホイール込み3ボタンのマウスが良いんだが、余計なのついてる製品ばっかで困る・・・


ロジクールM570で問題のボタン耐久性だが、他メーカーもオムロンのボタンだろうから結局壊れるだろうね。
まあ、とりあえずM570以外も試してみたいからサンワダイレクトで400-MA061を購入しようかな・・・


という方向だったんだが、M570のボタンを自力交換して修理する人が結構居るようなので、
自分もマウス購入前にオムロンのスイッチを購入して修理を試みることにした。

自力修理をしている人の情報を見ると、オムロンD2F-01Fってスイッチを使ってる人が多いようなんだが、
互換品のD2FC-F-7Nの方が安かったんで、それにした。



D2FC-F-7Nは中華製でD2F-01Fは国産でD2F-01Fの方が高品質とかって説もあるようなんだが、D2FC-F-7Nの方がメーカー公表スペックが良いとか・・・
まあ、耐久力は期待してない。
他のマウスでもこのスイッチが使われていることが多いようで、1マウスの修理に2個使うとして6個なら3マウスの修理ができるね。

M570のスイッチ交換は、このスイッチを外すのが結構難しいぽい。
うまく修理できるといいが・・・


ちなみに、今使ってるメインPCのマウスはロジクールM525。
このマウスは今のところ左右ボタンは問題ないと思うんだが、購入当初からチルトホイールの誤反応が多い。
チルトホイールつき自体敬遠するんだが、このマウスのチルト、ゆるゆるで特に反応しやすいと思う。
サイドボタンはついてないので、再度の誤クリックはない。
あと、購入時に候補の中からできるだけ大きい物を選んだんだが、全然小さすぎ。
小さいマウスは手にフィットしない状態で使うから手痛める。
M570とかトラックボール系は良い大きさしてる。

とりあえずのFeedリーダー作った

ここ数日、Feedのニュースを表示するPlasmoidがPlasma5にしたら無くなっちゃったから自分で作っちゃおうと思ってQMLを勉強していたが、とりあえずの物を作った。


ダウンロード

モジュールはQtリファレンスのバージョンを指定してimportしてあるんで、Archとか最新版がインストールされそうな環境じゃないと動かないかも。
$ plasmapkg2 -i ディレクトリ
ってやるとインストールされて[Add Widgets...]から設置できる。
-iじゃなくて-uで更新。

$ plasmapkg2 -r com.example.feed
でアンインストール。

[内容]
RSS1.0 RSS2.0 Atom いずれかのFeedのURLをPlasmoidの設定から登録すると60分間隔で更新する。
Feedの構造によっては処理できないものもあるかもです。

現時点での問題は、
設定変更時にイベント処理させる方法がわからないので、設定変更後に次回取得まで待つかKDE再起動(ログアウト)しないと更新されない。
ListViewのサイズを設定していないので長いタイトルは横にはみ出すぽい。


↓コード(修正しているので実物と違っています)

metadata.desktop

[Desktop Entry]
Name=Feed Reader
ServiceTypes=Plasma/Applet
Type=Service
X-KDE-PluginInfo-Author=My Name
X-KDE-PluginInfo-Email=mail@example.com
X-KDE-PluginInfo-Name=com.example.feed
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-Version=1.0
X-KDE-PluginInfo-Website=http://example.com/
X-Plasma-API=declarativeappletscript
X-Plasma-MainScript=ui/main.qml


contents/ui/main.qm (メインUI)
import QtQuick 2.5
import QtQml 2.2
import org.kde.plasma.plasmoid 2.0
import "script.js" as JavaScript

ListView{
property string feed: plasmoid.configuration.feed;
anchors.fill:parent
ListModel{id:model}
model:model
delegate:Text{
color:"blue"
text:title
MouseArea{
anchors.fill:parent
cursorShape:Qt.PointingHandCursor
onClicked:Qt.openUrlExternally(url)
}
}
Timer{
id:timer
repeat:true
interval:60*60*1000
onTriggered:listUpdate()
}
Component.onCompleted:{
timer.start();
listUpdate();
}
function listUpdate(){
if(!feed.match(/^https?:/)) return;
JavaScript.FeedGet([feed],function(list){
model.clear();
for(var i=0;i<list.length;i++){
model.append(list[i]);
}
});
}
}

contents/ui/configGeneral.qml (設定画面)
import QtQuick 2.0
import QtQuick.Controls 1.4

Item {
property alias cfg_feed:feed.text
TextField{
id:feed
}
}

contents/config/config.qml (設定画面のカテゴリ)
import org.kde.plasma.configuration 2.0

ConfigModel{
ConfigCategory{
name: "General"
icon: "plasma"
source: "configGeneral.qml"
}
}

contents/config/main.xml (設定ファイル)
<?xml version="1.0" encoding="UTF-8"?>
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
<kcfgfile name=""/>
<group name="General">
<entry name="feed" type="String">
<default></default>
</entry>
</group>
</kcfg>


contents/code/script.js
var list=[];
var exist=[];
function HttpGet(url,cb){
var http=new XMLHttpRequest();
http.open("GET",url);
http.onreadystatechange=function(){
if(http.readyState==4){
cb(http.responseText);
}
}
http.send();
}
function FeedGet(url,cb){
for(var i=0;i<url.length;i++){
(function(i){
HttpGet(url[i],function(file){
if(file.match(/<feed\W/)){
ParseAtom(file);
}else{
ParseRss(file);
}
list=list.sort(function(a,b){
if(exist[a.url]<exist[b.url]) return 1;
if(exist[a.url]>exist[b.url]) return -1;
return 0;
});
if(i==url.length-1) cb(list);
});
})(i);
}
}
function ParseAtom(file){
var item=file.match(/<entry\W[\s\S]*?<\/entry>/g);
for(var i=0;i<item.length;i++){
var url="";
var title="";
var desc="";
var date=new Date();
if(item[i].match(/<link [^>]*href\s*=[\s"']*([^\s"'>]*)/)) url=RegExp.$1;
if(item[i].match(/<title[^>]*>([\s\S]*?)<\/title>/)) title=RegExp.$1;
if(item[i].match(/<summary[^>]*>([\s\S]*?)<\/summary>/)) desc=RegExp.$1;
if(item[i].match(/<updated[^>]*>([\s\S]*?)<\/updated>/)) date=new Date(RegExp.$1);
if(!exist[url]){
url=HtmlEscapeU(url);
title=HtmlEscapeU(title);
desc=HtmlEscapeU(desc);
exist[url]=date.getTime();
list.push({"url":url,"title":title,"desc":desc,"date":date.toISOString()});
}
}
}
function ParseRss(file){
var item=file.match(/<item\W[\s\S]*?<\/item>/g);
for(var i=0;i<item.length;i++){
var url="";
var title="";
var desc="";
var date=new Date();
if(item[i].match(/<link[^>]*>([\s\S]*?)<\/link>/)) url=RegExp.$1;
if(item[i].match(/<title[^>]*>([\s\S]*?)<\/title>/)) title=RegExp.$1;
if(item[i].match(/<description[^>]*>([\s\S]*?)<\/description>/)) desc=RegExp.$1;
if(item[i].match(/<dc:date[^>]*>([\s\S]*?)<\/dc:date>/)) date=new Date(RegExp.$1);
if(!exist[url]){
url=HtmlEscapeU(url);
title=HtmlEscapeU(title);
desc=HtmlEscapeU(desc);
exist[url]=date.getTime();
list.push({"url":url,"title":title,"desc":desc,"date":date.toISOString()});
}
}
}
function HtmlEscapeU(str){
str=str.replace(/&#(\d+);/g,function(m,$1){return String.fromCharCode($1);});
str=str.replace(/&quot;/g,'"');
str=str.replace(/&amp;/g,'&');
return str;
}
qmlsceneコマンドで.qmlを実行する場合は.jsのimportはパス指定しないと.qmlと同じディレクトリだが、Plasmoidとしてインストールした場合はcodeディレクトリがimportされるぽい。


JavaScriptのコードはFeedのURLを配列で受け取って複数Feedを合成するように作ってあるんだが、
KDE4時代も元々1ウィジェット1Feedで使ってたし、設定UI作るのめんどいから1Feedしか登録できないようにした。

タイトルと記事URL以外に、要約と日付も取得しているんだが表示してない。
ツールチップか何かで表示しようか考えてパース処理は作ったんだが。

データの保存は当初JavaScriptのlocalStorage(DOMストレージ)が使えると思ってたんだが、QMLでは無理らしい。
QtにlocalStorageという機能があるんだが、これはWeb SQL Database相当のもので、Sqliteクエリ投げる感じのやつ。


設定画面で[適用]ボタン押した時に処理する方法がマジわかんない・・・

Plasmoidの設定でハマってる・・・

引き続き、QMLの勉強中で、RSSやAtom等を取得してリスト表示するのは概ね出来そうなんだが、Plasmoidの設定関連でハマってる。
これはQtQuickとは別でKDEの情報探さないとダメみたいね。
Qtのリファレンス等の情報も不満だが、KDEの情報はもっと調べにくい。

/usr/share/plasma/plasmoids/ 以下にあるPlasmoidのコード参考にしたりとかして、
設定値を取得することはできたんだが、[適用]ボタン押した時にイベント駆動で処理する方法がわからない・・・
とりあえず、現時点でわかった情報。


contents/ui/main.qml
以外に、
contents/config/config.qml
contents/config/main.xml
contents/ui/xxxx.qml
が必要ぽい。

contents/config/config.qml
import org.kde.plasma.configuration 2.0

ConfigModel{
    ConfigCategory{
        name: "General"
        icon: "plasma"
        source: "configGeneral.qml"
    }
}
Plasmoidの設定が呼びだされた場合は、このファイルに従って設定画面のカテゴリが追加される。
この場合、[General]カテゴリが追加され、sourceで指定した contents/ui/configGeneral.qml が[General]カテゴリの設定画面になる。

contents/ui/configGeneral.qml
import QtQuick 2.0
import QtQuick.Controls 1.4

Item {
    property alias cfg_tf: tf.text
    TextField{
       id:tf
    }
}
これでTextFieldが一個だけの設定画面になる。
TextFieldのidがtfなのでtf.textが文字列となるが、エイリアスで cfg_ で始まるプロパティと同一にする必要があるぽい。

contents/config/main.xml
<?xml version="1.0" encoding="UTF-8"?>
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
      http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
  <kcfgfile name=""/>
  <group name="General">
    <entry name="tf" type="String">
      <default>test</default>
    </entry>
  </group>
</kcfg>
この.xmlファイルが設定ファイルになるぽい。
ファイルがなくてもエラーにならないが、再起動すると消える。
ここで<entry>属性のnameが"tf"となっているが、これが設定画面用.qmlのcfg_tfの値になるぽい。
configGeneral.qmlのTextFieldの値ととcfg_tfをaliasにしているので、TextFieldを変更すると保存される模様。

contents/ui/main.qml
import QtQuick 2.0
import org.kde.plasma.plasmoid 2.0

Column{
    id:root
    width:640
    height:480
    property string tf: plasmoid.configuration.tf;
    Text{
       text:tf
    }
}
いつものmain.qmlだが、org.kde.plasma.plasmoidをimportしている。
plasmoid.configuration.tf で設定値が取得できる模様。
ただし、[適用]ボタン押さなくてもすぐに反映しちゃうぽい。


で、[適用]ボタンを押した時にmain.qmlで処理したいんだが、その方法がわからない・・・

QML勉強中(外部.jsの利用)

引き続き、QMLの勉強中。
.qmlファイル中にJavaScriptコード書いてクロスドメイン制約無しでXMLHttpRequestが使えることはわかったが、
設定画面はmain.qmlと別ファイルになるんで、JavaScriptは外部ファイルにして共有したほうが良さそう。
というわけで、.jsのimportをやってみた。


js.js
function HttpGet(url,cb){
    var http=new XMLHttpRequest();
    http.open("GET",url);
    http.onreadystatechange=function(){
        if(http.readyState==4){
            cb(http.responseText);
        }
    }
    http.send();
}
置き場所はmain.qmlと同じuiディレクトリ下にしたが、パス指定どころかURL指定でもimportできるようなんで都合のいい場所で良いぽい。
XMLHttpRequestでレスポンスを取得するfunctionだが、別ファイル化するのだから他も使えるように、.js側でUIの変更は行わずにコールバックで.qmlの方でUI変更を行う感じにした。


main.qml
import QtQuick 2.5
import QtQuick.Controls 1.4
import "js.js" as JavaScript
 
Column{
    property var url:"http://jvn.jp/rss/jvn.rdf"
    width:640
    height:480
    Text{
        id:tv
    }
    Button{
        text: "Button"
        onClicked:JavaScript.HttpGet("http://example.com/",function(res){tv.text=http.responseText;})
    }
    Component.onCompleted:JavaScript.HttpGet(url,function(res){tv.text=res;})
}
importのasで指定した名前がオブジェクトになって、その下にfunctionがある感じになる。
ファイル名のみを指定した場合はmain.qmlと同じディレクトリ、つまりui/js.jsをimportすることになるが、/を含めてでパス指定もできる。
2番目の引数でコールバックの無名関数を渡してmain.qml側でUI操作をするように改造した。


これで動いた。
というわけで、目的のFeedリーダーはもうすぐ作れそうだ。

QML勉強中(Plasmoidの設定)

引き続き、QMLの勉強中。
RSS等のニュース用Feedリーダーを作ろうとしているが、Feedアドレスの設定とかをPlasmoidの設定ボタンから行いたいが、今回はそれ。


Plasmoidの設定ボタンからのアクションを作るには、QTのリファレンス見ても書いて無いようで、KDEのリファレンス見ないとダメぽい。
KDEのリファレンスは発見するのも難しい状況なんだが、とりあえず動いた。


今までは、

metadata.desktop

contents/ui/main.qml
の2ファイルだけ作ってたが、新たに、
contents/config/config.qml
が必要。


config.qml
import org.kde.plasma.configuration 2.0

ConfigModel{
    ConfigCategory{
        name: "General"
        icon: "plasma"
        source: "main.qml"
    }
}
config.qml では、org.kde.plasma.configuration をimportして、
ConfigModelとConfigCategoryを定義すればいいぽい。

この config.qml を用意しておくと、Plasmoidの設定ボタンで設定画面が出てくるようになり、
[General]カテゴリに ui/main.qml で作ったUIが表示される。

今回はPlasmoidの設定ボタンのテスト目的なんで、設定用のUIは作らずに作成済みの main.qml を利用した。
実際には設定用の.qmlを用意して、JavaScriptのlocalStorageを利用して設定の保存と読み込みを行えば良いのかな?

あと、qmlsceneコマンドで.qmlを実行してもウインドウ表示されるだけでPlasmoidの設定ボタンは出てこないから、plasmapkg2コマンドでインストールする必要があるが、
plasmapkg2でインストールしちゃうとKDE再起動しないと再インストールが反映しなくなっちゃう。
config.qml のテストはqmlsceneでテストしておいて、全部完成してからplasmapkg2でインストールって感じにしないとダメだな。
最終的に一発勝負wこの仕様どうにかならんの?w


ここまでで得た知識で、目的の実現ができそうだな。
URLにジャンプするリンクの表示がまだか。TextにHTMLタグが使えるとか見た気がするが・・・

QML勉強中 (JavaScript連携編)

今日も引き続き、QMLの勉強中。
前回まででListViewを表示してJavaScriptで更新するのができたが、今回はクロスドメイン制約無しでXMLHttpRequestが使えるか?


main.qml
import QtQuick 2.5
import QtQuick.Controls 1.4
 
Column{
    width:640
    height:480
    Text{
        id:tv
    }
    Button{
        text: "Button"
        onClicked:(function(){
            var http=new XMLHttpRequest();
            http.open("GET","http://example.com");
            http.onreadystatechange=function(){
                if(http.readyState==4){
                    tv.text=http.responseText;
                }
            }
            http.send();
        })()
    }
}
TextとButtonを配置して、ボタンが押されたらXMLHttpRequestで取ってきたレスポンスを表示。
ドメイン制約はないようで、問題なくHTTP通信ができた。


Plasma5にして無くなった、ニュース見出しを表示するRSSリーダーの代わりを作ろうとしているんで、
あとはJavaScriptのコード書くだけでとりあえずできそう。

Plasma Widgetの設定ボタンから取ってくるFeedのアドレス設定とかできるようにしたいから、その辺ちょっと調べてみる。

QML勉強中 (JavaScript連携編)

引き続き、QMLの勉強中。
今回は、前回ListViewを表示してみたが、ListViewをJavaScriptで動的に更新してみる実験。

main.qml
import QtQuick 2.5
import QtQuick.Controls 1.4
 
Column{
    ListView{
        id:lv;
        ListModel{
            id:model
            ListElement{
                tx:"1"
            }
            ListElement{
                tx:"2"
            }
            ListElement{
                tx:"3"
            }
        }
        width:100
        height:200
        model:model
        delegate:Text{text:tx}
    }
    Button{
        text: "Button"
        onClicked:(function(){
            model.clear();
            model.append({"tx":"append1"});
            model.append({"tx":"append2"});
        })()
    }
}
前回は import QtQuick 2.0 としていたが、適切なバージョン番号がわからないのでAPIリファレンスのバージョン(最新?)に合わせることにした。
Arch Linux環境なので最新版がすぐ来るはずだし。
古い環境の場合はバージョン落とす必要があるかも。

今回はColumn型とButton型のオブジェクトを使用したが、Buttonを使うには QtQuick.Controls をimportする必要がある。

ボタンを押すとリストを更新する実験なんだが、
QMLの最上位にはオブジェクトは一個しか置けないぽくて、最上位にListViewとButtonを並べるのはダメみたい。
Column型は、子要素を縦方向に順番に並べてくれる。

ListViewは前回からちょっと省略した感じだが、ListViewには高さが無いのかな?
heightを指定しないとButtonと重なっちゃうようだったんでサイズ指定した。


Buttonは、onClickedでQMLのメソッドや自分で定義したJavaScriptのfunctionをクリック時に実行できる。
model.clear()でリストのデータを消去して、appendで新しく追加。
appendに渡す引数はJavaScriptのオブジェクト(ハッシュ)ぽい。

再利用もしない簡単な処理なんで無名関数を書いたが、当然だが名前付き関数を実行することもできる。
名前付きのfunctionを別の場所に定義する場合は、Button自身と親要素のColumn以外で定義した場合は id.func() の様にid指定で実行する必要がある。
ルート要素は一つしか置けないようで、Columnの外側には別のオブジェクトを置くこともできないし、JavaScriptのfunctionを置くこともできないぽい。
複数オブジェクトで同じfunctionを利用するような場合は、.jsを別ファイルにしてimportした方が自然かね。


QMLとJavaScriptの連携ができたんで、次はクロスドメイン制約無しでXMLHttpRequestができるかどうかを試してみる。
それができればJavaScriptでパース処理書くだけで目的のFeedリーダーが作れそう。

だが、まだPlasmoidの設定ボタン押した時の処理の書き方がわからないな。
できれば、設定ボタン経由でFeedのアドレス設定ができるようにしたいし。

QML勉強中 (ListView編)

引き続き、QMLの勉強中。

Plasma5にしてRSSニュースリーダーがないから自分で作っちゃおうと思ってるわけなんだが、
RSS(等のFeed)をHTTPで取ってきてリスト表示って感じになると思うんで、リストの表示方法。
ListViewってのを使えばリストが表示できるようなんだが、書き方がたくさんあってリファレンスが難解・・・
まあ、なんとなくわかった。

main.qml
import QtQuick 2.0

ListView{
    ListModel{
        id:model
    ListElement{
            l:"1"
            r:1
        }
    ListElement{
            l:"2"
            r:2
        }
    ListElement{
            l:"3"
            r:3
        }
    }
    Component{
        id:component
        Row{
            spacing:10
            Text{text:l}
            Text{text:r*2}
        }
    }
    model:model
    delegate:component
}
こんな感じ。

完成するまでインストールはしない方が良さそうなんで、
$ qmlscene main.qml
でテスト実行。

ListViewにmodelとdelegateを指定する必要がある様で、
modelがリストのデータ。
delegateがカラムの表示方法定義。
って感じなのかな。

delegateにはComponent型のオブジェクトをidで渡してる。
Component型はただ定義してidを使って再利用するためのオブジェクトぽい。
なので、これはComponent型のオブジェクトを別途定義せずとも、delegateの指定部分に直接Row型オブジェクトを書いちゃってもいいみたい。

Row型は子を水平方向に並べて表示するオブジェクトで、spacingでカラム間を空けられるのでリストの行に良さそう。

modelに指定するのはmodel型オブジェクトのようで、テキストを表示するリストの場合はListModelが基本ぽいんだが、
オブジェクトではなく数値を渡すなんてこともでき、数値を指定した場合は指定数分の行ができ、delegateで指定したComponentの方で、indexって名前の変数でカウントできるぽい。

今回はListModelの子のListElementでlとrを定義して、Componentの方でrは*2してる。
lの方は"で囲んで文字型みたいにしたが、定義の際に型を指定しなければ文字型と数値型は同じぽい。
lの方を*2した場合も*2された。


目的のことをやるにはリストを動的更新しなければいけないが、
QML内にJavaScriptを書けるようなんで、JavaScriptからmodelにclear()とかappend()できるぽい。
なので、次はJavaScript関連をやってみる。

QMLのリファレンスとか

QMLのリファレンスは
http://doc.qt.io/qt-5/reference-overview.html
が公式でいいのかな?
見て勉強中。


ちょっとわかりにくい感じで理解するのに苦戦してるが、
QMLの中にJavaScriptのfunctionを書いてイベント駆動で呼び出してGUIに変更加えることができるらしい。

JavaScriptが使えるなら、localStorageとか使えると思うから、ほとんどの場合ファイルアクセスとかはせずにlocalStorageで足りそうかな。
というか、APIリファレンス見てファイルアクセス関連の機能は見当たらないような・・・

通信はXMLHttpRequestがクロスドメイン制約無しで使えるのかな?
XMLHttpRequestとlocalStorageが使えれば、ほとんどのことはQML+JavaScriptで足りそうだな。
APIにはWebSocketとかWebViewなんかがあるようなんだが、HTTP通信とかSocketなんかは見当たらない。


JavaScriptならWebで使うから、
JavaScriptのfunctionをQMLから呼び出して、JavaScript経由でGUIに変更を加える。
ってことができたら、いろいろすんなり作れそうだな。

Plasmoidの作り方

メイン環境をPlasma5に代えて困ったことの一つに、RSSでニュースの見出し並べる奴が無くなっちゃったんだよね・・・
Plasma内で配信されてる奴も確認して、RSSリーダー一つ発見したが、見出し並べるやつじゃなくてブラウザ的なやつだったんで違う。

で、自分でPlasmoid作れないか?
と考えて調べた。

情報が少なくて探すのに苦労したが、
QMLってスクリプト言語でGUIアプリが作れて、結構簡単そう。


作り方

  • ディレクトリを作る
  • metadata.desktop を作る
  • contents/ui/main.qml を作る
最低限必要なのは、テキストファイル2つだけ。
ディレクトリを指定してインストールするので、専用のディレクトリが必要で、その中に2つのファイルを作る。
main.qmの場所は指定できそうなんでuiディレクトリじゃなくても良さそうだが、 contentsの下である必要がありそう。

metadata.desktop
[Desktop Entry]
Name=Hello World
ServiceTypes=Plasma/Applet
Type=Service
X-KDE-PluginInfo-Author=My Name
X-KDE-PluginInfo-Email=mail@example.com
X-KDE-PluginInfo-Name=com.example.hello
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-Version=1.0
X-KDE-PluginInfo-Website=http://example.com/
X-Plasma-API=declarativeappletscript
X-Plasma-MainScript=ui/main.qml
普通の.desktopショートカットと似たようなもんかな?
X-Plasma-MainScriptでmain.qmlの場所指定と、X-KDE-PluginInfo-Nameでパッケージ名の指定が必要な感じかな。X-Plasma-APIも必須かも。
まあ、とりあえず上記な感じで作っとけば良さそう。
X-KDE-PluginInfo-Nameで指定してるパッケージ名はJavaなんかと同じでドメインの反対みたいにして重複しないようにする感じだね。
アイコンなんかも.desktopで指定できるぽい。

main.qml
import QtQuick 2.0

Item {
    Text {
        text: "Hello World!";
    }
}
文字表示だけ。


インストール

$ plasmapkg2 -i 作成したディレクトリ
ユーザー権限でインストールできる。
これでPlasmaの[Add Widget]で一覧に表示されるようになる。


アンインストール

$ plasmapkg2 -r パッケージ名
こっちもユーザー権限で。
パッケージ名がわからない場合は -l オプションで一覧が表示できる。



まだ文字表示だけだが、QMLでのアプリの作り方とかAPIリファレンスとか探せば良さそうかな。
QMLはUI関連だけで、処理はCとかで作るとか見たが、Perlと連携とかはできないだろうか。