SSブログ

SDツールの土台作成 [Qt]

今回はSDカードツールの話にします。と言っても、このツールはあんまり必要じゃ無さげになってきたんですけどね・・。まあ、なんでもいいので取りかかっていきましょう。

*

まずは、プログラムを埋め込む枠を作るためにGUIから作成します。とりあえずは「ドラッグ&ドロップでSDカードのインポートフォルダにファイルをコピーする」と言うのをアプリの機能としたので、QTextEditのみを使って、そこへのドラッグ&ドロップで動作、動作状況はQTextEdit上にテキストで表示すると言う感じで対応しようと思います。・・って、だんだんやることの敷居が低くなってますね・・。

プロジェクト作成して、ウィンドウにQTextEditを貼り付けて、レイアウトをごにょごにょいじって、保存して、実行。

11022200.png
土台完成


ま、ここまでは、これまでやってきたことの焼き直しですね。カーソルが表示されていたので、readOnlyに設定したいのですが、NetWalker 上のQt Creatorでは、プロパティの編集ができないので、Qt Designer を起動して設定します。・・・、そう言えば、このソフト自体はMac向けを目指していますが、現状これの開発はNetWalker上で行ってます。NetWalkerだと、どこででも開発できるので・・。AndroidのSDKもARM向けが出ればいいんですけどね・・。

ま、それはさておき、「readOnly」のプロパティにチェックを入れて、Qt Creatorで再読み込みし、同プロパティを見てみましたが、反映されてません・・。でも、実行してみたら、カーソルは出てきませんでした。と言うことで、readOnlyにはなっている様です。う~ん、NetWalkerでは、Qt Creator上のDesignerの使用はやめましょうかね・・。

図に示すほどでもないですが、今、クラス構成は下記の様な感じにしようかと思っています。

11022201.png
単純


役割分担は下記の様にしましょう。

MainWindowClassメインウィンドウで、アプリの実行・終了の制御
QTextEditファイル・ディレクトリのドロップ場所及び、状況の表示
SdtoolMainディレクトリのチェックとかファイルのコピーとか実行全般


と言うことで、SdtoolMainと言うクラスの追加をしときます。ベースクラスは無しですね。


とまあ、同じようなことばかり繰り返してますが、つづく。






BackupControlクラスのメンバ関数仕様検討 [Qt]

大体の機能分担を決めたので、それに従って実装して行きたいと思います。BackupControlは以前作成したので、BackupMainも作成しておきます。こちらは、QThreadの派生クラスとします。

*

まずは、BackupControlに以前検討したメソッドを追加しようと思いましたが、自作のクラスは自分でソースを編集する必要がありそうですね・・。クラスエディタとかがあればいいのに。

さて、コードを書こうと思いましたが、よく考えたら引数とかを全く決めてませんでした。そこから始めないといけませんね。

addSourceDir()
引数QString &dir転送元ディレクトリ
戻り値intディレクトリ登録の成否。下記の値のいずれかを返す。
AddSrcSuccess追加成功
AddSrcDuplicate追加済みディレクトリ
AddSrcBackupProceededバックアップ中
AddSrcFail追加失敗
処理 引数で与えられたディレクトリを転送元ディレクトリとして追加する。追加失敗は、存在しないディレクトリ名の指定を想定。「AddSrcBackupProceeded」はUI的に発生しない様にする予定。


delSourceDir()
引数QString &dir削除対象ディレクトリ
戻り値intディレクトリ削除の成否。下記のいずれかを返す。
DelSrcSuccess削除成功
DelSrcBackupProceededバックアップ処理中
DelSrcFail削除失敗
処理 引数で指定されたディレクトリを転送元ディレクトリから削除する。削除失敗は、指定されたディレクトリが転送元として追加されていない場合を想定。「DelSrcBackupProceeded」はUI的に発生させないようにする予定。


