서론

QT의 구조와 slot&signal, 위젯들의 이해를 위해 간단한 계산기 프로그래밍을 해보자.

 

UI

윈도우가 제공하는 계산기 UI를 참고하였다. 진수 변환을 자주 사용하기 때문에 숫자를 입력하면 동적으로 진수 변환이 이뤄지게 하였다.

 

Headers/mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

private :
    char operation_flag = 0;
    char reset_mode = 0;
    double first_num = 0;
    char plus_minus_flag = 0;
    char dot_flag = 0;


public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    void ProceessNum(int num);
    void ProcessOperation(char operation_flag);

private slots:
    void on_Number0_button_clicked();

    void on_Number1_button_clicked();

    void on_Number2_button_clicked();

    void on_Number3_button_clicked();

    void on_Number4_button_clicked();

    void on_Number5_button_clicked();

    void on_Number6_button_clicked();

    void on_Number7_button_clicked();

    void on_Number8_button_clicked();

    void on_Number9_button_clicked();

    void on_Reciprocal_clicked();

    void on_Square_button_clicked();

    void on_quareRoot_button_clicked();

    void on_CE_button_clicked();

    void on_C_button_clicked();

    void on_PlusMinus_button_clicked();

    void on_Sum_button_clicked();

    void on_Sub_button_clicked();

    void on_Mul_button_clicked();

    void on_Div_button_clicked();

    void on_Back_button_clicked();

    void on_Equal_button_clicked();

    void on_Dot_button_clicked();

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

 

operation_flag 변수는 현재 연산할 기호의 프래그값이다.

reset_mode는 현재 입력한 값이 첫번째 값인지, 두번째 값인지 설정하는 값이다.

first_num은 연산할 첫번째 입력 값이다.

plus_minus_flag는 현재 음수값인지, 양수값인지 확인하는 값이다.

dot_flag는 현재 소수값을 입력하는지 확인하는 값이다.

 

Sources/mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->lineEdit->setText("0");
    ui->current_lineEdit->setText("0");
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::ProceessNum(int num){
    QString current = ui->lineEdit->text();

    if (!reset_mode) {
        if(current == "0"){
            ui->lineEdit->setText(QString::number(num));
        }else{
            ui->lineEdit->setText(current + QString::number(num));
        }
    } else {  // reset_mode == 0
        reset_mode = 0;
        ui->lineEdit->setText(QString::number(num));
    }

    int value = ui->lineEdit->text().toInt();

    QString binaryString = QString::number(value, 2);
    int padding = 4 - (binaryString.length() % 4);
    if (padding != 4) {
        binaryString = QString(padding, '0') + binaryString;
    }
    for (int i = 4; i < binaryString.length(); i += 5) {
        binaryString.insert(i, ' ');
    }
    ui->Bin_lineEdit->setText(binaryString);

    QString octalString = QString::number(value, 8);
    ui->Oct_lineEdit->setText(octalString);

    QString hexString = QString::number(value, 16).toUpper();
    ui->Hex_lineEdit->setText(hexString);

}

void MainWindow::ProcessOperation(char get_operation_flag){
    operation_flag = get_operation_flag;
    reset_mode = 1;
    first_num = ui->lineEdit->text().toDouble();

    switch(get_operation_flag){
    case 1:
        ui->current_lineEdit->setText(QString::number(first_num) + " + ");
        break;
    case 2:
        ui->current_lineEdit->setText(QString::number(first_num) + " - ");
        break;
    case 3:
        ui->current_lineEdit->setText(QString::number(first_num) + " * ");
        break;
    case 4:
        ui->current_lineEdit->setText(QString::number(first_num) + " % ");
        break;
    }
}

// 0
void MainWindow::on_Number0_button_clicked()
{
    ProceessNum(0);
}

// 1
void MainWindow::on_Number1_button_clicked()
{
    ProceessNum(1);
}

// 2
void MainWindow::on_Number2_button_clicked()
{
    ProceessNum(2);
}

// 3
void MainWindow::on_Number3_button_clicked()
{
    ProceessNum(3);
}

// 4
void MainWindow::on_Number4_button_clicked()
{
    ProceessNum(4);
}

// 5
void MainWindow::on_Number5_button_clicked()
{
    ProceessNum(5);
}

// 6
void MainWindow::on_Number6_button_clicked()
{
    ProceessNum(6);
}

// 7
void MainWindow::on_Number7_button_clicked()
{
    ProceessNum(7);
}

// 8
void MainWindow::on_Number8_button_clicked()
{
    ProceessNum(8);
}

// 9
void MainWindow::on_Number9_button_clicked()
{
    ProceessNum(9);
}

// 1/x
void MainWindow::on_Reciprocal_clicked()
{
    double num = 1.0 / ui->lineEdit->text().toDouble();
    ui->lineEdit->setText(QString::number(num,'f',5));
}

