|
|
| (同じ利用者による、間の8版が非表示) |
| 12行目: |
12行目: |
| QString strAppDir = QCoreApplication::applicationDirPath(); | | QString strAppDir = QCoreApplication::applicationDirPath(); |
| </syntaxhighlight> | | </syntaxhighlight> |
| | <br><br> |
| | |
| | == QIODevice::Textオプション == |
| | <code>QIODevice::Text</code>を指定する場合、改行コードは自動的にプラットフォームに合わせて変換される。<br> |
| <br><br> | | <br><br> |
|
| |
|
| 74行目: |
78行目: |
| </syntaxhighlight> | | </syntaxhighlight> |
| <br> | | <br> |
| | ==== 文字列の検索 ==== |
| | 特定の文字列を検索する場合は、テキストファイルを読み込みながら検索する文字列が各行に含まれているかを確認する。<br> |
| | <br> |
| | 以下の例では、各行が"hoge"という文字列と一致するかどうかを確認している。<br> |
| | 一致する行が存在する場合、その行を出力して処理を終了して、一致する行が存在しない場合はその旨を出力する。<br> |
| | <syntaxhighlight lang="c++"> |
| | bool SearchString(const QString &filePath, const QString &str) |
| | { |
| | QFile File(filePath); |
| | if (!File.open(QIODevice::ReadOnly | QIODevice::Text)) { |
| | std::cerr << QString("ファイルのオープンに失敗 : %1").arg(File.errorString()).toStdString() << std::endl; |
| | return false; |
| | } |
| | |
| | QTextStream in(&File); |
| | while (!in.atEnd()) { |
| | QString line = in.readLine(); |
| | if (line == str) { |
| | std::cout << QString("%1 が見つかりました").arg(str).toStdString() << std::endl; |
| | File.close(); |
| | return true; |
| | } |
| | } |
| | |
| | std::cout << QString("%1 は見つかりませんでした").arg(str).toStdString() << std::endl; |
| | File.close(); |
| | |
| | return false; |
| | } |
| | </syntaxhighlight> |
| | <br> |
| | |
| ==== バイナリデータの読み込み ==== | | ==== バイナリデータの読み込み ==== |
| バイナリデータを読み込む場合は、<code>QFile</code>クラスの<code>readLine</code>メソッドまたは<code>readAll</code>メソッドを使用する。<br> | | バイナリデータを読み込む場合は、<code>QFile</code>クラスの<code>readLine</code>メソッドまたは<code>readAll</code>メソッドを使用する。<br> |
| 179行目: |
215行目: |
| | | |
| OutStream << str.replace(QChar(0x301C), QChar(0xFF5E)); | | OutStream << str.replace(QChar(0x301C), QChar(0xFF5E)); |
| | </syntaxhighlight> |
| | <br> |
| | 以下の例では、ファイルの先頭にテキストを追記している。<br> |
| | # まず、既存のファイルの内容を読み込み、その内容をメモリ(<code>QString</code>クラスや<code>QByteArray</code>)に保存する。 |
| | # 次に、追加する内容と元のファイル内容を結合させる。 |
| | # 最後に、新しい内容でファイルを上書きする。 |
| | <syntaxhighlight lang="c++"> |
| | #include <QFile> |
| | #include <QTextStream> |
| | |
| | QFile File("/tmp/sample.txt"); |
| | if (!File.open(QIODevice::ReadOnly | QIODevice::Text)) { |
| | std::cerr << QString("Failed to open file for reading.").toStdString() << std::endl; |
| | return -1; |
| | } |
| | |
| | // 元のファイル内容を読み込む |
| | QString oldText; |
| | QTextStream in(&File); |
| | oldText = in.readAll(); |
| | File.close(); |
| | |
| | // 追加する内容と元のファイル内容を結合させる |
| | QString newText = "hoge" + "\n" + oldText; |
| | |
| | // ファイルに新しい内容を書き込む |
| | if (!File.open(QIODevice::WriteOnly | QIODevice::Text)) { |
| | std::cerr << QString("Failed to open file for writing.").toStdString() << std::endl; |
| | return -1; |
| | } |
| | |
| | QTextStream out(&File); |
| | out << newText; |
| | File.close(); |
| </syntaxhighlight> | | </syntaxhighlight> |
| <br> | | <br> |
| 232行目: |
302行目: |
| QByteArray data_4(std::begin<char>({0x00, v1, v2, v2, 0x05, 0x06, '\xf3'}), 7); | | QByteArray data_4(std::begin<char>({0x00, v1, v2, v2, 0x05, 0x06, '\xf3'}), 7); |
| </syntaxhighlight> | | </syntaxhighlight> |
| <br><br>
| |
|
| |
| == CSVファイル ==
| |
| 以下の例では、CSVファイルを作成している。<br>
| |
| 処理手順は以下の通りである。<br>
| |
| # 数値データを生成する。<br>ここでは、sin曲線y=sin(x)を生成する。
| |
| # 数値データをテキストデータに変換する。
| |
| # ファイル保存ダイアログを開いて、保存するファイル名を入力する。
| |
| # 全テキストデータを書き込む。
| |
| <br>
| |
| <syntaxhighlight lang="c++">
| |
| #include <QFileDialog>
| |
| #include <QMessageBox>
| |
| #include <QTextStream>
| |
| #include <QFile>
| |
| #include <vector>
| |
| #include <math.h>
| |
| #include <sstream>
| |
| #include "mainwindow.h"
| |
| #include "ui_mainwindow.h"
| |
|
| |
| using namespace std;
| |
|
| |
| MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
| |
| {
| |
| ui->setupUi(this);
| |
| }
| |
|
| |
| MainWindow::~MainWindow()
| |
| {
| |
| delete ui;
| |
| }
| |
|
| |
| void MainWindow::OnButtonClicked()
| |
| {
| |
| // Input File Name
| |
| QString FileName = QFileDialog::getSaveFileName(this, tr("Save CSV File"), "", tr("CSV (*.csv);;All Files (*)"));
| |
|
| |
| if(FileName.isEmpty())
| |
| { // Cancel
| |
| return;
| |
| }
| |
|
| |
| // Generate CSV Data
| |
| int iSize = 100;
| |
| vector<double> lx(iSize, 0.0f),
| |
| ly(iSize, 0.0f);
| |
|
| |
| double dx = 2 * 3.15159 / iSize;
| |
| for(int i = 0; i < iSize; i++)
| |
| {
| |
| lx[i] = i * dx;
| |
| ly[i] = sin(vx);
| |
| }
| |
|
| |
| // Convert from Double to String
| |
| QString strFileData = "";
| |
| //stringstream ss;
| |
| for(int i = 0; i < iSize; i++)
| |
| {
| |
| strFileData += lx[i] + ", " + ly[i] + "\n";
| |
| //ss << lx[i] << "," << ly[i] << endl;
| |
| }
| |
|
| |
| // Write to File
| |
| QFile File(FileName);
| |
|
| |
| if(!File.open(QIODevice::WriteOnly))
| |
| {
| |
| QMessageBox::information(this, tr("Unable to open file"), File.errorString());
| |
|
| |
| return;
| |
| }
| |
|
| |
| QTextStream OutStream(&File);
| |
| // 浮動小数点をe形式にする
| |
| //OutStream.setRealNumberNotation(QTextStream::ScientificNotation);
| |
|
| |
| // 浮動小数点の桁数を固定
| |
| //OutStream.setRealNumberNotation(QTextStream::FixedNotation);
| |
|
| |
| // 浮動小数点の桁数を設定
| |
| OutStream.setRealNumberPrecision(3);
| |
|
| |
| OutStream << strFileData;
| |
| //OutStream << ss.str().c_str();
| |
|
| |
| File.close();
| |
| }
| |
| </syntaxhighlight>
| |
| <br><br>
| |
|
| |
| == INIファイル ==
| |
| ==== INIファイルの書き込み ====
| |
| 以下の例では、ソフトウェアにおけるウインドウの状態を保存している。<br>
| |
| <br>
| |
| ウインドウの座標、縦横のサイズ、状態、最少幅、タイトル文字列をSetting.iniファイルに保存する。<br>
| |
| もし、Settings.iniファイルが存在する場合は上書きする。<br>
| |
| <syntaxhighlight lang="c++">
| |
| void MainWindow::saveSetting()
| |
| {
| |
| QSettings settings("settings.ini", QSettings::IniFormat, this);
| |
| settings.beginGroup("MainWindow");
| |
| settings.setValue("pos", pos());
| |
|
| |
| if(!isMaximized())
| |
| {
| |
| settings.setValue("size", size());
| |
| }
| |
|
| |
| settings.setValue("maximized", isMaximized());
| |
| settings.setValue("miniwid", minimumWidth());
| |
| settings.setValue("title", windowTitle());
| |
|
| |
| settings.endGroup();
| |
| }
| |
| </syntaxhighlight>
| |
| <br>
| |
| 以下の例では、ソフトウェア終了時に、ウインドウの幅と高さをINIファイルに保存している。<br>
| |
| <syntaxhighlight lang="c++">
| |
| // mainwindow.cpp
| |
|
| |
| #include <QMessageBox>
| |
| #include <QSettings>
| |
| #include <QSize>
| |
| #include "mainwindow.h"
| |
| #include "ui_mainwindow.h"
| |
|
| |
| MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
| |
| {
| |
| ui->setupUi(this);
| |
|
| |
| ORG_NAME = "My Company";
| |
| APP_NAME = "My Tool";
| |
|
| |
| QSettings settings(ORG_NAME, APP_NAME);
| |
| int width = settings.value("Window / Width").toInt();
| |
| int height = settings.value("Window / Height").toInt();
| |
|
| |
| this->resize(QSize(width, height));
| |
| }
| |
|
| |
| MainWindow::~MainWindow()
| |
| {
| |
| delete ui;
| |
| }
| |
|
| |
| // ソフトウェアの終了処理はcloseEventをオーバーライドすることで実現できる
| |
| void MainWindow::closeEvent(QCloseEvent *event)
| |
| {
| |
| int width = this->geometry().width();
| |
| int height = this->geometry().height();
| |
|
| |
| QMessageBox::information(this, "Finish Timing", tr("window width : %1 \nwindow height : %2").arg(width).arg(height));
| |
|
| |
| QSettings settings(ORG_NAME, APP_NAME);
| |
|
| |
| settings.setValue("Window / Width", width);
| |
| settings.setValue("Window / Height", height);
| |
| }
| |
| </syntaxhighlight>
| |
| <br>
| |
| <syntaxhighlight lang="c++">
| |
| // mainwindow.h
| |
|
| |
| #ifndef MAINWINDOW_H
| |
| #define MAINWINDOW_H
| |
|
| |
| #include <QMainWindow>
| |
|
| |
| namespace Ui {class MainWindow;}
| |
|
| |
| class MainWindow : public QMainWindow
| |
| {
| |
| Q_OBJECT
| |
|
| |
| private:
| |
| const QString ORG_NAME;
| |
| const QString APP_NAME;
| |
|
| |
| public:
| |
| explicit MainWindow(QWidget *parent = 0);
| |
| ~MainWindow();
| |
|
| |
| private:
| |
| Ui::MainWindow *ui;
| |
|
| |
| protected:
| |
| virtual void closeEvent(QCloseEvent *event);
| |
| };
| |
|
| |
| #endif // MAINWINDOW_H
| |
| </syntaxhighlight>
| |
| <br>
| |
| ==== INIファイルの読み込み ====
| |
| 以下の例では、前回のウインドウの状態を復元している。<br>
| |
| Setting.iniファイルから必要な情報を読み込み、画面の状態を変更する。<br>
| |
| <br>
| |
| Settings.iniファイルが存在しない場合またはpos等のキー値が無ければ何もしない。<br>
| |
| <syntaxhighlight lang="c++">
| |
| bool MainWindow::loadSetting()
| |
| {
| |
| QSettings settings("settings.ini", QSettings::IniFormat, this);
| |
| settings.beginGroup("MainWindow");
| |
|
| |
| if(settings.contains("pos"))
| |
| {
| |
| move(settings.value("pos", QPoint(50, 40)).toPoint());
| |
| }
| |
|
| |
| if(settings.contains("size"))
| |
| {
| |
| resize(settings.value("size", QSize(800, 720)).toSize());
| |
| }
| |
|
| |
| if(settings.value("maximized").toBool())
| |
| {
| |
| setWindowState(windowState() | Qt::WindowMaximized);
| |
| }
| |
|
| |
| if(settings.contains("miniwid"))
| |
| {
| |
| setMinimumWidth(settings.value("miniwid", 400).toInt());
| |
| }
| |
|
| |
| if(settings.contains("title"))
| |
| {
| |
| setWindowTitle(settings.value("title", "なし").toString());
| |
| }
| |
|
| |
| settings.endGroup();
| |
| }
| |
| </syntaxhighlight>
| |
| <br>
| |
| 以下に、設定ファイル(Settings.ini)の内容を示す。<br>
| |
| 左上位置(46, 15)、画面サイズ(800x600)、最大化(false)、最少幅(400)、画面のタイトルが"サンプル画面"の場合である。<br>
| |
| [MainWindow]
| |
| pos=@Point(46 15)
| |
| size=@Size(800 600)
| |
| maximized=false
| |
| miniwid=400
| |
| title=\x30b5\x30f3\x30d7\x30eb\x753b\x9762
| |
| <br><br> | | <br><br> |
|
| |
|
| 731行目: |
559行目: |
| // ファイルを閉じる | | // ファイルを閉じる |
| file.close(); | | file.close(); |
| | </syntaxhighlight> |
| | <br><br> |
| | |
| | == ファイルパス == |
| | ==== 絶対パスの検証 ==== |
| | ファイルのパスがファイルシステム上で有効な形式を持っているかどうか (例: 不正な文字、パスの構造がシステムの要件を満たしているか等) を検証する。<br> |
| | <br> |
| | Qtでは、有効なパスが有効かどうかを検証するメソッドは存在しない。<br> |
| | しかし、<code>QFileInfo</code>クラスおよび<code>QDir</code>クラスを使用して間接的にパスの妥当性を検証することができる。<br> |
| | <syntaxhighlight lang="c++"> |
| | #include <QFileInfo> |
| | #include <QDir> |
| | |
| | // QFileInfoを使ってパスの情報を取得 |
| | QFileInfo FileInfo("/tmp/sample.txt"); |
| | |
| | // ファイル名に使用できない文字が含まれているかどうかを確認 |
| | QString fileName = FileInfo.fileName(); |
| | if (fileName.isEmpty() || fileName.contains(QRegExp("[\/\\0]"))) { |
| | // ファイル名に不適切な文字が含まれている場合 |
| | return false; |
| | } |
| | |
| | // パスが絶対パスかどうかを確認 (相対パスは不適切とする) |
| | if (!FileInfo.isAbsolute()) { |
| | return false; |
| | } |
| | </syntaxhighlight> |
| | <br> |
| | ==== 相対パスの確認 ==== |
| | 相対パスの場合、基準となるディレクトリからの解決が可能かどうかを確認する。<br> |
| | 相対パスは特定のディレクトリを基準として解釈されるため、その基準ディレクトリから相対パスを解決 (絶対パスに変換) することにより、パスが想定通りの形式であるかを検証できる。<br> |
| | <br> |
| | 以下の例では、指定された基準ディレクトリ(basePath)から相対パス(relativePath)を解決して絶対パスに変換して、その絶対パスに対してファイル名が適切な形式を持つかどうか等の検証を行っている。<br> |
| | 実際のシナリオでは、更に詳細な検証が必要になるが、このように相対パスを絶対パスに変換して検証することになる。<br> |
| | <syntaxhighlight lang="c++"> |
| | #include <QDir> |
| | |
| | QString basePath = "<基準ディレクトリ>"; |
| | QString relativePath = "<相対パス>"; |
| | |
| | QDir baseDir(basePath); |
| | QString resolvedPath = baseDir.absoluteFilePath(relativePath); |
| | |
| | // 解決されたパスを確認 (不正な文字等) |
| | QFileInfo FileInfo(resolvedPath); |
| | QString fileName = FileInfo.fileName(); |
| | if (fileName.isEmpty() || fileName.contains(QRegExp("[\/\\0]"))) { |
| | // ファイル名に不適切な文字が含まれている場合 |
| | return false; |
| | } |
| </syntaxhighlight> | | </syntaxhighlight> |
| <br><br> | | <br><br> |