KDE4 Plasmaデスクトップ。 DIYプラスモイド

画像 バージョン4.x以降、KDesktop、Kicker、およびSuperKarambaは長年にわたって実証されていたものの代わりにPlasma Desktopに加わりましたが、道徳的に時代遅れです(もちろん、意見は分かれます)。 このフレームワークは、デスクトップ(少なくとも目に見える部分)をウィジェットまたはプラスモイドのコレクションとして提示します。 ある時点でいくつかの空き時間を獲得したので、Plasma SDKを少し整理し、その時点でデスクトップに本当に欠けていた機能を実装することにしました。 この機能は、追加のアプリケーションを使用せずにエントリをLiveJournalに送信する機能です。 これは、デスクトップに組み込まれた一種のミニクライアントです。 「それは素晴らしいことだ」と私は考え、関心のある主題分野に取り組むことから始めました。

以下に説明するすべてを実装するには、システムに実際にKDE4と次のインストール済みパッケージが含まれている必要があります:kdesdk、kdebase-devel、kdelibs-devel、cmake。 ディストリビューションによっては、パッケージの名前が若干異なる場合があります(Fedora Coreの名前を付けます)が、一般的な意味は明確だと思います。

まず、Plasmidはバイナリであり、スクリプト化されています。 ためらうことなく、私は心の近くで「プラス」を使用し、それに応じて.so(共有オブジェクト)モジュールであるバイナリウィジェット、つまり動的にロードされるライブラリを作成することにしました。 基本フレームワークは次のようになります。

#ifndef __lj_plasmoid_h
#define __lj_plasmoid_h

#include <Plasma/Applet>

class QSizeF;
class LjPlasmoid : public Plasma::Applet
{
Q_OBJECT
public :

LjPlasmoid(QObject *parent, const QVariantList &args);
~LjPlasmoid();

void paintInterface(QPainter *painter, const QStyleOptionGraphicsItem *option, const QRect& contentsRect);
void init();

};

#endif


* This source code was highlighted with Source Code Highlighter .
#ifndef __lj_plasmoid_h
#define __lj_plasmoid_h

#include <Plasma/Applet>

class QSizeF;
class LjPlasmoid : public Plasma::Applet
{
Q_OBJECT
public :

LjPlasmoid(QObject *parent, const QVariantList &args);
~LjPlasmoid();

void paintInterface(QPainter *painter, const QStyleOptionGraphicsItem *option, const QRect& contentsRect);
void init();

};

#endif


* This source code was highlighted with Source Code Highlighter .
#ifndef __lj_plasmoid_h
#define __lj_plasmoid_h

#include <Plasma/Applet>

class QSizeF;
class LjPlasmoid : public Plasma::Applet
{
Q_OBJECT
public :

LjPlasmoid(QObject *parent, const QVariantList &args);
~LjPlasmoid();

void paintInterface(QPainter *painter, const QStyleOptionGraphicsItem *option, const QRect& contentsRect);
void init();

};

#endif


* This source code was highlighted with Source Code Highlighter .



インターフェイスのコンストラクタ、デストラクタ、初期化、レンダリングのすべてが非常に明白です。 複雑なことは何もありません。 ほぼ空の実装:

#include "lj_plasmoid.h"

#include <QPainter>
#include <QFontMetrics>
#include <QSizeF>

#include <plasma/svg.h>
#include <plasma/theme.h>

//
// .desktop

K_EXPORT_PLASMA_APPLET(ljplasmoid, LjPlasmoid)

LjPlasmoid::LjPlasmoid(QObject *parent, const QVariantList &args)
: Plasma::Applet(parent, args)
{
//
//

setBackgroundHints(DefaultBackground);
resize(400, 300);
}

LjPlasmoid::~LjPlasmoid()
{
}

void LjPlasmoid::init()
{
}

void LjPlasmoid::paintInterface(QPainter *p,
const QStyleOptionGraphicsItem *option, const QRect &contentsRect)
{
//
}

* This source code was highlighted with Source Code Highlighter .
#include "lj_plasmoid.h"

#include <QPainter>
#include <QFontMetrics>
#include <QSizeF>

#include <plasma/svg.h>
#include <plasma/theme.h>

//
// .desktop

K_EXPORT_PLASMA_APPLET(ljplasmoid, LjPlasmoid)

LjPlasmoid::LjPlasmoid(QObject *parent, const QVariantList &args)
: Plasma::Applet(parent, args)
{
//
//

setBackgroundHints(DefaultBackground);
resize(400, 300);
}

LjPlasmoid::~LjPlasmoid()
{
}

void LjPlasmoid::init()
{
}