backup()
引数なし
戻り値intバックアップ開始結果。下記のいずれかを返す。
BackupStartSuccessバックアップ開始成功
BackupStartNotSetSrcバックアップ元ディレクトリ未設定
BackupStartNotSetDestバックアップ先ディレクトリ未設定
BackupStartBackupProceededバックアップ中
BackupStartFailバックアップ開始失敗
処理 BackupMainに転送元ディレクトリリストと転送先ディレクトリを渡し、BackupMainの処理を開始する。バックアップ開始失敗はThread開始失敗を想定。「BackupStartBackupProceeded」はUI的に発生させないようにする予定。


setDestinationDir()
引数QString &dir転送先ディレクトリ
戻り値int転送先ディレクトリ設定結果。下記のいずれかを返す
SetDestSuccess転送先ディレクトリ設定成功
SetDestDuplicate設定済み転送先ディレクトリ
SetDestDuplicate設定済み転送先ディレクトリ
SetDestBackupProceededバックアップ中
SetDestFail転送先ディレクトリ設定失敗
処理 引数で指定されたフォルダを転送先フォルダとして設定する。設定失敗は指定されたフォルダが存在しない場合を想定。「SetDestBackupProceeded」はUI的に発生させない予定。


getSourceDirs()
引数なし
戻り値QStringList設定されている転送元ディレクトリのリスト
処理 設定されている転送元ディレクトリのリストをまとめて返す。


getDestinationDir()
引数なし
戻り値QString設定されている転送先ディレクトリ
処理 設定されている転送先ディレクトリを返す。何も設定されていない場合は、空文字列を返す(isEmpty()でtrueになる)。


stop()
引数なし
戻り値intバックアップ停止結果。下記を返す。
BackupStopSuccessバックアップ停止成功
BackupStopNotProceedバックアップ処理中でない
BackupStopFailバックアップ停止失敗
処理 実行中のバックアップ処理を停止させる。処理停止のフラグでも立てるか?そうすると、バックアップの実行中にフラグチェックの処理がいりますね。QThread::terminate()は使いません。


引数を参照渡しにするかポインタ渡しにするか悩みましたが、いくつかサイトを検索して、おおよそ下記の方針で使い分けることにしました。

  • ポインタ渡し - 引数を変更する可能性がある場合、NULLの引数を許容する場合
  • 参照渡し - 引数を変更しない場合、NULLの引数を許容しない場合


getSourceDirs() で、クラスのオブジェクトを返す時にどうするか悩みました。値で返すのか、ポインタで返すのか・・。自分で作ったクラスを返す時は注意する必要がある(コピーコンストラクタを作る?)が、Qtで用意されているクラスならそのまま値返しができそうな雰囲気です。ちょっと不安なんですが、まあ、今回は試しに値返しにしてみることにしました。何か不具合が出たら、それはそれでいい勉強になるでしょう。今回、色々悩んでて、クラスに対する代入演算子や初期化演算子の動きがよくわかってい無かったことが判明しましたね・・。理解できたんかなぁ・・。

スレッド実行中の処理について、排他処理を行う必要がありますね・・。うまくいくんかな・・。やり方が間違っているか・・?


さて、以下は signal です。とりあえずは、QThreadが元から持っているsignalは出てくるとして、他に何かいりますかね?と思ったら、以前検討してました。全部いるかな・・?

finished()
引数なし
戻り値なし
処理 スレッドの実行完了時に発生。コピー処理終了のsignalとして利用可能かな。


started()
引数なし
戻り値なし
処理 スレッドの実行開始時に発生。バックアップ開始のシグナルとして利用可能かな。


terminated()
引数なし
戻り値なし
処理 スレッドがterminateされたときに発生。QThread::terminate()を使う予定はないので、これは発生しない想定。なので、利用しない。


stopped()
引数なし
戻り値なし
処理 バックアップ停止完了時に発生。


startBackupFile()
引数QString &dirバックアップ元ファイルフルパス
戻り値なし
処理 1ファイルのバックアップ開始時に発生。引数はバックアップファイルのフルパス。


finishBackupFile()
引数QString &dirバックアップ元ファイルフルパス
戻り値なし
処理 1ファイルのバックアップ完了時に発生。引数はバックアップ元ファイルのフルパス。