// x^2
void MainWindow::on_Square_button_clicked()
{
    double num = ui->lineEdit->text().toDouble();
    ui->lineEdit->setText(QString::number(num*num));
}

// √x
void MainWindow::on_quareRoot_button_clicked()
{
    double num = ui->lineEdit->text().toDouble();
    double root = 1.0;

    for(int i=0; i<100; i++){
        root = 0.5 * (root + num/root);
    }

    ui->lineEdit->setText(QString::number(root));
}

// CE
void MainWindow::on_CE_button_clicked()
{
    ui->lineEdit->setText("0");
    ui->current_lineEdit->setText("0");
    ui->Bin_lineEdit->setText("0");
    ui->Oct_lineEdit->setText("0");
    ui->Hex_lineEdit->setText("0");

    operation_flag = 0;
    first_num = 0;
    reset_mode = 0;
}

// C
void MainWindow::on_C_button_clicked()
{
    ui->lineEdit->setText("0");
    ui->Bin_lineEdit->setText("0");
    ui->Oct_lineEdit->setText("0");
    ui->Hex_lineEdit->setText("0");

}

// +/-
void MainWindow::on_PlusMinus_button_clicked()
{
    double num = ui->lineEdit->text().toDouble();
    if(!plus_minus_flag){
        num = -num;
        ui->lineEdit->setText(QString::number(num));
    }else{
        num = +num;
        ui->lineEdit->setText(QString::number(num));
    }
}

// +
void MainWindow::on_Sum_button_clicked()
{
    ProcessOperation(1);
}

// -
void MainWindow::on_Sub_button_clicked()
{
    ProcessOperation(2);
}

// *
void MainWindow::on_Mul_button_clicked()
{
    ProcessOperation(3);
}

// %
void MainWindow::on_Div_button_clicked()
{
    ProcessOperation(4);
}

// <-
void MainWindow::on_Back_button_clicked()
{
    int num = ui->lineEdit->text().toInt() / 10;
    ui->lineEdit->setText(QString::number(num));

    int value = ui->lineEdit->text().toInt();

    QString binaryString = QString::number(value, 2);
    int padding = 4 - (binaryString.length() % 4);
    if (padding != 4) {
        binaryString = QString(padding, '0') + binaryString;
    }
    for (int i = 4; i < binaryString.length(); i += 5) {
        binaryString.insert(i, ' ');
    }
    ui->Bin_lineEdit->setText(binaryString);

    QString octalString = QString::number(value, 8);
    ui->Oct_lineEdit->setText(octalString);

    QString hexString = QString::number(value, 16).toUpper();
    ui->Hex_lineEdit->setText(hexString);
}

// .
void MainWindow::on_Dot_button_clicked()
{
    QString current = ui->lineEdit->text();

    dot_flag = 1;

    if(!current.contains('.')){
        ui->lineEdit->setText(current + ".");
    }
}

// =
void MainWindow::on_Equal_button_clicked()
{
    double second_num = ui->lineEdit->text().toDouble();
    double result = 0;
    QString operation;

    switch(operation_flag){
    case 1: // add
        result = first_num + second_num;
        operation = QString(" + ");
        break;
    case 2: // sub
        result = first_num - second_num;
        operation = QString(" - ");
        break;
    case 3: // mul
        result = first_num * second_num;
        operation = QString(" * ");
        break;
    case 4: // div
        result = first_num / second_num;
        operation = QString(" % ");
        break;
    }

    ui->lineEdit->setText(QString::number(result));
    ui->current_lineEdit->setText(QString::number(first_num) + operation + QString::number(second_num) + " = ");

    int value = ui->lineEdit->text().toInt();

    QString binaryString = QString::number(value, 2);
    int padding = 4 - (binaryString.length() % 4);
    if (padding != 4) {
        binaryString = QString(padding, '0') + binaryString;
    }
    for (int i = 4; i < binaryString.length(); i += 5) {
        binaryString.insert(i, ' ');
    }
    ui->Bin_lineEdit->setText(binaryString);

    QString octalString = QString::number(value, 8);
    ui->Oct_lineEdit->setText(octalString);

    QString hexString = QString::number(value, 16).toUpper();
    ui->Hex_lineEdit->setText(hexString);

    reset_mode = 1;
}

 

처음 진수 변환할 때 진수 변환 공식을 사용하려 했지만 QString::number에 기능이 있는걸 확인하고 사용했다.

 

사용법은

QString::number(값, 몇진수) 이렇게 사용하면 된다. 매개변수 값으로 더 추가해서 0을 채워넣을 수 있다.

'🌠Development > QT' 카테고리의 다른 글

QT - Signal and Slot (2)  (0) 2024.07.12
QT - Signal and Slot (1)  (0) 2024.07.11
QT - Layout  (1) 2024.07.11
QT - 기본 코드 살펴보기  (1) 2024.07.05
QT - 프로그래밍의 시작  (0) 2024.07.05