Qtに関する覚え書き[その他・未整理]

デバッグ出力

整数

整数をデバッグ出力します。
int iDt = 255;
qDebug() << iDt;255
qDebug("10進=%d, 16進=%x, 8進=%o", iDt, iDt, iDt); 10進=255, 16進=ff, 8進=377
※C言語のprintfのように使えます。ただし%dにqint64を指定すると警告が出ます。

真理値

真理値をデバッグ出力します。
bool bDt = true;
qDebug() << bDt;true
qDebug("bool=%d", bDt);bool=1
※true/false、1/0で表示されます。

文字列

文字列をデバッグ出力します。
QString sDt = "テスト";
qDebug() << sDt;"テスト"
qDebug() << "文字 = " + sDt;"文字 = テスト"
qDebug("文字 = %s", sDt.toUtf8().constData());文字 = テスト
qDebug("文字 = %s", qPrintable(sDt));文字 = ■■■
※半角英数の場合はqPrintableでも表示できます。日本語は文字化けします。

メッセージボックス

メッセージボックスで文字列を表示します。
QMessageBox::information(this, "タイトル", "文字列");
※タイトルはメッセージダイアログのウインドウタイトルです。

文字列操作

文字列と数値の変換

文字列を数値に変換します。
QString numStr = "1234";
int i = numStr.toInt();i=1234
long l = numStr.toLong();l=1234
double d = numStr.toDouble();d=1234
※結果はすべて1234になります。

数値を文字列に変換します。
QString str = QString::number(2.5);
※結果は"2.5"になります。

キャラクターを数値として計算し、結果を文字列に変換します。
QString str = QString((int)'A' + 2);
※結果は"C"になります。

長さや数の取得

QString txtStr = "ABC123:def126 ";
int sz = txtStr.length(); 空白を含む文字数sz=14
int ix = txtStr.indexOf("12"); 指定文字列を最初に見つけた位置ix=3
int cnt = txtStr.count("12"); 指定文字列の個数cnt=2
QString str = txtStr.at(1); 指定位置の文字str="B"
※lengthは0x00も1文字として数えるらしいです。

チェック

QString txtStr = "ABC123:def126 ";
bool bl = txtStr.contains ("F12", Qt::CaseInsensitive); 指定文字を含むかbl=true
bool bl = txtStr.startsWith("A") 指定文字から始まるかbl=true
bool bl = txtStr.endsWith("6"); 指定文字で終わるかbl=false(最後は空白)
※CaseInsensitiveを指定すると大文字と小文字の違いを無視します。
※startsWithとendsWithでもCaseInsensitiveを指定することができます。

NullとEmptyは違います。
QString txtStr = "";
bool bl = txtStr.isEmpty(); 空かbl=true
bool bl = txtStr.isNull(); NULLかbl=false

文字列操作1

QString txtStr = "ABC123:def126 ";
QString str = txtStr.mid(1, 3); 指定位置から指定文字数str="BC1"
QString str = txtStr.left(1); 先頭から指定文字数str="A"
QString str = txtStr.right(2); 末尾から指定文字数str="6 "
QString str = txtStr.toLower(); 英小文字str="abc123:def126 "
QString str = txtStr.toUpper(); 英大文字str="ABC123:DEF126 "
QString str = txtStr.repeated(2); 指定回数だけ繰り返すstr="ABC123:def126 ABC123:def126 "

文字列操作2

下記の処理は元の文字列(txtStr)を書き換えるので、使う場合は注意が必要です。
QString txtStr = "ABC123:def126 ";
txtStr.replace(3, 2, "xy"); 指定位置から指定文字数の置き換えtxtStr="ABCxy3:def126 "
txtStr.chop(2); 末尾の指定文字数を削除txtStr="ABCxy3:def12"
txtStr.insert(1, QString("and")); 指定位置の前に挿入txtStr="AandBCxy3:def12"
txtStr.fill('X', 4); 文字を指定数並べるtxtStr="XXXX"
txtStr.setNum(2.5); 数値を文字列に変換txtStr="2.5"

文字列の右詰め

