前回のおさらい
前回はコンボボックスを使い方計算内容を切り替える方法について解説しました。オームの法則、モジュール計算、距離速度時間計算機能が揃いアプリらしくなってきました(前回の記事)。今回は長くなったコードを整理します。以下の実行ボタンのクリックイベントのコードを関数化して短くします。
void MainWindow::on_pB_Do_clicked()
{
_E=ui->lE_E->text().toFloat(); //電圧代入
_R=ui->lE_R->text().toFloat(); //抵抗値代入
_I=ui->lE_I->text().toFloat(); //電流値代入
_D=ui->lE_D->text().toFloat(); //直径代入
_Z=ui->lE_Z->text().toFloat(); //歯数代入
_M=ui->lE_M->text().toFloat(); //モジュール代入
switch(_idxTab)
{
case 0:
switch (_idxPsy)
{
case 0:
if(ui->lE_E->text()=="") //電圧が空白の場合
{
_E=_I*_R; //電圧計算
ui->lE_E->setText(QString::number(_E)); //電圧表示
}
else if(ui->lE_R->text()=="") //抵抗が空白の場合
{
_R=_E/_I; //抵抗計算
ui->lE_R->setText(QString::number(_R)); //抵抗表示
}
else if(ui->lE_I->text()=="") //電流が空白の場合
{
_I=_E/_R; //電流計算
ui->lE_I->setText(QString::number(_I)); //電流表示
}
break;
case 1:
if(ui->lE_E->text()=="") //距離が空白の場合
{
_E=_I*_R; //距離計算
ui->lE_E->setText(QString::number(_E)); //距離表示
}
else if(ui->lE_R->text()=="") //速度が空白の場合
{
_R=_E/_I; //速度計算
ui->lE_R->setText(QString::number(_R)); //速度表示
}
else if(ui->lE_I->text()=="") //時間が空白の場合
{
_I=_E/_R; //時間計算
ui->lE_I->setText(QString::number(_I)); //時間表示
}
break;
}
break;
case 1:
if(ui->lE_D->text()=="") //直径が空白の場合
{
_D=_Z*_M; //直径計算
ui->lE_D->setText(QString::number(_D)); //直径表示
}
else if(ui->lE_Z->text()=="") //歯数が空白の場合
{
_Z=_D/_M; //歯数計算
ui->lE_Z->setText(QString::number(_Z)); //歯数表示
}
else if(ui->lE_M->text()=="") //モジュールが空白の場合
{
_M=_D/_Z; //モジュール計算
ui->lE_M->setText(QString::number(_M)); //モジュール表示
}
break;
}
}
cppファイルを追加
コードを関数化する前に、自作関数専用のファイルを作ります。これでイベント関数が入るmainwindow.cppと自作関数が入るファイルを分けます。以下手順でcppファイルを追加します。

コードの整理
mainwindow.hにsub.cppに書く関数を宣言します。
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pB_Do_clicked();
void on_tabWidget_currentChanged(int index);
void on_cmbBx_Physics_currentIndexChanged(int index);
private:
Ui::MainWindow *ui;
float _E=0; //電圧
float _I=0; //電流
float _R=0; //抵抗
float _D=0; //直径
float _Z=0; //歯数
float _M=0; //モジュール
int _idxTab; //現在開いているtab
int _idxPsy; //追加物理計算インデックス
/* 今回の追加分 */
void calcOhm(); //オームの法則計算
void calcDstSpdTm(); //距離速度時間計算
void calcModule(); //モージュール計算
};
#endif // MAINWINDOW_H
sub.cppに関数を書きます。mainwindowとフォームの内容を使いたいのでmainwindow.hとui_mainwindow.hをインクルードします。
#include "mainwindow.h"
#include "ui_mainwindow.h"
/* オームの法則計算 */
void MainWindow::calcOhm()
{
if(ui->lE_E->text()=="") //電圧が空白の場合
{
_E=_I*_R; //電圧計算
ui->lE_E->setText(QString::number(_E)); //電圧表示
}
else if(ui->lE_R->text()=="") //抵抗が空白の場合
{
_R=_E/_I; //抵抗計算
ui->lE_R->setText(QString::number(_R)); //抵抗表示
}
else if(ui->lE_I->text()=="") //電流が空白の場合
{
_I=_E/_R; //電流計算
ui->lE_I->setText(QString::number(_I)); //電流表示
}
}
/* 距離速度時間の法則計算 */
void MainWindow::calcDstSpdTm()
{
if(ui->lE_E->text()=="") //距離が空白の場合
{
_E=_I*_R; //距離計算
ui->lE_E->setText(QString::number(_E)); //距離表示
}
else if(ui->lE_R->text()=="") //速度が空白の場合
{
_R=_E/_I; //速度計算
ui->lE_R->setText(QString::number(_R)); //速度表示
}
else if(ui->lE_I->text()=="") //時間が空白の場合
{
_I=_E/_R; //時間計算
ui->lE_I->setText(QString::number(_I)); //時間表示
}
}
/* オームの法則計算 */
void MainWindow::calcModule()
{
if(ui->lE_D->text()=="") //直径が空白の場合
{
_D=_Z*_M; //直径計算
ui->lE_D->setText(QString::number(_D)); //直径表示
}
else if(ui->lE_Z->text()=="") //歯数が空白の場合
{
_Z=_D/_M; //歯数計算
ui->lE_Z->setText(QString::number(_Z)); //歯数表示
}
else if(ui->lE_M->text()=="") //モジュールが空白の場合
{
_M=_D/_Z; //モジュール計算
ui->lE_M->setText(QString::number(_M)); //モジュール表示
}
}
mainwindow.cppの全体コードは下記になります。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QRegExpValidator>
#include <QDebug> //追記
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
_idxTab=ui->tabWidget->currentIndex(); //開いているtab番号代入
_idxPsy=0; //物理計算インデックス初期化
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pB_Do_clicked()
{
_E=ui->lE_E->text().toFloat(); //電圧代入
_R=ui->lE_R->text().toFloat(); //抵抗値代入
_I=ui->lE_I->text().toFloat(); //電流値代入
_D=ui->lE_D->text().toFloat(); //直径代入
_Z=ui->lE_Z->text().toFloat(); //歯数代入
_M=ui->lE_M->text().toFloat(); //モジュール代入
switch(_idxTab)
{
case 0:
switch (_idxPsy)
{
case 0:
calcOhm(); //オームの法則計算
break;
case 1:
calcDstSpdTm(); //距離速度時間計算
break;
}
break;
case 1:
calcModule(); //モージュール計算
break;
}
}
//tab切り替え時のイベント
void MainWindow::on_tabWidget_currentChanged(int index)
{
_idxTab=ui->tabWidget->currentIndex(); //開いているtab番号代入
}
//物理計算内容切り替え時のイベント
void MainWindow::on_cmbBx_Physics_currentIndexChanged(int index)
{
_idxPsy=index;
switch (_idxPsy)
{
case 0:
ui->lbl_E->setText("電圧");
ui->lbl_R->setText("抵抗");
ui->lbl_I->setText("電流");
break;
case 1:
ui->lbl_E->setText("距離");
ui->lbl_R->setText("速度");
ui->lbl_I->setText("時間");
break;
}
}
void MainWindow::on_pB_Do_clicked()関数内のコードがかなり短くなったと思います。
ファイルを分け、関数化してコード見やすくする方法について解説しました。色々試して自分なりのコード整理術を磨いていくのも楽しいかもしれません。次回は単位を付け電卓を更に見やすくします。