[ 新規 | 編集 | 差分 ] [ 検索 | 一覧 | FrontPage ] [ 履歴 (RSS) | 差分履歴 (RSS) ] [ ログイン ]
【PR】Amazon | SL-C3000 | SL-C1000(3/18発売!) | SL-C860 | SL-6000W | SL-6000L | SL-6000N

開発TIPS

編集

Qt/E,Qtopia用のソフトウェア開発で培ったTIPS

qcopメッセージ送信

編集

プログラムからのqcopメッセージの送信

QCopEnvelope クラスはデストラクタに実際のメッセージ送信の処理が
記述されているので、オブジェクトの解放時に実際のメッセージ送信の処理が行われます。
#変数のスコープから外れる時です。
ですので、狭いスコープで変数を宣言して使用した方が間違いが少なくなると思います。

ごちゃごちゃ説明書くより多分例を見てもらった方が早いと思うので…
↓のコードは必要な部分だけを記述したコードです。
(実際に動かしてないのでもしかしたら微妙に間違ってるかも?)

例)

#include <qpe/qcopenvelope_qws.h>

{
  QCopEnvelope e("QPE/TaskBar", "showInputMethod()");
}

{
  QCopEnvelope e("QPE/System", "execute(QString,QString)");
  e << "textedit" << "/home/zaurus/Document/memo.txt";
}

/* パラメータ無しならこれでもいけたかな? */
{
  QCopEnvelope("QPE/TaskBar", "showInputMethod()");
}

起動時の引数

編集

メインのWidgetクラスで下記のスロットを実装。
引数の文字列が渡されてきます。
スロットのスコープはprivateで大丈夫です。

void setDocument(const QString&);

このスロットはファイルタイプをアプリケーションに関連付けした時に
ファイル名が渡されてくるスロットにもなっているので
関連付けにも対応させたい場合にはそれに対応した実装をする必要があります。

引数を渡してQtopiaアプリケーションを起動する方法には下記の方法があります。
いずれの実行方法でも上記スロットが呼ばれて引数が文字列として渡されます。

Global::execute(const QString& c, const QString& document); [staic]
AppLnk::execute(const QStringList& args);
qcop QPE/System 'execute(QString,QString)' appname argument

※AppLnk::execute()の引数はQStringListですがリストの最初の文字列しか使用されません。

execute(args); -> invoke(args); -> Global::execute(exec(), args[0]);

実装はこのような感じになっています。

また、Qtopiaアプリケーションには高速起動という仕組みもあるため、
main()関数の引数はアプリケーションの処理には使用出来ないと思った方が良いと思います。
コンソール等から起動をすれば処理する事も可能だと思いますが、
これはQtopiaアプリケーションの通常の起動方法ではないため、同じアプリケーションが
2つ起動出来てしまったりいろいろと不具合が出てくると思います。

終了時の処理

編集

メインのWidgetクラスで下記のメソッドをオーバーライド。

void closeEvent(QCloseEvent *e);

終了を取り消したい場合は

e->ignore();

終了を受け入れる場合は

e->accept();

補足:奈々氏
これ、単純に

void hogehoge::closeEvent(QCloseEvent *e){
 e->ignore();
}

