(KIO)get のサンプルプログラム - 旧 Wiki アーカイブ
簡単にコードの解説を。
kiosample::kiosample() : KMainWindow( 0, "kiosample" ) { // set the shell's ui resource file setXMLFile("kiosampleui.rc"); setupGUI(); isDownloading = false; } kiosample::~kiosample() { }
コンストラクタ、デストラクタです。 デストラクタで何の処理も行っていないのは、下でnewするオブジェクト(QBuffer* downloadDateは除く)はすべてQOBjectを継承したクラスで、親を持っているので終了時にQtの機能としていもづる式にdeleteするためです。 参照:Qt/KDEでのdeleteの挙動
void kiosample::setupGUI() { QVBox* mainVBox = new QVBox(this); QHBox* srcHBox = new QHBox(mainVBox); QLabel* srcLabel = new QLabel("Source URL", srcHBox); srcEdit = new KLineEdit(srcHBox); QHBox* targetHBox = new QHBox(mainVBox); QLabel* targetLabel = new QLabel("Target URL", targetHBox); targetEdit = new KURLRequester(targetHBox); startGetButton = new KPushButton("Start Getting!", mainVBox); QObject::connect(startGetButton, SIGNAL(clicked()), this, SLOT(slotGetStart()) ); setCentralWidget(mainVBox); }
このメソッドでは各種のGUI部品を作っています。 レイアウトに関しては、LabelとEditを横にならべ(QHBox)、そしてそれらを縦に並べる(QVBox)という構成になっています。 またボタンがクリックされるとslotGetStart?()を呼び出すようにSignal&Slotを設定します。
void kiosample::slotGetStart() { if (srcEdit->text().isEmpty() || targetEdit->url().isEmpty()) return; if (isDownloading) return; //ダウンロード中 kdDebug() << "kiosample : slotGetStart()" << endl; downloadData = new QBuffer; downloadData->open(IO_WriteOnly); /* ダウンロード開始 */ KIO::TransferJob* job = KIO::get(KURL(srcEdit->text()), false, false); QObject::connect(job, SIGNAL(data(KIO::Job *, const QByteArray &)), this, SLOT(slotData(KIO::Job *, const QByteArray &))); QObject::connect(job, SIGNAL(result(KIO::Job *)), this, SLOT(slotJobFinished(KIO::Job *))); isDownloading = true; }
ここが肝心のKIO::getを呼び出しているところです。 まずAPIを参照してTransferJob?を作り、そのjobが発信するsignalと下で説明するslotを接続しています。 また、job->addMetaData?("UserAgent?", "kiosample")等とすることによってjobに付加情報も与えることができます。
void kiosample::slotData(KIO::Job *job, const QByteArray& data) { if(data.isEmpty()) return; /* *データをバッファに一時保存 *slotDataは複数回呼ばれる可能性が有ります */ downloadData->writeBlock(data.data(), data.size()); }
KIO::getが他のoperationと違う点は、データを受け取って来るという点です。 そしてそのデータを受け取っている部分がここです。 slotDataは先程jobのdataシグナルと結びつけました。 また、この部分は複数回呼ばれる可能性があるため、QBufferオブジェクトに一時的に受け取ったデータを書き込んでいます。
void kiosample::slotJobFinished(KIO::Job *job) { if( job->error() ){ job->showErrorDialog(); isDownloading = false; return; } //ファイルに書き込み QFile file(targetEdit->url()); file.open(IO_WriteOnly); file.writeBlock(downloadData->buffer()); //一時データを削除 delete downloadData; downloadData = 0; isDownloading = false; KMessageBox::information(this, "Download Finished!"); }
jobが処理を終了したというシグナルを発するとこのスロットが呼ばれます。(上で呼ばれるようにしました) まずはエラーが起きていないかどうかをチェックし、それから先程受け取ったデータをファイルに書き込みます。 また、一時データをnewしたことを忘れないで下さい。newしたものは必ずdeleteしなければいけません。QObjectの子クラス以外は。