今、思いついた関数仕様はこんなところでしょうか。実装する前に、ちゃんと動作を検討しとく必要がありますね・・。


つづく。


【参考】
参照とポインタ - Gulf of St.Lawrence
ポインタと参照の使い分け - thinkin’ in the brain
オブジェクトを返す関数 - C++ Builder / Turbo C++ 質問の木
C++編(言語解説) 第16章 コピーコンストラクタ
C++ クラス設計に関するノート - オブジェクトの広場
C++ で関数から object をどう返すか - KBDAHOLIC - やぬすさんとこ
C++ クラス設計に関するノート
コピーコンストラクタ - C++入門




   

クラス間の機能分担とQtのスレッド [Qt]

さて、今週はQtの話に戻ります。前回、バックアップ処理の実現に何らかの並行処理が必要なことに気付きました。って、最初から気づけよと言う感じですかね・・。手動で停止することが頭に無かったのでした。

「並行処理」でぱっと思いついたのが「スレッド」ですが、Qtにはどのような並行処理が用意されているのでしょうか・・?と思って、リファレンスを眺めていたら、スレッドのページがありました。ここを読んで行きましょう。

*

単純にスレッドを実行するには、下記の通り行えばいい様です。



クラス図にすれば、こんな感じでしょうか?ファイルのバックアップ処理を行うクラスを「BackupMain」としました。

11012500.png
バックアップ処理をスレッド化する際のクラス図


どういう機能のクラスにすればいいですかねぇ・・。バックアップ処理の分担分けとしては、下記の通りにしたい気がします。

BackupControl バックアップ元ファイルとバックアップ先ディレクトリを選定し、BackupMainに通知。 BackupMainの開始と停止制御。
BackupMain BackupControlから指定された情報を元に順次バックアップを実行。


実装イメージとしては、BackupMain内にバックアップ元、バックアップ先(今回の場合、バックアップ元一つ一つに持たせる意味はありませんが・・)のペアを保存するキューを持たせ、BackupControlからそこにファイルのパスを追加、BackupMainでパスを取り出してコピーを実行としたいと思っています。

・・・とここまで考えていましたが、も一つスレッドが必要かも・・・。バックアップ元のファイルの抽出をBackupControlで行っていると、停止ボタンのイベントが拾えない気がします。と言うか、ファイルパスの抽出と実行を同じスレッドですればいいか・・。

機能分担を考えなおすとこんな感じでしょうか。

BackupControl バックアップ元ディレクトリとバックアップ先ディレクトリをBackupMainに通知。 BackupMainの開始と停止制御。
BackupMain BackupControlから指定された情報を元に対象ディレクトリを選定し、順次バックアップを実行。


ま、ほぼ一緒ですね。バックアップ元のディレクトリとバックアップ先ディレクトリをまとめてBackupMainに渡して、後は勝手にやってくれと言う感じにしましょう。

先程のキューの排他処理が必要かと思ってましたが、この構成にすれば、それも不要ですね。


と言う感じで、実装して行きましょう。


【参考】
Thread Support in Qt - Qt 4.5.3






バックアップの処理クラスを考える [Qt]

先日、「mainwindow.ui」に以前追加したslotが残っている件を気にしていましたが、それを削除できないかと思っていたところ、できました。

Objectペインの「MainWindowClass」を右クリックし、「change signals/slots」を選択します。

10122800.png

こっちにはありました


「Slots」の欄に「addButtonClicked()」が残っていたので、これを選択して「-」ボタンを押して削除します。

10122801.png

ここに残ってます


結果を保存して、「mainwindow.ui」をテキストエディタで見たところ、該当の箇所の記述が消えていました。

10122802.png

消えた!


*

以上、すっきりしたところで、実装を進めようと思いますが、進める前にクラス構成を考えたいと思います。今まで、MainWindowクラスに色々貼り付けていましたが、ここは単なるUIとして、バックアップ制御を受け持つクラスを別に用意したいと思います。クラス図を書くとこんな感じでしょうか・・。