QString txtStr = "12345";
QString str = txtStr.rightJustified(8, '0'); str="00012345"
QString str = txtStr.rightJustified(8, '.'); str="...12345"
QString str = txtStr.rightJustified(3, '.', true); str="123"
QString str = txtStr.rightJustified(3, '.', false); str="12345"
QString str = QString::number(98).rightJustified(4, '0'); str="0098"
※rightJustifiedの第3引数はfalseがデフォルトです。 trueを指定すると指定桁数に切り詰めます。

空白の切り詰め

simplifiedは空白・タブ・改行をまとめて1つの空白に置き換えます。先頭と末尾は削ります。
trimmedは先頭と末尾だけ空白・タブ・改行を取り除きます。
QString txtStr = "\t AB CD\n EF GH\tIJ\n\nKL \n";
QString str = txtStr.simplified(); str="AB CD EF GH IJ KL"
QString str = txtStr.trimmed(); str="AB CD\n EF GH\tIJ\n\nKL"
※先頭と末尾の処理はどちらも同じです。trimmedは中央部をそのまま残します。

文字列の分割

例として、文字列を区切り文字で分割して文字列リスト(QStringList)に入れます。

ループで文字列リストを処理する例です。どちらでも同じ結果になります。

文字列の整形

argと%を使って文字列を整形できます。

printfのように文字列を整形できます。
※日本語が入っている場合は、sDt.toUtf8().constData()にしないと文字化けします。

sprintfは、Ver.5.7ではasprintfになっています。

バリアント型

チェック

バリアント型変数の内容が指定した型に変換できるか調べます。
QTime tm = QTime(22, 30);
QVariant var = QVariant(tm);
bool bl = var.canConvert(QMetaType::QString); bl=true
bool bl = var.canConvert(QMetaType::Int); bl=false
bool bl = var.canConvert<QString>(); bl=true
bool bl = var.canConvert<int>(); bl=false
※trueになれば変換できます。どちらでも調べられます。
※ほとんどのタイプはQStringに変換可能です。

■メタタイプ[targetTypeId (QVariant)]
タイプ 対応する他のタイプ (自動的にキャスト)
QMetaType::Bool QChar, Double, Int, LongLong, QString, UInt, ULongLong
QMetaType::QByteArray Double, Int, LongLong, QString, UInt, ULongLong
QMetaType::QCharBool, Int, UInt, LongLong, ULongLong
QMetaType::QColorQString
QMetaType::QDateQDateTime, QString
QMetaType::QDateTimeQDate, QString, QTime
QMetaType::Double Bool, Int, LongLong, QString, UInt, ULongLong
QMetaType::QFontQString
QMetaType::Int Bool, QChar, Double, LongLong, QString, UInt, ULongLong
QMetaType::QKeySequenceInt, QString
QMetaType::QVariantList QStringList (アイテムがQStringsに変換可能な場合)
QMetaType::LongLong Bool, QByteArray, QChar, Double, Int, QString, UInt, ULongLong
QMetaType::QPointQPointF
QMetaType::QRectQRectF
QMetaType::QString Bool, QByteArray, QChar, QColor, QDate, QDateTime, Double, QFont, Int,
QKeySequence, LongLong, QStringList, QTime, UInt, ULongLong
QMetaType::QStringList QVariantList, QString (リストがアイテムを持つ場合)
QMetaType::QTimeQString
QMetaType::UInt Bool, QChar, Double, Int, LongLong, QString, ULongLong
QMetaType::ULongLong Bool, QChar, Double, Int, LongLong, QString, UInt

値のセット

バリアント型変数に文字列や数値を入れます。
QVariant var = QVariant(6);整数
QVariant var = QVariant(0.5);浮動小数点数
QVariant var = QVariant(true);真理値
QVariant var = QVariant("テスト");文字列
QVariant var = QVariant::fromValue(static_cast<QObject *>(label)); QLabel
※最後の行は、label(QLabel)をQObjectにキャストしてvarにセットしています。

値の取り出し