void LjPlasmoid::paintInterface(QPainter *p,
const QStyleOptionGraphicsItem *option, const QRect &contentsRect)
{
//
}

* This source code was highlighted with Source Code Highlighter .
#include "lj_plasmoid.h"

#include <QPainter>
#include <QFontMetrics>
#include <QSizeF>

#include <plasma/svg.h>
#include <plasma/theme.h>

//
// .desktop

K_EXPORT_PLASMA_APPLET(ljplasmoid, LjPlasmoid)

LjPlasmoid::LjPlasmoid(QObject *parent, const QVariantList &args)
: Plasma::Applet(parent, args)
{
//
//

setBackgroundHints(DefaultBackground);
resize(400, 300);
}

LjPlasmoid::~LjPlasmoid()
{
}

void LjPlasmoid::init()
{
}

void LjPlasmoid::paintInterface(QPainter *p,
const QStyleOptionGraphicsItem *option, const QRect &contentsRect)
{
//
}

* This source code was highlighted with Source Code Highlighter .



これをすべて保存したので、すぐに私のウィジェットが美しいフレーム内の空の領域を描画することを確認するために、Plasmidを収集し始めました。 このためには、モジュール自体に加えて、次の内容の.desktopファイルが必要です。

[Desktop Entry]
Name=LjPlasmoid
Comment=LiveJournal Plasmoid
Type=Service
ServiceTypes=Plasma/Applet

X-KDE-Library=plasma_applet_ljplasmoid
X-KDE-PluginInfo-Author=Ivan Ivanov
X-KDE-PluginInfo-Email=ivan.ivanov@mail.ru
X-KDE-PluginInfo-Name=ljplasmoid
X-KDE-PluginInfo-Version=0.1
X-KDE-PluginInfo-Website=http://plasma.kde.org/
X-KDE-PluginInfo-Category=Examples
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true


X-KDE-PluginInfo-Nameフィールドの値がマクロK_EXPORT_PLASMA_APPLEの最初のパラメーターと一致する必要があるという事実に注意する必要があります。 次に、モジュール自体をKDE4ライブラリのあるフォルダーにコピーする必要があり(ほとんどの場合、「/ usr / lib / kde4」、またはx86_64アセンブリの場合は「/usr/lib64/kde4」)、.desktopファイルはアドレスに送信する必要があります」/ usr / share / kde4 / services '。 最後に、プラズマにデータを再読み込みさせ、新しく作成されたウィジェットが利用可能なウィジェットのリストに表示されるようにする必要があります。 これは、面白いコマンド「kbuildsycoca4」を実行することにより行われます。

プラズモイドの動作を確認するには、デスクトップに直接追加する方法と、週単位のウィンドウでウィジェットを表示する「plasmoidviewer」ユーティリティを使用する方法の2つがあります。 しかし、どちらも助けてくれませんでした。 「頭脳」の代わりに、「ljplasmoid」という名前のオブジェクトを作成できないと主張するエラーメッセージを頑固に見ました。

問題の場所を特定する試みは長くて苦痛でした。 優れたユーティリティ「strace」までのすべての手段を使用し、「plasma-desktop」プロセスがバイナリモジュールにアクセスするかどうかを判断しようとしました。 それは判明しました、はい、それは回っていましたが、ほとんど意味がありませんでした-エラーはそれ自体を明示することで持続しました。 最後の順番で、同じ場所を数時間踏んだ後、アセンブリに問題があるのではないかと疑い始めました(ソースコードとアセンブリを編集するために、IDE CodeBlocksを使用しました)。 別の方法で問題を解決するために必死だったので、KDEサイトで提供されているcmakeスクリプトをコンパイルに使用してみることにしました。 ここに最小限の変更があります:

project(ljplasmoid)

set(CMAKE_VERBOSE_MAKEFILE ON)
find_package(KDE4 REQUIRED)
include(KDE4Defaults)

add_definitions (${QT_DEFINITIONS} ${KDE4_DEFINITIONS})
include_directories( ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${KDE4_INCLUDES})

set(ljplasmoid_SRCS lj_plasmoid.cpp)
kde4_add_plugin(plasma_applet_ljplasmoid ${ljplasmoid_SRCS})
target_link_libraries(plasma_applet_ljplasmoid ${KDE4_PLASMA_LIBS} ${KDE4_KDEUI_LIBS})