10122803.png

描くほどでもないですが・・


アプリケーション自体はMainWindowクラス主体で動くので、そのエンジンとなる「BackupControl」と言うクラスを作成します。ベースクラスは無しとします。

MainWindowクラスとこのクラス(BackupControl)の間でBackupControlクラス側に必要そうなメソッドは下記のような感じでしょうか。

addSourceDir()バックアップ元ディレクトリの追加
delSourceDir()バックアップ元ディレクトリの削除
backup()バックアップ開始
setDestinationDir()バックアップ先ディレクトリの設定
getSourceDirs()設定されているバックアップ元ディレクトリの取得
getDiestinationDir()設定されているバックアップ先ディレクトリの取得
stop()バックアップの停止


最後のメソッドで思いつきましたが、そう言えば、バックアップ動作の中止のボタンが必要ですね・・。

また、経過出力のためにsignalを出してもらう必要がありそうです。signalでいいんですかね・・。

startCopyFile()1ファイルコピー開始のsignal(コピー元)
finishCopyFile()1ファイルコピー終了のsignal(コピー元)
startCopy()コピー処理開始のsignal
finishCopy()コピー処理終了のsignal
stopCopy()コピー処理停止のsignal


ここまで書いて気付きましたが、これって、バックアップ処理は並列処理で行わないと途中で停止ができない気がしますね・・。Qtのスレッドの仕組みを見なければ・・。


つづく。




タイトルバーの文字化けを直す [Qt]

さて、ファイル選択ダイアログのタイトルバーの文字が化けてしまう件ですが、まずは、先日調べた以下のフレーズを試してみようと思います。今のところ翻訳データは無いので、main()に下記を追加してみます。

QTextCodec::setCodecForTr(QTextCodec::codecForName("utf8"));


ソースはこんな感じです。

#include <QtGui/QApplication>
#include "mainwindow.h"


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;

    QTextCodec::setCodecForTr(QTextCodec::codecForName("utf8"));

    w.show();
    return a.exec();
}
これでうまくいくといいですけどねぇ・・


これで実行してみます。・・・コンパイルエラーが出ました・・。

ヘッダをインクルードするのを忘れてました。QTextCodecのページを見たところ、「#include <QTextCodec>」だとのこと。

追加して実行したところ・・。

10122100.png
文字化けが直りました



正常に表示できました。と言うことで、簡単ですが、今回はこれで。







ディレクトリ選択ダイアログの表示 [Qt]

ウィンドウタイトルを変えるだけで、えらいとまどってしまいましたが、気を取り直して、とりあえず、各ボタンのスロットを作っていきます。まずは、関数の枠から・・。

ボタンを右クリックし、「Go to slot...」を実行して行きます。

10121400.png
追加は容易になりました


残り三つのボタンに対応するslotを作成して、ヘッダファイルを見てみたら、インデントがおかしいです・・。カーソル位置がおかしかったのか・・?

10121401.png
これは手で直します


ソースを見る限り、追加したslotは「private slots:」ラベルの下に追加されていくみたいですね。後から追加した方が上の方に追加されています。

ちなみに、関数の枠もちゃんとできています。

10121402.png
こっちは作成した順に追加されています


ログを仕込んで、実行したところ、全てのボタンが反応しました。

10121403.png
ログで確認


では、とりあえずQFileDIalogを「追加」ボタンから呼び出してみます。簡単に使いたいならstatic関数を呼べばいいとのこと。下記の関数が用意されています。

QFileDialog::getExistingDirectory 存在するディレクトリの指定に使用。
QFileDialog::getOpenFileName 存在するファイルを一つだけ指定するのに使用。
QFileDialog::getOpenFileNames 存在する一つ以上のファイルを指定するのに使用。
QFileDialog::getSaveFileName 一つのファイル名を指定するのに使用。ファイルは存在していても無くてもどちらでもいい。