バリアント型変数(var)から文字列や数値を取り出します。
int rs = var.toInt();整数
double rs = var.toDouble(); 浮動小数点数
bool rs = var.toBool();真理値
QString rs = var.toString();文字列
QLabel *label = qvariant_cast<QLabel *>(var);QLabel

他の型も取り出せます。
QByteArray rs = var.toByteArray(); バイト配列
QChar rs = var.toChar();文字
QDate rs = var.toDate();日付
QDateTime rs = var.toDateTime(); 日付時刻
QList<QVariant> rs = var.toList(); バリアント型リスト
QPoint rs = var.toPoint();座標
QRect rs = var.toRect();領域
QSize rs = var.toSize();サイズ
QStringList rs = var.toStringList(); 文字列リスト
QTime rs = var.toTime();時刻
QUrl rs = var.toUrl();URL
qreal rs = var.toReal();実数

※「How to use QVariant/ja」参照。

https://wiki.qt.io/How_to_use_QVariant/ja

宣言・ルール

クラス宣言

クラス宣言の書式です。

class クラス名 [: アクセス指定子1 継承元クラス名1 [, アクセス2 継承元2 [, … ] ] ]

アクセス指定子は3種類あり、省略するとprivateになります。
種類説明
publicクラスの外からアクセス可能
protectedクラス内と派生先クラスだけアクセス可能
privateクラス内だけアクセス可能

ヘッダー(.h)のクラス宣言記述例です。
※暗黙的な呼び出し禁止(explicit)は省略できます。

コンストラクタの書式です。

クラス名::クラス名 (引数1, 引数2, …) : 初期化1,初期化2, …

ソース(.cpp)のコンストラクタとデストラクタの記述例です。
※デストラクタはほとんど使っていません。

定数の初期化

C言語の "#define MAX_COUNT 99" をクラス内に記述する例です。

MyClassのクラス宣言内で定数の変数名(maxCount)を宣言します。

コンストラクタで初期化します。

キャスト

キャストの例です。
QLabel *label = static_cast<QLabel *>(object); QLabel ← QObject
QLineEdit *edit = static_cast<QLineEdit *>(sender()); QLineEdit ← QObject
QKeyEvent *e = static_cast<QKeyEvent *>(event); QKeyEvent ← QEvent
QVariant var = QVariant::fromValue(static_cast<QObject *>(label)); QVariant ← QObject ← QLabel
msgbox.setStandardButtons(static_cast <QMessageBox::StandardButton>(button)); StandardButton ← int
QImage image = qvariant_cast <QImage>(e->mimeData()->imageData()); QImage ← QVariant
※最初の3行はqobject_castを使ったほうがいいらしいです。

■キャストの種類
種類説明
dynamic_cast継承元を派生クラスにキャストする時
const_castconstで宣言して、後でconstを外す必要が出た時
static_cast通常のキャスト
reinterpret_cast ポインタなど。"void *"を経由してstatic_castを使うほうが安全
※よく分からないので、ほとんどstatic_castを使っています。
※qobject_castは内部でdynamic_castを呼んでいるらしいです。
※この説明は不正確かもしれません。

実行時の引数

デバッグ用の引数を設定します。
(1)Qt Creator画面の左側の[プロジェクト]をクリックして プロジェクトモードに切り替えます。
(2)画面上部の[実行]をクリックすると、画面中央に引数の欄が現れます。
(3)引数の欄にテスト用の引数値を入力します。

例えば:AB 123 C:\Temp 文字列 "12 45"

※引数は空白で区切って指定します。
※空白が含まれる場合は引用符で囲みます。

次のどちらの方法でも引数を取り出すことができます。
※最初の値はプログラム名(フルパス)なので無視します。

関数の引数

ヘッダーの関数宣言に引数のデフォルト値を設定します。
※デフォルト値にはtr("")を使えません。

ソースの関数にはデフォルト値を入れません。
※引数は左から順番に指定します。 例えばblを指定する場合、valueとanswerは省略できません。

その他(未確認)

OSに制御を渡す (DoEvents)

時間がかかる処理を行う場合、定期的にOSに制御を渡すためにループの中などで使います。
※ExcludeUserInputEventsを指定すると、ユーザーからの入力を無視します。