「cmake」ユーティリティを使用してビルドするには、CMakeLists.txtファイルが置かれているフォルダーでスクリプト「cmake -G "Unix Makefiles" && make」を実行する必要があります(スクリプト自体が含まれています)。 私にはあまりはっきりしない理由で、編集方法の変更は報われました-プラスモイドが獲得しました! 言葉では言い表せない喜びに加えて、デスクトップに現れた半透明の空の長方形は、私に非常に強い熱意の攻撃を引き起こし、私は始められたことを続け始めました。 このような開発モデルで私の喜びを覆い隠した唯一のことは、単一のIDEの欠如であり、その結果、端末とエディターを絶えず切り替える必要がありました。 しかし、ここで解決策はすぐに見つかりました。 KDevelop開発環境とその組み込みの「CMakeベースのプロジェクト」プロジェクトテンプレートは、すべての問題を迅速に解決しました。

次の技術的なケースは、ユーザーインターフェイス要素を追加することです(入力フィールドと[送信]ボタンが必要です)。 PlasmaはQtを使用しますが、実際にはQt-oneにバインドされているクラスを接続する必要があります。 合計で、クラスにはいくつかの新しいインクルードと宣言があります。

...

#include <Plasma/PushButton>
#include <Plasma/TextEdit>

...

class LjPlasmoid : public Plasma::Applet
{
...

public slots:

void PostPressed();

public :

Plasma::PushButton m_post_button;
Plasma::TextEdit m_text_edit;
};


* This source code was highlighted with Source Code Highlighter .
...

#include <Plasma/PushButton>
#include <Plasma/TextEdit>

...

class LjPlasmoid : public Plasma::Applet
{
...

public slots:

void PostPressed();

public :

Plasma::PushButton m_post_button;
Plasma::TextEdit m_text_edit;
};


* This source code was highlighted with Source Code Highlighter .
...

#include <Plasma/PushButton>
#include <Plasma/TextEdit>

...

class LjPlasmoid : public Plasma::Applet
{
...

public slots:

void PostPressed();

public :

Plasma::PushButton m_post_button;
Plasma::TextEdit m_text_edit;
};


* This source code was highlighted with Source Code Highlighter .



それで、当然、実装はもう少し意味のあるものになります。

LjPlasmoid::LjPlasmoid(QObject *parent, const QVariantList &args)
: Plasma::Applet(parent, args), m_post_button( this ), m_text_edit( this )
{
m_post_button.setText( "Post" );
m_text_edit.setText( "[ok: put your text here]" );

connect(&m_post_button, SIGNAL(clicked()), SLOT(PostPressed()));

setBackgroundHints(DefaultBackground);
resize(300, 200);
}

void LjPlasmoid::paintInterface(QPainter *p,
const QStyleOptionGraphicsItem *option, const QRect &contentsRect)
{
p->setRenderHint(QPainter::SmoothPixmapTransform);
p->setRenderHint(QPainter::Antialiasing);

m_post_button.setGeometry(QRect(contentsRect.x() + contentsRect.width() - 75,
contentsRect.y() + contentsRect.height() - 30, 10, 30));
m_text_edit.setGeometry(QRect(contentsRect.x(), contentsRect.y(),
contentsRect.width(), contentsRect.height() - 35));
}


* This source code was highlighted with Source Code Highlighter .
LjPlasmoid::LjPlasmoid(QObject *parent, const QVariantList &args)
: Plasma::Applet(parent, args), m_post_button( this ), m_text_edit( this )
{
m_post_button.setText( "Post" );
m_text_edit.setText( "[ok: put your text here]" );

connect(&m_post_button, SIGNAL(clicked()), SLOT(PostPressed()));

setBackgroundHints(DefaultBackground);
resize(300, 200);
}

void LjPlasmoid::paintInterface(QPainter *p,
const QStyleOptionGraphicsItem *option, const QRect &contentsRect)
{
p->setRenderHint(QPainter::SmoothPixmapTransform);
p->setRenderHint(QPainter::Antialiasing);

m_post_button.setGeometry(QRect(contentsRect.x() + contentsRect.width() - 75,
contentsRect.y() + contentsRect.height() - 30, 10, 30));
m_text_edit.setGeometry(QRect(contentsRect.x(), contentsRect.y(),
contentsRect.width(), contentsRect.height() - 35));
}


* This source code was highlighted with Source Code Highlighter .
LjPlasmoid::LjPlasmoid(QObject *parent, const QVariantList &args)
: Plasma::Applet(parent, args), m_post_button( this ), m_text_edit( this )
{
m_post_button.setText( "Post" );
m_text_edit.setText( "[ok: put your text here]" );

connect(&m_post_button, SIGNAL(clicked()), SLOT(PostPressed()));

setBackgroundHints(DefaultBackground);
resize(300, 200);
}

