서론

윈도우에서 제공하는 메모장처럼 새로열기, 열기, 저장 기능을 만들어보자

 

메뉴바 구현

메뉴바를 구현하기 위해서는 3가지가 필요하다.

1. 메뉴바

2. 메뉴바 위에 올릴 메뉴들

3. 메뉴를 누르면 실행할 액션들

따라서 QMenuBar, QMenu, QAcion들을 헤더파일에 포함시키면 된다.

 

notepad.h

#ifndef NOTEPAD_H
#define NOTEPAD_H

#include <QDialog>
#include <QMenuBar>
#include <QMenu>
#include <QAction>
#include <QFileDialog>
#include <QMessageBox>

namespace Ui {
class Notepad;
}

class Notepad : public QDialog
{
    Q_OBJECT

public:
    explicit Notepad(QWidget *parent = nullptr);
    ~Notepad();

private:
    Ui::Notepad *ui;
    QMenuBar *menuBar;
    QMenu *menu;

private slots:
    void openFile();
    void saveFile();
    void newFile();
};

#endif // NOTEPAD_H

 

구현하다가 어떤 기능들을 따로 추가할지 모르기에 QAction 객체는 전역변수로 따로 선언을 안했다.

cpp 파일에 필요할 때마다 추가하려고 한다.

 

notepad.cpp

#include "notepad.h"
#include "ui_notepad.h"



Notepad::Notepad(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Notepad)
{
    ui->setupUi(this);

    menuBar = new QMenuBar(this);

    menu = new QMenu("File");
    QAction *newAction = new QAction("New", this);
    QAction *openAction = new QAction("Open", this);
    QAction *saveAction = new QAction("Save", this);

    menu->addAction(newAction);
    menu->addAction(openAction);
    menu->addAction(saveAction);

    menuBar->addMenu(menu);

    connect(openAction, SIGNAL(triggered(bool)), this, SLOT(openFile()));
    connect(saveAction, SIGNAL(triggered(bool)), this, SLOT(saveFile()));
    connect(newAction, SIGNAL(triggered(bool)), this, SLOT(newFile()));
}

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

 

메뉴바를 최종적으로 만들기 위해서는 3가지 과정이 필요하다.

 

1. 메뉴바, 메뉴, 액션 선언하기

2. 메뉴에 액션 추가하기

3. 메뉴바에 메뉴 추가하기

 

간단하게 조각들을 일단 만들어둔 뒤 작은 것(액션 < 메뉴 < 메뉴바) 순서로 합쳐주는 과정이 필요하다.

 

그리고 슬롯 함수와 QAction의 시그널과 연결해주면 된다.

다음으로는 슬롯 함수 구성을 알아보자.

 

슬롯 함수 구현

openFile()

void Notepad::openFile(){
    QString currentText = ui->textEdit->toPlainText();
    if(!currentText.isEmpty()){
        QMessageBox::StandardButton reply = QMessageBox::warning(this, tr("Warning"), tr("텍스트가 존재합니다.\n그래도 새로운 파일을 여시겠습니까?"), QMessageBox::Yes | QMessageBox::No);
        if(reply == QMessageBox::Yes){
            QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), tr("/home/dps_debug/Dongyeop/"), tr("Text Files (*.txt);;All Files (*)"));

            if (!fileName.isEmpty()){
                getFileName(fileName);
            }
        }
    }else{
        QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), tr("/home/dps_debug/Dongyeop/"), tr("Text Files (*.txt);;All Files (*)"));

        if (!fileName.isEmpty()){
            getFileName(fileName);
        }
    }
}

//getFilename
void Notepad::getFileName(QString filename){
    QFile file(filename);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)){
        QMessageBox::warning(this, tr("Error"), tr("Cannot open file: ") + file.errorString());
        return;
    }

    QTextStream in(&file);
    QString fileContent = in.readAll();

    ui->textEdit->setPlainText(fileContent);
    file.close();
}

디렉토리에서 txt나 모든 파일들을 textEdit으로 불러오는 작업이다.

 

코드 순서는 이렇다.

  1. 현재 텍스트가 있는지 검사한다.
  2. 텍스트가 존재한다면 QMessageBox를 통해 현재 페이지를 지우고 새로 열 것인지, 열기를 안할 것인지 물어본다.
  3. 만약 새로 연다면 디렉토리 선택 상자를 열고 파일의 경로를 반환한다.
  4. 파일의 경로가 비어있지 않다면 QFile에 값을 전달한다.
  5. QFile이 읽기 전용인지, 텍스트인지 검사를 거쳐 예외처리를 한다.
  6. 아니라면 QTextStream으로 파일 값들을 불러온 후 String으로 처리 후 textEdit에 넣는다.

 


saveFile()

void Notepad::saveFile(){
    QString currentText = ui->textEdit->toPlainText();

    if(!currentText.isEmpty()){
        QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), "", tr("Text Files (*.txt);;All Files (*)"));

        if (!fileName.isEmpty()){
            QFile file(fileName);
            if (!file.open(QIODevice::WriteOnly | QIODevice::Text)){
                QMessageBox::warning(this, tr("Error"), tr("Cannot save file: ") + file.errorString());
                return;
            }

            QTextStream out(&file);
            out << ui->textEdit->toPlainText();  // QTextEdit의 텍스트 가져오기
            file.close();
        }
    }else{
        QMessageBox::about(this,tr("wait"), tr("notepad is empty"));
    }
}

textEdit에 쓴 글들을 저장하는 작업이다.

 

로직 순서는 아래와 같다.

  1. 현재 텍스트 값을 QString에 저장한다.
  2. QString 값이 존재하는지 판단
  3. 존재한다면 저장 디렉토리 상자를 열고 저장한다.
  4. 존재하지 않다면 메세지 발생


newFile()

void Notepad::newFile(){
    QString text = ui->textEdit->toPlainText();
    if(!text.isEmpty()){
        QMessageBox::StandardButton reply = QMessageBox::warning(this, tr("warning"), tr("really?"), QMessageBox::Yes | QMessageBox::No);
        if(reply == QMessageBox::Yes){
            ui->textEdit->setText("");
        }
    }else{
        ui->textEdit->setText("");
    }
}

파일을 새로 여는 작업이다.

 

로직 순서는 아래와 같다.

  1. 현재 텍스트 값을 QString에 저장한다.
  2. 현재 텍스트를 지우고 새로 작업을 할 것인지 물어본다.
  3. 새로 작업을 한다면 텍스트를 지운다.

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

QT - Thread (2) [공식문서를 살펴보자]  (2) 2024.07.22
Qt - Thread(1)  (1) 2024.07.22
QT - QFileDialog 사용해보기  (0) 2024.07.19
QT project - 타이머 구현하기  (0) 2024.07.17
QT project - 스톱워치 구현하기  (0) 2024.07.17