commit 0196d4ab368669487fe0e49c4231efa5985c5009 Author: Darkheim Date: Sat Jul 12 19:11:31 2025 -0500 Initial commit: Qt Colculator with C++20 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d04ecfe --- /dev/null +++ b/.gitignore @@ -0,0 +1,27 @@ +# Build directories +build/ +cmake-build-*/ + +# Qt MOC files +moc_*.cpp +moc_*.h +*.moc + +# IDE files +.idea/ +.vscode/ +*.user +*.pro.user* + +# Executables +Calculator +*.exe + +# CMake +CMakeCache.txt +CMakeFiles/ +cmake_install.cmake +Makefile + +# Debug files +*.dSYM/ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..8700200 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.16) +project(Calculator) + +set(CMAKE_CXX_STANDARD 20) + +# Добавить флаги для отладки +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -g") +endif() + +find_package(Qt5 REQUIRED COMPONENTS Core Widgets) + +set(CMAKE_AUTOMOC ON) + +add_executable(Calculator main.cpp + Calculator.cpp + Calculator.h) + +target_link_libraries(Calculator Qt5::Core Qt5::Widgets) \ No newline at end of file diff --git a/Calculator.cpp b/Calculator.cpp new file mode 100644 index 0000000..63d231c --- /dev/null +++ b/Calculator.cpp @@ -0,0 +1,154 @@ +#include "Calculator.h" +#include +#include +#include +#include + + + Calculator::Calculator(QWidget *parent) : QWidget(parent) + { + setupUI(); // Set up the user interface + connectSignals(); // Connect signals and slots + setWindowTitle("Calculator"); // Set the window title + resize(300, 400); // Resize the window to a reasonable size + } + + void Calculator::setupUI() + { + auto *mainLayout = new QVBoxLayout(this); + + //Display setup + display = new QLineEdit("0"); + display -> setReadOnly(true); + display -> setAlignment(Qt::AlignRight); + display -> setStyleSheet("font-size: 18px; padding: 10px;"); + mainLayout -> addWidget(display); + + // Button grid + auto *gridLayout = new QGridLayout(); + + // Clear button + clearBtn = new QPushButton("C"); + gridLayout -> addWidget(clearBtn, 0, 0, 1, 4); + + // Number buttons + for (int i = 1; i <= 9; ++i) + { + auto *btn = new QPushButton(QString::number(i)); + int row = 3- (i - 1) / 3; + int col = (i - 1) % 3; + gridLayout -> addWidget(btn, row, col); + connect(btn, &QPushButton::clicked, this, &Calculator::digitClicked); + } + + //Zero button + auto *zeroBtn = new QPushButton("0"); + gridLayout -> addWidget(zeroBtn, 4, 0, 1, 2); + connect(zeroBtn, &QPushButton::clicked, this, &Calculator::digitClicked); + + // Decimal point button + auto *dotBtn = new QPushButton("."); + gridLayout -> addWidget(dotBtn, 4, 2); + connect(dotBtn, &QPushButton::clicked, this, &Calculator::digitClicked); + + // Operator buttons + auto *addBtn = new QPushButton("+"); + auto *subBtn = new QPushButton("-"); + auto *mulBtn = new QPushButton("*"); + auto *divBtn = new QPushButton("/"); + equalBtn = new QPushButton("="); + + gridLayout -> addWidget(divBtn, 1, 3); + gridLayout -> addWidget(mulBtn, 2, 3); + gridLayout -> addWidget(subBtn, 3, 3); + gridLayout -> addWidget(addBtn, 4, 3); + gridLayout -> addWidget(equalBtn, 5, 0, 1, 4); + + mainLayout -> addLayout(gridLayout); + + // Store buttons for connections + operatorButtons = {addBtn, subBtn, mulBtn, divBtn}; + } + + void Calculator::connectSignals() + { + for (auto *btn : operatorButtons) + { + connect(btn, &QPushButton::clicked, this, &Calculator::operatorClicked); + } + + connect(clearBtn, &QPushButton::clicked, this, &Calculator::clearDisplay); + connect(equalBtn, &QPushButton::clicked, this, &Calculator::calculateResult); + } + + void Calculator::digitClicked() + { + const auto *button = qobject_cast(sender()); // const auto* + const QString digit = button -> text(); // const + + if (waitingForOperand) { + display -> clear(); + waitingForOperand = false; + } + + if (display -> text() == "0" && digit != ".") { + display -> clear(); + } + + display -> setText(display -> text() + digit); + } + + void Calculator::operatorClicked() + { + auto *button = qobject_cast(sender()); + const QString op = button -> text(); + + if (!waitingForOperand && !operation.isEmpty()) { + calculateResult(); + } + + firstNumber = display -> text().toDouble(); + operation = op; + waitingForOperand = true; + } + + void Calculator::calculateResult() + { + if (waitingForOperand || operation.isEmpty()) { + return; // No operation to perform + } + + double secondNumber = display -> text().toDouble(); + double result = 0.0; + + if (operation == "+") + result = firstNumber + secondNumber; + else if (operation == "-") + result = firstNumber - secondNumber; + else if (operation == "*") + result = firstNumber * secondNumber; + else if (operation == "/") + { + if (secondNumber != 0) + result = firstNumber / secondNumber; + else + { + display -> setText("Error"); + clearDisplay(); + return; + } + } + + display -> setText(QString::number(result)); + operation.clear(); + waitingForOperand = true; + } + + void Calculator::clearDisplay() + { + display -> setText("0"); + firstNumber = 0.0; + operation.clear(); + waitingForOperand = true; + } + diff --git a/Calculator.h b/Calculator.h new file mode 100644 index 0000000..94f2c55 --- /dev/null +++ b/Calculator.h @@ -0,0 +1,44 @@ +#ifndef CALCULATOR_H +#define CALCULATOR_H + +#include +#include +#include +#include + + +class Calculator final : public QWidget{ + Q_OBJECT + +public: + explicit Calculator(QWidget *parent = nullptr); + ~Calculator() override = default; + + Calculator(const Calculator &) = delete; + Calculator &operator=(const Calculator &) = delete; + Calculator(Calculator &&) = delete; + Calculator &operator=(Calculator &&) = delete; + +private slots: + void digitClicked(); + void operatorClicked(); + void calculateResult(); + void clearDisplay(); + +private: + void setupUI(); + void connectSignals(); + + QLineEdit *display; + QPushButton *clearBtn; + QPushButton *equalBtn; + QList operatorButtons; + + double firstNumber = 0.0; + QString operation; + bool waitingForOperand = true; +}; + + + +#endif //CALCULATOR_H diff --git a/README.md b/README.md new file mode 100644 index 0000000..3d3e787 --- /dev/null +++ b/README.md @@ -0,0 +1,20 @@ +# Qt Calculator + +A simple calculator application built with Qt5 and C++20. + +## Features +- Basic arithmetic operations (+, -, *, /) +- Clear functionality +- Error handling for division by zero +- Modern C++ practices (Rule of Five) + +## Build Requirements +- Qt5 (Core, Widgets) +- CMake 3.16+ +- C++20 compatible compiler + +## Building +```bash +mkdir build && cd build +cmake .. +make \ No newline at end of file diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..90c8ec3 --- /dev/null +++ b/main.cpp @@ -0,0 +1,13 @@ +#include +#include "Calculator.h" + + +int main(int argc, char* argv[]) +{ + QApplication app(argc, argv); + + Calculator calculator; + calculator.show(); + + return app.exec(); +} \ No newline at end of file