親子関係

parentで親を取得する時、レイアウトは親と見なされないようです。

例えば:

QWidget ← QGridLayout ← QLabel

※ラベルの親はレイアウトを飛ばして上位のウィジェット(QWidget)になります。

クリップボード

クリップボードに文字列(str)をセットします。

クリップボードから文字列を取り出します。

スリープ

指定時間だけ処理を止めます。
※Sleepは長い時間を指定すると危険かもしれません。

画面サイズ取得

表示画面のサイズを取得します。
※幅×高さをデバッグ出力します。

クラス名

クラス名を取得します。

クラス名を調べます。

トップウインドウ検索

ラベルを指定してトップウインドウを取得します。

ラベルの親をたどってトップウインドウを探します。
※親が取得できなくなったらループを出ます。結果はwidgetに入っています。

タイトル行の高さ

ウインドウタイトルの高さを取得します。
※ウインドウ枠は含まれません。

現在時刻の文字列

現在の時刻を取得して文字列に変換します。

フォーマットの例です。
QDateTime tm = QDateTime(QDate(2001, 5, 21), QTime(14, 13, 9));
QString str = tm.toString("dd.MM.yyyy");str="21.05.2001"
QString str = tm.toString("ddd MMMM d yy");str="Tue May 21 01"
QString str = tm.toString("hh:mm:ss.zzz");str="14:13:09.042"
QString str = tm.toString("h:m:s ap");str="2:13:9 pm"
※QString::toString参照。

子要素の検索

widgetの子要素の中から、指定したオブジェクト名のラベルを探します。
※該当ラベルを見つけたらオブジェクト名をデバッグ出力します。

タブオーダーの設定

すべてのウィジェットのタブオーダーを自分自身にします。
※これでタブキーを押してもフォーカスが移動しないはずです、多分。

レイアウトのクリア

レイアウトを空にして中にあったウィジェットを破棄します。
※takeAtだと全部消せなかったので、removeWidgetを使っています。
※レイアウトの中に別のレイアウトがある場合はまだテストしてません。

ラジオボタンの選択取得

グループボックス内で選択されているラジオボタンを返す関数です。

関数を呼んでラジオボタンを確認します。
※選択されているボタンのテキストをデバッグ出力します。
※btnに何も入ってない場合はすべてのラジオボタンがオフの状態です。

ラジオボタンの選択クリア

グループボックス内でオンになっているラジオボタンをオフにします。
※AutoExclusiveをオフにしないと、ラジオボタンの状態を変更できません。

テキストの折り返し

文字列をラベルの幅に合わせて分割し、改行コードを入れた文字列を返します。
※横幅が固定のラベルに長い文字列を入れる時に使います。
※文字列がラベルの幅に収まれば、何もしないで文字列を返します。
※ラベルのフォントサイズに合わせて適当な所に改行コードを入れた文字列を返します。
※フォント関連の設定が済んでいないと、サイズの計算が正しくできないことがあります。

ラベルのwordWrapで文字列の折り返し表示をすると結果が微妙なので、 自力で折り返し処理を作りました。
余計な改行コードが入っているので、戻り値の文字列の扱いには注意が必要です。

enum定義名の取得

指定されたウィジェットのenum定義リストを返す関数です。
※第2引数はenum名を指定する時に使います。省略すると定義を全部取り出します。

メタオブジェクトの中からenum定義を取り出します。

QLineEdit(edit)のenum定義リストを取得します。
※3行目はEchoModeの定義名だけ取り出します。

結果(listAll)はこうなります。

"ActionPosition,0,QLineEdit::LeadingPosition"
"ActionPosition,1,QLineEdit::TrailingPosition"
"EchoMode,0,QLineEdit::Normal"
"EchoMode,1,QLineEdit::NoEcho"
"EchoMode,2,QLineEdit::Password"
"EchoMode,3,QLineEdit::PasswordEchoOnEdit"

※"EchoMode"を指定すると最初の2行は取り出しません。

Ver.5.5からは、これが使えるらしいです。
※Ver5.3なのでテストできません。

2016年12月