void LjPlasmoid::paintInterface(QPainter *p,
const QStyleOptionGraphicsItem *option, const QRect &contentsRect)
{
p->setRenderHint(QPainter::SmoothPixmapTransform);
p->setRenderHint(QPainter::Antialiasing);

m_post_button.setGeometry(QRect(contentsRect.x() + contentsRect.width() - 75,
contentsRect.y() + contentsRect.height() - 30, 10, 30));
m_text_edit.setGeometry(QRect(contentsRect.x(), contentsRect.y(),
contentsRect.width(), contentsRect.height() - 35));
}


* This source code was highlighted with Source Code Highlighter .



したがって、方法がわからないが、単純な「顔」を持つウィジェットを取得しました。

画像

LiveJournalと直接連携するために、公式ウェブサイトで説明されているAPI 、この目的のために「libcurl」を使用して作成されたクラスの簡単なセットを使用しました。 トピックのトピックを超えているため、このクラスのソースコードは公開しませんが、興味がある人はここからダウンロードできます

したがって、最後のメソッドはまだ実装されていません-ログにメッセージを送信します:

void LjPlasmoid::PostPressed()
{
LjSession session;
LjRequest post(&session, recieve_responce, this );

post.AddData( "mode" , "postevent" );
post.AddData( "user" , "user_name" );
post.AddData( "password" , "user_password" );
post.AddData( "ver" , "1" );
post.AddData( "event" , m_text_edit.nativeWidget()->toPlainText().toAscii().data());
post.AddData( "lineendings" , "unix" );
post.AddData( "subject" , "[Posted via LjPlasmoid]" );
post.AddData( "security" , "public" );
post.AddData( "year" , "2009" );
post.AddData( "mon" , "11" );
post.AddData( "day" , "23" );
post.AddData( "hour" , "20" );
post.AddData( "min" , "00" );

printf( "text2send: %s\n" , m_text_edit.nativeWidget()->toPlainText().toAscii().data());

post.Post();
m_text_edit.setText( "[ok: put your text here]" );
}


* This source code was highlighted with Source Code Highlighter .
void LjPlasmoid::PostPressed()
{
LjSession session;
LjRequest post(&session, recieve_responce, this );

post.AddData( "mode" , "postevent" );
post.AddData( "user" , "user_name" );
post.AddData( "password" , "user_password" );
post.AddData( "ver" , "1" );
post.AddData( "event" , m_text_edit.nativeWidget()->toPlainText().toAscii().data());
post.AddData( "lineendings" , "unix" );
post.AddData( "subject" , "[Posted via LjPlasmoid]" );
post.AddData( "security" , "public" );
post.AddData( "year" , "2009" );
post.AddData( "mon" , "11" );
post.AddData( "day" , "23" );
post.AddData( "hour" , "20" );
post.AddData( "min" , "00" );

printf( "text2send: %s\n" , m_text_edit.nativeWidget()->toPlainText().toAscii().data());

post.Post();
m_text_edit.setText( "[ok: put your text here]" );
}


* This source code was highlighted with Source Code Highlighter .
void LjPlasmoid::PostPressed()
{
LjSession session;
LjRequest post(&session, recieve_responce, this );

post.AddData( "mode" , "postevent" );
post.AddData( "user" , "user_name" );
post.AddData( "password" , "user_password" );
post.AddData( "ver" , "1" );
post.AddData( "event" , m_text_edit.nativeWidget()->toPlainText().toAscii().data());
post.AddData( "lineendings" , "unix" );
post.AddData( "subject" , "[Posted via LjPlasmoid]" );
post.AddData( "security" , "public" );
post.AddData( "year" , "2009" );
post.AddData( "mon" , "11" );
post.AddData( "day" , "23" );
post.AddData( "hour" , "20" );
post.AddData( "min" , "00" );

printf( "text2send: %s\n" , m_text_edit.nativeWidget()->toPlainText().toAscii().data());

post.Post();
m_text_edit.setText( "[ok: put your text here]" );
}


* This source code was highlighted with Source Code Highlighter .



これは、自分のニーズに合わせてプラスモイドを作成する方法の例にすぎません。 このため、エラーリターン、動作パラメーターの微調整などはありません。 ただし、このトピックは、Plasmaが内部からのものであるという一般的で最も表面的なアイデアを提供することができます。

このウィジェットに関しては、計画は次のとおりです。 適切なセットアップを実装します。 KDE-Lookを付けます 最近、プロトコルに依存するすべてのロジックをluaスクリプトに移行することで、拡張性とさまざまなブログプラットフォームと連携する機能を提供することを考えています。

PSそして最も重要なこと:招待に対するnsinrealに感謝します!

Source: https://habr.com/ru/post/J76371/


All Articles