hakeの日記

Windows環境でプログラミングの勉強をしています。

関連付けとQCop受信 - ZEditorの場合

サムさんトコにコメントした際に気になったの実験。
以前の実験で関連付けによるアプリ起動の際はQCopメッセージ

setDocument(QString) filepath

でファイルパスを渡すというのを知ったわけなのですが。QCop受信の手段としてQCopChannelクラスを使用していました。ところがZEditorのソースを見るとQCopChannelを使用していません。ではどうなているかというとpublic slotでsetDocument(QString)を定義してるんですよね。
というわけで、rcvqcopに同じ様にして実験してみるとちゃんとQStringは引数を受け取っています。QCopChannelでは引数がQCStringとQByteArrayで処理が面倒なのでQStringで受け取れるのは便利です。

次に同じようにpublic slotでtest(QString)というのを定義してみてターミナルからメッセージを送信

$ qcop QPE/Application/rcvqcop 'setDocument(QString)' 'abcd'
$ qcop QPE/Application/rcvqcop 'test(QString)' 'abcd'

setDocumentの方は上手く行くのに、testの方は上手くいきません。何で???
ZEditorでももう一つのQcopメッセージJumpTo(int)はQCStringとQByteArrayで引数を渡しています、ということは何か理由があるのでしょうね。


ところで、そのJumpTo(int)の処理も

connect( qApp, SIGNAL(appMessage( const QCString&, const QByteArray&)), this,
         SLOT( qcop_receive( const QCString&, const QByteArray& )));

void TextEdit::qcop_receive( const QCString& msg, const QByteArray& data )
{
   // 処理
}

というようにQCopChannnelを使用していません、rcvqcopで同じ記述でsetDocumentを試してみたのですが上手く行かないのですよね、これも謎です。

補足

上のqAppをconnectする方法、setDocumentではダメでしたがgoingToSendSetDocumentとtestは受信しました。ということは関連付けに関係するQCopメッセージでsetDocumentだけはシステム側で特別なことを行っているということなのでしょうか。

結論

  • setDocument(関連付けで使用)はpublic slotで定義
  • その他のQCopメッセージは以下の様にslotを接続してそのslot内でメッセージを解析して処理を行う
connect( qApp, SIGNAL(appMessage( const QCString&, const QByteArray&)), this,
         SLOT( slot( const QCString&, const QByteArray& )));

rcvqcop.h

#ifndef RCVQCOP_H
#define RCVQCOP_H

#include <qpe/qpeapplication.h> // qAppによるconnectを使用する場合


#include <qmainwindow.h>
#include <qmultilineedit.h>
#include <qcopchannel_qws.h>
#include <qdatastream.h> 
#include <qtextstream.h> 

class RcvQCop : public QMainWindow{
	Q_OBJECT
public:
	RcvQCop(QWidget *parent = 0, const char *name = 0);
//	~RcvQcop();
private:
	QMultiLineEdit *eb;

public slots:
	void setDocument(const QString&);
	void test(const QString&);

private slots:
	void printQCop(const QCString &m, const QByteArray &d);

};

#endif

rcvqcop.cpp

#include "rcvqcop.h"

RcvQCop::RcvQCop(QWidget *parent, const char *name)
		: QMainWindow(parent, name)
{
	setCaption("QCop Receive Test");

	eb = new QMultiLineEdit( this );
	setCentralWidget( eb );
	eb->clear();
	
	// QCopチャンネルを設定して、SLOTに接続する。
//	QCopChannel *channel = new QCopChannel( "QPE/Application/rcvqcop", this );
//	connect(channel, SIGNAL(received(const QCString&, const QByteArray&)),
//		this, SLOT(printQCop(const QCString&, const QByteArray&)));

         // qAppを使用したconnect
//	connect(qApp, SIGNAL(appMessage(const QCString&, const QByteArray&)),
//		this, SLOT(printQCop(const QCString&, const QByteArray&)));

}


// public slotを定義 QCopメッセージで直接呼ばれる
void RcvQCop::setDocument(const QString& str)
{
	eb->insertLine( "Rcv : Qcop messeage 'setDocument(QString)'" );
	eb->insertLine( str );
}

//    こちらは上手く動かない???
void RcvQCop::test(const QString& str)
{
	eb->insertLine( "Rcv : Qcop messeage 'test(QString)'" );
	eb->insertLine( str );
}

// 
void RcvQCop::printQCop(const QCString &m, const QByteArray &d)
{
	if (m == "goingToSendSetDocument(QString)"){  // 引数あり
		QDataStream d_stream(d, IO_ReadOnly);  // QByteArrayをストリームにして受ける
		QString s, str;
		d_stream >> s;  // 不等号の向きは>>でなければいけない。
		
		QTextOStream s_stream(&str);
		s_stream << "Rcv : Qcop Message A\n";
		s_stream << m << "\n";
		s_stream << s << "\n";
//		delete &s_stream;
		eb->insertLine( str );

	}else if (m == "setDocument(QString)"){  // 引数あり
		QDataStream d_stream(d, IO_ReadOnly);  // QByteArrayをストリームにして受ける
		QString s, str;
		d_stream >> s;  // 不等号の向きは>>でなければいけない。
		
		QTextOStream s_stream(&str);
		s_stream << "Rcv : Qcop Message B\n";
		s_stream << m << "\n";
		s_stream << s << "\n";
		eb->insertLine( str );

	}else{     // その他のコマンド
		eb->insertLine( "Rcv : Qcop Message" );
		eb->insertLine( m );

		if( d.size() != 0 ){
			QDataStream d_stream(d, IO_ReadOnly);  // QByteArrayをストリームにして受ける
			QString s, str;
			d_stream >> s;  // 不等号の向きは>>でなければいけない。
			QTextOStream s_stream(&str);
			s_stream << s << "\n";
			eb->insertLine( str );
		}
	}