コピー元の追加は複数指定できた方が便利ですし、できたらディレクトリだけでなくファイル名も指定できると自由度が増す気がします。と言うことで、QFileDialog::getOpenFileNamesを使ってみたいのですが、これがディレクトリを指定できるのかどうかが不明です。まあ、試してみましょう。

引数は下記のものが用意されています。

QWidget *parent = 0親ウィジェット。これを設定するとモーダルダイアログになるとのこと。親ウィジェットの中央に表示されるとのこと。thisでいいと思います。
const QString & caption = QString()ダイアログのタイトルバーに表示される文字列ですね。設定しない場合はデフォルトの文字列が使われるとのこと。
const QString & dir = QString()ワークディレクトリ。ファイル名を含む場合は、そのファイルが選択された状態になる。
const QString & filter = QString()フィルター。複数のフィルターを指定する時は、「;;」で区切るとのこと。書式が不明・・。
QString * selectedFilter = 0選択されているフィルター。
Options options = 0


とりあえず、このように実装してみました。

void MainWindow::on_addButton_clicked()
{
    qDebug() << "on_addButton_clicked()";

    QStringList *srcList = new QStringList();

    *srcList = QFileDialog::getOpenFileNames(this, tr("バックアップ元の選択"));
    qDebug() << *srcList;

    delete srcList;
}
うまくいくか?


実行して、ファイルダイアログを起動したところ、このような画面に・・。タイトルが化けてます・・。

10121404.png
タイトル部分が文字化け・・


ディレクトリを選択して、「開く」を押したところ、そのディレクトリ内に入ってしまいました・・。ファイルを選択して「開く」を押したらうまくいった様です・・。このダイアログではディレクトリは選択できませんね・・。

と言うことで、QFileDialog::getOpenFileNamesでは、ディレクトリの選択は出来ませんね・・。

仕方がないので、QFileDialog::getExistingDirectoryを利用します。

void MainWindow::on_addButton_clicked()
{
    qDebug() << "on_addButton_clicked()";

    QStringList *srcDir = new QStringList();

    *srcList = QFileDialog::getExistingDirectory(this, tr("バックアップ元の選択"));
    qDebug() << *srcDir;

    delete srcDir;
}
うまくいくか?


これで、1つづつですが、ディレクトリの選択は出来るようになりました。が、相変わらず、キャプションの文字化けが残っています・・。

10121405.png
文字化けを直したい


次回はこれを調べましょう。つづく。


Qt Designer上での各部品のプロパティの変更 [Qt]

前回の記事で、Qt Designer上でのslotの追加の仕方が概ねわかりました。slotの作成に各部品の名前が関わってくることが判明したので、まず、各部品に名前を付けることにしました。つけた名前は、下記の通りです。

部品名オブジェクト名概要
1バックアップ対象リスト表示領域srcListバックアップ対象のディレクトリを列挙する。
2追加ボタンaddButtonバックアップ対象ディレクトリの追加のためのボタン。
3削除ボタンdelButtonバックアップ対象ディレクトリの削除のためのボタン。
4バックアップボタンstartButtonバックアップ開始のボタン。
5バックアップ先表示領域destDirバックアップ先のディレクトリを表示。
6選択ボタンdestButtonバックアップ先のディレクトリを選択するためのボタン。
7進捗状況表示領域progressView進捗状況を表示する。


各部品の対応は下記の通りです。

10120700.png
名前を付けるのは難しいですね


そう言えば、ウィンドウのタイトルも変えておきました。一応、英字にしときましたが・・。

とさらっと書きましたが、変え方がなかなかわかりませんでした・・。Object Inspector(右上)で「MainWindowClass」を選択して、Property Editor(右下と言うか、右中央?)で「windowTitle」と言うプロパティを変更しようとしましたが、編集できる状態になりません・・・。説明を見る限り、ここのValueの欄をクリックすれば、変更できそうな感じなのですが、いくらクリックしても編集状態に変わりませんでした・・。

10120701.png
かなり、いらいら状態・・