とかやっちゃうと、ソフトが落とせなくなりますのでご注意を。
つかりリース前に気づけよ>自分(ぉぃ

OKキーが押された時の処理

編集
setWState(WState_Reserved1);

しておいて下記のスロットを実装

void accept();

QDir::FilterSpec

編集

日本語訳のマニュアルを見ててはまりました。

System - システムファイルを一覧する (Unix では何もしない)

Qt/Eのソースをハックして解決したんですけど、本家のマニュアルを見たら
ちゃんとこう書いてありました…(^^;>ソース読むより先にマニュアル読めよ>自分

System - List system files (on unix, FIFOs, sockets and device files)

GUIクラスの作成

編集

ベースクラスがHogeBase、実装クラスがHogeとすると

1. designerでUI作ってHogeBase.uiで保存

2. 実装クラスのヘッダファイル生成

uic -subdecl Hoge HogeBase.h HogeBase.ui -o Hoge.h 

3. 実装クラスのソースファイル生成

uic -subimpl Hoge Hoge.h HogeBase.ui -o Hoge.cpp 

4. プロジェクトファイル生成

progen -o hoge.pro 

5. メイクファイル生成

tmake -o makefile hoge.pro

6. メイク

make

Fepの状態の検出

編集

QPE/KeyboardチャンネルにstatChanged()ってメッセージがきてるみたい。

この時に$HOME/Settings/fepmode.ja.confを読めば状態が取れそう。

fepmonappletがこの方法でFepの状態を取得しているみたい。

fepIn %d, InpMode %d, HenMode %d

int型のデータ3つかなぁ?
QDataStreamで読み込めそうな予感。

fepinterface.hで定義されてる値を使ってそうな感じなんだけどなあ〜。

何となくな感じでクラスを作ってみた。多分こんな感じだと思うんだよな〜。
fepmode.ja.confが64バイトでFModeNo_MAX=16だから多分int型のデータが16個なんだと思う。
ほとんど未使用っぽい&使い方はよく分からないけど(笑)

Fep状態監視クラス

編集
#ifndef _FEPMONITOR_H_
#define _FEPMONITOR_H_

#include <qstring.h>
#include <qfile.h>
#include <qcopchannel_qws.h>

#define QT_QWS_SHARP
#include <sl/fepinterface.h>

#include <stdlib.h>

class FepMonitor : public QObject
{
    Q_OBJECT
public:
    FepMonitor(QObject* parent=0, const char* name=0)
        : QObject(parent, name){
        m_fepconf = QString(getenv("HOME")) + "/Settings/"
            + FepConfigFileName + ".conf";
        m_fepchannel = new QCopChannel("QPE/Keyboard", this);
        connect(m_fepchannel,
            SIGNAL(received(const QCString&, const QByteArray&)),
            this,
            SLOT(fepMessage(const QCString&, const QByteArray&)));
        loadFepMode();
    }

    /* FModeNo is FModeNo_XXX in <sl/fepinterface.h> */
    int getFepMode(int FModeNo){
        if(FModeNo < FModeNo_MAX){
            return m_fepmode[FModeNo];
        } else {
            return -1;
        }
    }
    bool isActive(){
        return getFepMode(FModeNo_KeyOnOff);
    }
signals:
    void statChanged();
private:
    int m_fepmode[FModeNo_MAX];
    QString m_fepconf;
    QCopChannel* m_fepchannel;

    void loadFepMode(){
        QFile f(m_fepconf);
        if(f.open(IO_ReadOnly)){
            f.readBlock((char*)m_fepmode, sizeof(m_fepmode));
            f.close();
        }
    }
private slots:
    void fepMessage(const QCString& msg, const QByteArray& /*data*/){
        if(msg == "statChanged()"){
            loadFepMode();
            emit statChanged();
        }
    }
};

#endif /* _FEPMONITOR_H_ */

FModeNo の意味

編集
定数意味
FModeNo_KeyOnOff 0キー入力時に IM が On のとき 1
FModeNo_KeyInp 1キー入力のモード(CIM_*/CZM_* の or をとったもの)
FModeNo_KeyHen 2変換中は 1 -> IMStatusModeの値っぽい
FModeNo_PadInp 3入力パッドのモード(?) 50音パッドとかかな? (CIM_*/CZM_* の or をとったもの)
FModeNo_CRimOnOff 4手書き入力パッド が表示されているとき 1
FModeNo_FepOffDisable 5FEP が Off にできないとき 1。50音パッドが表示されているときは1だった

入力モード

編集
定数意味
CIM_None 0x01?
CIM_Hiragana 0x02ひらがな
CIM_Katakana 0x04カタカナ
CIM_Alpanum 0x08英数
CZM_Hankaku 0x40半角
CZM_Zenkaku 0x80全角

IMStatusMode

編集
定数意味
NON_ACTIVE 0IM Off
WAIT_INPUT 1入力待ち
INPUT_STATUS 2入力中
COMPOSITION_STATUS 3変換中
CANDIDATE_STATUS 4変換候補ウィンドウ表示中
ONKUN_STATUS 5音訓変換モード
TANSYUKU_STATUS 6?
SYNSYUKU_STATUS 7変換対象文字列変更中(Shift+左右)
PARTINPUT_STATUS 8?
IM_OTHER_STATUS 100?

コメント

編集

情報求む!

[[#rcomment]]

QTextStream::readLine()は遅い?

編集

下記の様な処理をするとめちゃめちゃ遅いです。

QFile f(filename);
if(f.open(IO_ReadOnly)){
  QTextStream stream(&f);
  while(!stream.atEnd()){
    const QString& s = stream.readLine();
  }
  f.close();
}

ファイル内容を一気に読み込むのでメモリは食うと思いますが
下記のような処理の方が断然早いです。
ファイルサイズがあまり大きくないファイルを処理する場合には
下記のようにした方が良いと思われます。

QFile f(filename);
if(f.open(IO_ReadOnly)){
  QTestStream stream(&f);
  const QStringList& list = QStringList::split('\n', stream.read());
  f.close();
  for(QStringList::ConstIterator it=list.begin();
      it!=list.end(); ++it){
    const QString& s = *it;
  }
}

大きなファイルを読み込みたいときも、例えば下記のような方法が使えます。(inue)

QFile f(filename);
if(f.open(IO_ReadOnly)){
  QTextCodec* codec = QTextCodec::codecForName("SJIS");
  char buf[1000];
  while(!f.atEnd()){
    int sz = f.readLine(buf,sizeof(buf));
    const QString& s = codec->toUnicode(buf,sz-1);
  }
  f.close();
}

codecは用途に合ったものを設定してください。
なお、このコードでは、改行コードは\nのみ、一行が1000バイトに収まることが前提です。
実際に使うコードには、一行がそれ以上になる場合の考慮なども必要です。
でも、元が圧倒的に高速になる(10倍どころではない)ので、多少余分な処理を追加しても誤差の範囲です。

コメント

編集

Qt/E, Qtopia開発関連で質問があればどうぞ。私の分かる範囲であればまとめます。

[[#rcomment]]

09729