Small fixes
This commit is contained in:
parent
0196d4ab36
commit
ec4da11bb8
24
.gitattributes
vendored
Normal file
24
.gitattributes
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# Set default behavior to automatically normalize line endings
|
||||||
|
* text=auto
|
||||||
|
|
||||||
|
# C++ source files
|
||||||
|
*.cpp text diff=cpp
|
||||||
|
*.h text diff=cpp
|
||||||
|
|
||||||
|
# CMake files
|
||||||
|
CMakeLists.txt text
|
||||||
|
*.cmake text
|
||||||
|
|
||||||
|
# QMake files
|
||||||
|
*.pro text
|
||||||
|
|
||||||
|
# Bash scripts
|
||||||
|
*.sh text eol=lf
|
||||||
|
|
||||||
|
# Documentation
|
||||||
|
*.md text diff=markdown
|
||||||
|
|
||||||
|
# Binary files
|
||||||
|
*.png binary
|
||||||
|
*.jpg binary
|
||||||
|
*.ico binary
|
||||||
31
.github/workflows/build.yml
vendored
Normal file
31
.github/workflows/build.yml
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
name: Build Qt Calculator
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ main ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Install Qt
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y qtbase5-dev qt5-qmake cmake
|
||||||
|
|
||||||
|
- name: Configure CMake
|
||||||
|
run: cmake -B ${{github.workspace}}/build
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: cmake --build ${{github.workspace}}/build
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
working-directory: ${{github.workspace}}/build
|
||||||
|
run: |
|
||||||
|
echo "Running built application to verify it works"
|
||||||
|
# Add tests if you implement them later
|
||||||
@ -8,9 +8,26 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -g")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -g")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(Qt5 REQUIRED COMPONENTS Core Widgets)
|
# Установить пути поиска для Qt5
|
||||||
|
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "/usr/lib/qt5" "/usr/lib/x86_64-linux-gnu/qt5" "/usr/lib/cmake/Qt5")
|
||||||
|
|
||||||
|
# Альтернативный способ поиска Qt5
|
||||||
|
if(NOT Qt5_DIR)
|
||||||
|
set(Qt5_DIR "/usr/lib/cmake/Qt5")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Настройка Qt5 и пути модулей
|
||||||
|
find_package(Qt5 COMPONENTS Core Widgets QUIET)
|
||||||
|
|
||||||
|
# Проверка наличия Qt5
|
||||||
|
if(NOT Qt5_FOUND)
|
||||||
|
message(FATAL_ERROR "Qt5 не найден. Установите пакеты Qt5: sudo apt install qtbase5-dev qt5-qmake")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Включение автоматической генерации MOC-файлов для Qt
|
||||||
set(CMAKE_AUTOMOC ON)
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
set(CMAKE_AUTORCC ON)
|
||||||
|
set(CMAKE_AUTOUIC ON)
|
||||||
|
|
||||||
add_executable(Calculator main.cpp
|
add_executable(Calculator main.cpp
|
||||||
Calculator.cpp
|
Calculator.cpp
|
||||||
|
|||||||
@ -5,50 +5,50 @@
|
|||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
|
||||||
|
|
||||||
Calculator::Calculator(QWidget *parent) : QWidget(parent)
|
Calculator::Calculator(QWidget *parent) : QWidget(parent)
|
||||||
{
|
{
|
||||||
setupUI(); // Set up the user interface
|
setupUI(); // Set up the user interface
|
||||||
connectSignals(); // Connect signals and slots
|
connectSignals(); // Connect signals and slots
|
||||||
setWindowTitle("Calculator"); // Set the window title
|
setWindowTitle("Calculator"); // Set the window title
|
||||||
resize(300, 400); // Resize the window to a reasonable size
|
resize(300, 400); // Resize the window to a reasonable size
|
||||||
}
|
}
|
||||||
|
|
||||||
void Calculator::setupUI()
|
void Calculator::setupUI()
|
||||||
{
|
{
|
||||||
auto *mainLayout = new QVBoxLayout(this);
|
auto *mainLayout = new QVBoxLayout(this);
|
||||||
|
|
||||||
//Display setup
|
// Display setup
|
||||||
display = new QLineEdit("0");
|
display = new QLineEdit("0");
|
||||||
display -> setReadOnly(true);
|
display->setReadOnly(true);
|
||||||
display -> setAlignment(Qt::AlignRight);
|
display->setAlignment(Qt::AlignRight);
|
||||||
display -> setStyleSheet("font-size: 18px; padding: 10px;");
|
display->setStyleSheet("font-size: 18px; padding: 10px;");
|
||||||
mainLayout -> addWidget(display);
|
mainLayout->addWidget(display);
|
||||||
|
|
||||||
// Button grid
|
// Button grid
|
||||||
auto *gridLayout = new QGridLayout();
|
auto *gridLayout = new QGridLayout();
|
||||||
|
|
||||||
// Clear button
|
// Clear button
|
||||||
clearBtn = new QPushButton("C");
|
clearBtn = new QPushButton("C");
|
||||||
gridLayout -> addWidget(clearBtn, 0, 0, 1, 4);
|
gridLayout->addWidget(clearBtn, 0, 0, 1, 4);
|
||||||
|
|
||||||
// Number buttons
|
// Number buttons
|
||||||
for (int i = 1; i <= 9; ++i)
|
for (int i = 1; i <= 9; ++i)
|
||||||
{
|
{
|
||||||
auto *btn = new QPushButton(QString::number(i));
|
auto *btn = new QPushButton(QString::number(i));
|
||||||
int row = 3- (i - 1) / 3;
|
int row = 3 - (i - 1) / 3;
|
||||||
int col = (i - 1) % 3;
|
int col = (i - 1) % 3;
|
||||||
gridLayout -> addWidget(btn, row, col);
|
gridLayout->addWidget(btn, row, col);
|
||||||
connect(btn, &QPushButton::clicked, this, &Calculator::digitClicked);
|
connect(btn, &QPushButton::clicked, this, &Calculator::digitClicked);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Zero button
|
// Zero button
|
||||||
auto *zeroBtn = new QPushButton("0");
|
auto *zeroBtn = new QPushButton("0");
|
||||||
gridLayout -> addWidget(zeroBtn, 4, 0, 1, 2);
|
gridLayout->addWidget(zeroBtn, 4, 0, 1, 2);
|
||||||
connect(zeroBtn, &QPushButton::clicked, this, &Calculator::digitClicked);
|
connect(zeroBtn, &QPushButton::clicked, this, &Calculator::digitClicked);
|
||||||
|
|
||||||
// Decimal point button
|
// Decimal point button
|
||||||
auto *dotBtn = new QPushButton(".");
|
auto *dotBtn = new QPushButton(".");
|
||||||
gridLayout -> addWidget(dotBtn, 4, 2);
|
gridLayout->addWidget(dotBtn, 4, 2);
|
||||||
connect(dotBtn, &QPushButton::clicked, this, &Calculator::digitClicked);
|
connect(dotBtn, &QPushButton::clicked, this, &Calculator::digitClicked);
|
||||||
|
|
||||||
// Operator buttons
|
// Operator buttons
|
||||||
@ -58,13 +58,13 @@
|
|||||||
auto *divBtn = new QPushButton("/");
|
auto *divBtn = new QPushButton("/");
|
||||||
equalBtn = new QPushButton("=");
|
equalBtn = new QPushButton("=");
|
||||||
|
|
||||||
gridLayout -> addWidget(divBtn, 1, 3);
|
gridLayout->addWidget(divBtn, 1, 3);
|
||||||
gridLayout -> addWidget(mulBtn, 2, 3);
|
gridLayout->addWidget(mulBtn, 2, 3);
|
||||||
gridLayout -> addWidget(subBtn, 3, 3);
|
gridLayout->addWidget(subBtn, 3, 3);
|
||||||
gridLayout -> addWidget(addBtn, 4, 3);
|
gridLayout->addWidget(addBtn, 4, 3);
|
||||||
gridLayout -> addWidget(equalBtn, 5, 0, 1, 4);
|
gridLayout->addWidget(equalBtn, 5, 0, 1, 4);
|
||||||
|
|
||||||
mainLayout -> addLayout(gridLayout);
|
mainLayout->addLayout(gridLayout);
|
||||||
|
|
||||||
// Store buttons for connections
|
// Store buttons for connections
|
||||||
operatorButtons = {addBtn, subBtn, mulBtn, divBtn};
|
operatorButtons = {addBtn, subBtn, mulBtn, divBtn};
|
||||||
@ -83,31 +83,31 @@
|
|||||||
|
|
||||||
void Calculator::digitClicked()
|
void Calculator::digitClicked()
|
||||||
{
|
{
|
||||||
const auto *button = qobject_cast<QPushButton *>(sender()); // const auto*
|
const auto *button = qobject_cast<QPushButton *>(sender());
|
||||||
const QString digit = button -> text(); // const
|
const QString digit = button->text();
|
||||||
|
|
||||||
if (waitingForOperand) {
|
if (waitingForOperand) {
|
||||||
display -> clear();
|
display->clear();
|
||||||
waitingForOperand = false;
|
waitingForOperand = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (display -> text() == "0" && digit != ".") {
|
if (display->text() == "0" && digit != ".") {
|
||||||
display -> clear();
|
display->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
display -> setText(display -> text() + digit);
|
display->setText(display->text() + digit);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Calculator::operatorClicked()
|
void Calculator::operatorClicked()
|
||||||
{
|
{
|
||||||
auto *button = qobject_cast<QPushButton *>(sender());
|
auto *button = qobject_cast<QPushButton *>(sender());
|
||||||
const QString op = button -> text();
|
const QString op = button->text();
|
||||||
|
|
||||||
if (!waitingForOperand && !operation.isEmpty()) {
|
if (!waitingForOperand && !operation.isEmpty()) {
|
||||||
calculateResult();
|
calculateResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
firstNumber = display -> text().toDouble();
|
firstNumber = display->text().toDouble();
|
||||||
operation = op;
|
operation = op;
|
||||||
waitingForOperand = true;
|
waitingForOperand = true;
|
||||||
}
|
}
|
||||||
@ -118,7 +118,7 @@
|
|||||||
return; // No operation to perform
|
return; // No operation to perform
|
||||||
}
|
}
|
||||||
|
|
||||||
double secondNumber = display -> text().toDouble();
|
double secondNumber = display->text().toDouble();
|
||||||
double result = 0.0;
|
double result = 0.0;
|
||||||
|
|
||||||
if (operation == "+")
|
if (operation == "+")
|
||||||
@ -133,20 +133,20 @@
|
|||||||
result = firstNumber / secondNumber;
|
result = firstNumber / secondNumber;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
display -> setText("Error");
|
display->setText("Error");
|
||||||
clearDisplay();
|
clearDisplay();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
display -> setText(QString::number(result));
|
display->setText(QString::number(result));
|
||||||
operation.clear();
|
operation.clear();
|
||||||
waitingForOperand = true;
|
waitingForOperand = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Calculator::clearDisplay()
|
void Calculator::clearDisplay()
|
||||||
{
|
{
|
||||||
display -> setText("0");
|
display->setText("0");
|
||||||
firstNumber = 0.0;
|
firstNumber = 0.0;
|
||||||
operation.clear();
|
operation.clear();
|
||||||
waitingForOperand = true;
|
waitingForOperand = true;
|
||||||
|
|||||||
78
README.md
78
README.md
@ -3,18 +3,86 @@ # Qt Calculator
|
|||||||
A simple calculator application built with Qt5 and C++20.
|
A simple calculator application built with Qt5 and C++20.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Basic arithmetic operations (+, -, *, /)
|
- Basic arithmetic operations (+, -, *, /)
|
||||||
- Clear functionality
|
- Clear functionality
|
||||||
- Error handling for division by zero
|
- Error handling for division by zero
|
||||||
- Modern C++ practices (Rule of Five)
|
- Modern C++ practices (Rule of Five implementation)
|
||||||
|
|
||||||
## Build Requirements
|
## Requirements
|
||||||
- Qt5 (Core, Widgets)
|
|
||||||
- CMake 3.16+
|
To compile and run this project, you need:
|
||||||
|
|
||||||
|
- CMake 3.16 or higher
|
||||||
|
- Qt5 (Core and Widgets)
|
||||||
- C++20 compatible compiler
|
- C++20 compatible compiler
|
||||||
|
|
||||||
## Building
|
## Installing Dependencies
|
||||||
|
|
||||||
|
### Ubuntu/Debian:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Full development environment
|
||||||
|
sudo apt install qtcreator qtbase5-dev qt5-qmake qtbase5-dev-tools cmake
|
||||||
|
|
||||||
|
# Minimal required packages
|
||||||
|
sudo apt install qtbase5-dev qt5-qmake cmake
|
||||||
|
```
|
||||||
|
|
||||||
|
### Verifying Qt5 Installation
|
||||||
|
|
||||||
|
Check if Qt5 packages are installed and locate them:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dpkg -l | grep qt5
|
||||||
|
find /usr -name "Qt5Config.cmake"
|
||||||
|
```
|
||||||
|
|
||||||
|
If Qt5Config.cmake is not found, install the necessary packages:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt install qtbase5-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### Fedora:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo dnf install qt5-qtbase-devel qt5-qttools-devel qt-creator cmake
|
||||||
|
```
|
||||||
|
|
||||||
|
### Arch Linux:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo pacman -S qt5-base qt5-tools qtcreator cmake
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building the Project
|
||||||
|
|
||||||
|
### Using CMake (recommended)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
cmake ..
|
cmake ..
|
||||||
make
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using QMake (alternative)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
qmake qt-project.pro
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running the Application
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./Calculator
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting Qt5 Find Issues
|
||||||
|
|
||||||
|
If CMake cannot find Qt5, you can specify the Qt5 path manually:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cmake -DQt5_DIR=/path/to/qt5/lib/cmake/Qt5 ..
|
||||||
|
```
|
||||||
21
build.sh
Normal file
21
build.sh
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Check for Qt5 installation
|
||||||
|
if ! dpkg -l | grep -q qtbase5-dev; then
|
||||||
|
echo "Qt5 is not installed. Installing required packages..."
|
||||||
|
sudo apt install -y qtbase5-dev qt5-qmake cmake
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create build directory
|
||||||
|
mkdir -p build
|
||||||
|
cd build
|
||||||
|
|
||||||
|
# Configure CMake with Qt5 paths
|
||||||
|
cmake .. \
|
||||||
|
-DQt5_DIR=/usr/lib/cmake/Qt5 \
|
||||||
|
-DCMAKE_PREFIX_PATH=/usr/lib/x86_64-linux-gnu/cmake
|
||||||
|
|
||||||
|
# Build the project
|
||||||
|
make
|
||||||
|
|
||||||
|
echo "Build completed. Run the calculator with: ./build/Calculator"
|
||||||
17
qt-project.pro
Normal file
17
qt-project.pro
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# Alternative project file for Qt Creator and qmake
|
||||||
|
|
||||||
|
QT += core widgets
|
||||||
|
CONFIG += c++20
|
||||||
|
|
||||||
|
TARGET = Calculator
|
||||||
|
TEMPLATE = app
|
||||||
|
|
||||||
|
SOURCES += main.cpp \
|
||||||
|
Calculator.cpp
|
||||||
|
|
||||||
|
HEADERS += Calculator.h
|
||||||
|
|
||||||
|
# Default rules for deployment.
|
||||||
|
qnx: target.path = /tmp/$${TARGET}/bin
|
||||||
|
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||||
|
!isEmpty(target.path): INSTALLS += target
|
||||||
Loading…
Reference in New Issue
Block a user