調べても良くわからないので、Qt Creator上で変更するのはあきらめて、同時にインストールされていたQt Designerを別途起動して変更を試みたところ、あっさりできました・・・・。

10120702.png
ここまで来るのに苦労しました・・。


う~ん、Qt Creator に組み込まれているものと、同時にインストールされた Qt Desginerではバージョンが違うんですかね・・。何となく、最新のものでは大丈夫で、今のところNetWalker上だけの症状の様な気もしますが、ご参考まで。


つづく。





Qt Designerで追加したslotの削除とsignal/slotのconnect [Qt]

さて、slotを追加できたのはいいんですが、どうやって削除すればいいんでしょうか・・? いろいろクリックしていても、削除の方法が出てこなさげです。

今回、追加ボタンの名前を変えたいだけなので、試しにボタンの名前を「pushButton」から「addButton」に変えてみました。そして、右クリック→「Go to slot」したところ、また新しいslotが追加されました・・。できたスロットは「on_addButton_clicked」。名前は固定ですかね・・? もしかしたら、これで古い方は削除すればいいだけなのかもしれません。

よくわかりませんが、これで実行してみましたところ、新しく作成したslotが呼ばれていました・・。じゃあ、削除は手動ですかね・・。と言うことで、前々回前回追加した項目は手動で削除することにします。

で、実行。で、問題無く動作しました。と、それはいいんですが、ソースを見てもsignalとslotをconnectしている箇所が見当たりません・・。何故つながってるんでしょうか・・?

UI関連のファイルに定義されているのかなと思い、「mainwindow.ui」をテキストエディタで見てみたところ、ソースの末尾に「<slots>」と言う項目が追加されていました。

10113000.png
スロットの記述はありました


これ、最初に作成したslotですね・・。これを消すにはどうすればいいんでしょう・・・?

目的のものが無かったので、次に「ui_mainwindow.h」を覗いてみたところ、「Ui_MainWindowClass」と言うクラスの「setupUi()」と言う関数の中に「QMetaObject::connectSlotsByName(MainWindowClass);」との記載があります。これがそうなんですかねぇ・・。

10113001.png
これ?


と言うことで、「QMetaObject」の説明を見てみます。そこの「connectSlotsByName()」関数の説明を見てみると、全ての子オブジェクトから「void on_<object name>_<signal name>(<signal parameters>);」と言う形のslotを探して接続するとのこと。と言うことで、Qt Designerを使う時はsignalが自動で作成されるslotに自動でconnectされる様です。・・・結構、やっつけで作った感じがしないでもないですね。

・・・オブジェクトの名前を変えた時に追随してくれるといいんですが、それは無さげですね・・。「リファクタリング」っていうメニューでも無いんかな・・?


以上で、Qt Designerでのslotの追加と接続の方法がわかったので、次回より各オブジェクト名を変更して、追加して行くことにします。


つづく。






Qt Designerでのslotの追加 [Qt]

前の記事で疑問を提示しましたが、他に解決法もよくわからないので、釈然としないながらも手動で関数を追加することにします。

「mainwindow.h」に定義されているMainWindowClassのprivate区画に「void addButtonClicked();」を追加し、「mainwindow.cpp」に、関数の実装を記載します。

10112300.png
宣言を追加


10112301.png
とりあえず、デバグ出力


これで、実行してみます。

エラーが出ましたね。うまくconnectされていない様です。

10112302.png
うまくいかんねぇ・・


「Object::connect: No such slot MainWindow::addButtonClicked() in ui_window.h:135」と言うエラーが出ています。以前の記事を読み返したら、slotの追加自体を完全に手動に切り替えてますね。今回は、スロットの作成と接続はQt Designerでやっています。関係だけQt Designerで指定して、スロットの実体は手動で書くのかと思いましたが、根本的にそれは違うのでしょうか・・?

*

色々見てみましたがよくわからなかったので、当てずっぽうで、Edit widgetsモードでボタンを右クリックして、「Go to slot」を選択したところ、なにやら自動でスロットが作成されました・・。

10112303.png
名前も自動で付けられました(mainwindow.cpp)


