以下のページに詳しく書いてあります。
- 範囲for文
- 型推論
- ラムダ式
- 型alias
- typedef ⇒ usingを使おう
- typedefはオワコン
- 新初期化記法
- リストイニシャライザ
- override
以下のページに詳しく書いてあります。
Qtアプリを配布する場合は、実行ファイル(*.exe)ファイルのみでは実行できません。
アプリで使用しているDLLファイルがないためです。
そこで、DLLファイルをいざ集めようとするとこんなに大量にDLLファイルが必要になります。 <一例>
そこで、windeployqtを用いて、Qt Creator上で、自動で、DLLファイルを集める方法を用いました。
以下がQt Creatorのプロジェクトのビルド設定です。
コマンド : C:\Qt\5.9.1\tool\deploy.bat
引数 : %{CurrentBuild:Name} %{CurrentProject:Name}
作業ディレクトリ : %{buildDir}
(※コマンドは任意のパスです)
deploy.batファイルの中身は以下のとおりです。
if "%1"=="デバッグ" ( set BUILD_MODE=debug ) else ( set BUILD_MODE=release ) if not exist deploy\nul ( mkdir deploy ) xcopy /C /Y %BUILD_MODE%\*.exe deploy\ windeployqt --%BUILD_MODE% deploy %BUILD_MODE%\%2.exe
C:\Qt\5.9.1\toolのフォルダは以下のような構成になっております。
以下のページが参考になります。
Observerとは、英語で観察者を意味します。
Observer パターンとは、状態の変化を観察することを目的としたものですが、どちらかというと「観察」よりも「通知」に重点の置かれたものになっています。
あるインスタンスの状態が変化した際に、そのインスタンス自身が、「観察者」に状態の変化を「通知」する仕組みです。
<Observerパターンの定義 : クラス図>
[ObserverSample.h]
#include <vector> #include <algorithm> #include <iostream> class Observer { friend class Subject; public: virtual ~Observer() {} protected: virtual void update(Subject*) = 0; }; class Subject { private: std::vector<Observer*> obs_; public: // Observerを登録 void add_observer(Observer* o) { if (std::find(obs_.begin(), obs_.end(), o) == obs_.end()) { obs_.push_back(o); } } // Observerの登録抹消 void delete_observer(Observer* o) { auto iter = std::find(obs_.begin(), obs_.end(), o); if (iter != obs_.end()) { obs_.erase(iter); } } protected: // 登録されたObserverのハンドラを呼び出す // std::for_each ⇒ 範囲の全ての要素に、指定された関数を適用する // oの全ての要素にラムダ式を適用する // 【thisのキャプチャ】 // メンバ関数内では、thisをキャプチャすることでラムダ式内でメンバ変数、メンバ関数(update)を使用することができます。 // 下記のラムダ式では、thisをキャプチャして、vector[obs_]の各要素のObserverオブジェクトのupdateメソッドを使用しています。 void notify() { std::for_each(obs_.begin(), obs_.end(), [this](Observer* o) { o->update(this); }); } }; // 具象サブジェクト // 室温 class RoomTemp : public Subject { private: int value_; // public: RoomTemp(int initial) : value_(initial) {} void increment() // 室温を1度上げる { ++value_; notify(); } void decrement() // 室温を1度下げる { --value_; notify(); } int get_temp() const // 現在の室温 { return value_; } }; // 具象オブサーバクラス // 温度表示パネル : 室温の変化に応じて室温を表示する class TempDisp : public Observer { public: ~TempDisp() { std::cout << "お疲れ様でしたー" << std::endl; } protected: virtual void update(Subject* from) { int temp = static_cast<RoomTemp*>(from)->get_temp(); std::cout << "現在の温度: " << temp << "℃" << std::endl; } };
[main.cpp]
#include "ObserverSample.h" int main() { RoomTemp room1(20); RoomTemp room2(30); TempDisp disp1; TempDisp disp2; room1.add_observer(&disp1); room2.add_observer(&disp2); room1.increment(); room1.increment(); room1.increment(); room2.decrement(); room2.decrement(); room2.decrement(); }
以下のサイトを参考にさせていただきました。
以下のリンクがわかりやすいです。 * 地下アイドルとアイドルオタクを疎結合にしてみたら、夢も希望もなくなった〜デザインパターンのObserverを考える〜 - Qiita
HeadFirstデザインパターンの本のコードのサンプルは、GitHubにあります。
http://www.wickedlysmart.com/headfirstdesignpatterns/code.htmlgithub.com
パターン指向リファクタリング 読書メモ - mookjp.io
QTextStreamを用いることで、csvファイルに保存することが可能です。
csvファイル保存の形式に合わせるため、データごとにカンマで区切ります。今回は、10個のデータごとに改行します。
今回使用するデータは、日本語文字列データを使用しました。
以下がコードです。
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QString> #include <QDebug> #include <QFile> #include <QTextStream> #include <QFileDialog> #include <QMessageBox> #define Jstr(str) QString::fromLocal8Bit(str) MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_clicked() { // csvファイルに書き込むQStringListを作成 QStringList writeList; QString str = Jstr("日本語"); for (int i = 1; i <= 100; i++) { if (i % 10){ writeList.append(str + " : " + QString::number(i) + ","); } else { // 改行コードはLFです writeList.append(str + " : " + QString::number(i) + "\n"); } } // fileNameとfile pathを求める QString fileName = QFileDialog::getSaveFileName(this, tr("Save Paint Info"), "", tr("Paint info (*.csv);;All Files (*)")); if (fileName.isEmpty()) return; QFile file(fileName); if (!file.open(QIODevice::WriteOnly)) { QMessageBox::information(this, tr("Unable to open file"), file.errorString()); return; } // デバッグ表示 foreach (QString item, writeList) { qDebug() << item; } // csvファイルに書き込む QTextStream out(&file); foreach (QString item, writeList) { out << item; } }
不明なコンパイル時の出力はありますが、無事、csvファイルにデータを書き込むことができました。
Qt5では文字列リテラルを QString へ変換するには主に以下のメソッドを使用可能。
QString::fromLatin1()
QString::fromLocal8Bit()
QString::fromUtf8()
以下にマクロを使用しないパターンと使用するパターンを記載します。
[マクロ未使用パターン]
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QString> #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_clicked() { QStringList qStrList; // QString::fromLocal8Bit() ⇒ 現在のロケールに合わせたコーデックを使用して QString を生成します QString temp = QString::fromLocal8Bit("日本語"); for (int i = 0; i < 100; i++) { QString qStrTest = temp; qStrList.append(qStrTest); } foreach (QString item, qStrList) { qDebug() << item; } }
[マクロ使用パターン]
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QString> #include <QDebug> #define Jstr(str) QString::fromLocal8Bit(str) MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_clicked() { QStringList qStrList; QString temp = Jstr("日本語"); for (int i = 0; i < 100; i++) { QString qStrTest = temp; qStrList.append(qStrTest); } foreach (QString item, qStrList) { qDebug() << item; } }
実行結果は、以下のとおりです。日本語文字列を使用しても、文字化けが発生しません。
以下の記事のサイトを参考にさせていただきました。ありがとうございます。