ん~、こちらが正しい方法なのでしょうか?と言うことは、前回つなげた線は意味が無くなりますねぇ・・。と言うか、先にこちらを作ってから線をつなげるべきなんでしょうか・・?

slotの名前が気に入らないんですが、とりあえず、これで実行してみたところ・・、ちゃんと反応しました。ちなみに、「mainwindow.h」にもslotが追加されていました。

10112304.png
プロトタイプも自動作成(mainwindow.h)


なるほど、slotはこれで追加をすればいいんですね。でも、接続先を変えたい時はどうすればいいんでしょうか・・? ま、それはそれとして、名前の変更もしたいので、一旦これまで追加して行ったものを削除することにします。

*

と思いましたが、ボタンを右クリックして「Change signals/slots」を選択しようと思ったら、そのメニューが無くなっています・・。

10112305.png
なんで・・?


追加したslotの削除方法は無いんでしょうか・・・?


つづく。


【参考】
Qt Designer's Signals and Slots Editing Mode




   


ボタンのイベントを取得したい [Qt]

前回、国際化対応について調べましたが、ボタンに書かれている文字列をQt Designer上で直接入力したところ、ソース上には現れませんね・・。ソースの文字列をtr()で囲おうと思ったんですが、これの国際化対応はまた別の処理が必要な気がしてきました・・。ちなみに文字列は.uiファイルに入っています。もう面倒なので、後回しにしますか・・。

*

ボタンの文字列を変更して、実行したものがこちらです。最初に書いた図とは、ボタン内の表記を変えていますが、まあ、とりあえずこちらの様な感じで行こうと思います。

10111600.png
画面上にもうちょっと説明が必要な気がしますね


さて、まずは「追加」及び「選択」を押したときにディレクトリ選択のダイアログが出る様にしたいと思います。と思ったところで、どこに処理を追加しようかなと悩んでしまいました。いきなり、レイアウトから始めたので、現状はMainWindowクラスしか存在していません。そういや、ボタンに動作を追加するのってどうでしたっけ・・?

その辺の話は、こちらに書かれている様です。って、以前見た様な見てない様な・・。「Edit」→「Edit signals/slots」でsignal/slotの編集モードに入ります。

10111601.png
モードの変更が必要なのね


まずは、「追加」のボタンからフォームにsignalを送って見ることにします。追加のボタンからぐいぃ〜っとドラッグすると、電気回路図のグランドみたいなマークが出てきて、離すと次のダイアログが出てきました。

10111602.png
clicked()につながるslotを追加?


signal(pushButton)側に「clicked()」と「clicked(bool)」がありますが、前者は単に後者の引数がfalseに設定されているものの様です。この引数は、ボタンが「checkable」の場合に意味があるようです。今回はいらないので、前者でいいですね。

MainWindowClass(QMainWindow)側にslotが何も出ていないので、「Edit」ボタンをクリックして、MainWindowクラスにslotを追加してみましょう。

10111603.png
これで関数を追加ですかね


「Slots」側の「+」ボタンを押して、slot関数を追加します。

10111604.png
ま、名前は普通に


追加されたslotを選択して、「OK」を押します。

10111605.png
OK


左下の「Show signals and slots inherited from QWidget」と言うのが気になりますね・・。試しに、チェックを入れたら、デフォルトで用意されているsignal/slotが全部表示されました。あ~、そう言うことね・・。

10111606.png
関係無かった・・


これは、今はどうでもいいことでした。気を取り直して「OK」をクリック。すると、フォーム上に接続の様子が出てきました。画面が狭いので、見にくいですね・・。

10111607.png
見にくい・・


さて、とりあえず、ここで保存をして、追加したslotである「addButtonClicked()」を編集したいと思います。と思って、ソースを見てみましたが、特に関数は追加されていません・・。どうすりゃええの・・?昔の記事では、手動で追加してるみたいですね。


んんん~。ほんとにそれが正解なのか・・? つづく。




   

ブログを作る(無料) powered by SSブログ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。