본문 바로가기
대외활동/시스템프로그래밍

0807 QT 에디터 & 액션

by hoshi03 2024. 8. 7.

• 에디터

#include "qteditor.h"
#include <QTextEdit>
#include <QMenuBar>
#include <QMenu>
#include <QAction>

QtEditor::QtEditor(QWidget *parent): QMainWindow(parent)
{
    QTextEdit *text = new QTextEdit(this);
    setCentralWidget(text);

    //상단에 메뉴바 생성
    QMenuBar *bar = new QMenuBar(this);
    setMenuBar(bar);
    //메뉴바에 메뉴 넣기
    QMenu *fileMenu1 = bar->addMenu("&파일");
    QMenu *fileMenu2 = bar->addMenu("&편집");
    QMenu *fileMenu3 = bar->addMenu("&서식");
    QMenu *fileMenu4 = bar->addMenu("&보기");
    QMenu *fileMenu5 = bar->addMenu("&도움말");
    QMenu *fileMenu6 = bar->addMenu("&종료");

    //메뉴에 하위 메뉴 넣기
    // QMenu *subMenu1 = fileMenu1->addMenu("&subMenu1");
    // QMenu *subMenu2 = fileMenu1->addMenu("&subMenu2");

    //액션 등록해서 편집 메뉴에서 클릭하거나/숏컷 실행시 실행되게 만들어주기
    // QAction *act = new QAction(QIcon(":/new/prefix1/resources/bold.png"), "&new",this);
    // act->setShortcut(tr("ctrl+N"));
    // act->setStatusTip(tr("make new one"));
    // connect(act, SIGNAL(triggered()), SLOT(newFile()));

    // fileMenu2->addAction(act);

    QAction *newAct =  makeAction(":/new/prefix1/resources/create.png", "&new",
                                 "ctrl+N", "make new one",this ,SLOT(newFile()));
    fileMenu1->addAction(newAct);

    QAction *quitAct =  makeAction(":/new/prefix1/resources/exit.png", "&quit",
                                  "ctrl+Q", "program quit", this ,SLOT(quitProgram()));
    fileMenu6->addAction(quitAct);
}

//액션 추가 위에 4줄을 한번에 수행하는 메서드
QAction *QtEditor::makeAction(QString icon, QString text, QString shortCut, QString toolTip, QObject* recv, const char* slot){
    QAction *act = new QAction(text,this);
    if(icon.length()) act->setIcon(QIcon(icon));
    act->setShortcut(shortCut);
    act->setStatusTip(toolTip);
    connect(act, SIGNAL(triggered()), recv, slot);
    return act;
}

QtEditor::~QtEditor() {}

// 액션으로 동작할 슬롯 함수들
void QtEditor::newFile(){
    qDebug() << "new file";
}

void QtEditor::quitProgram(){
    qDebug() << "quit Program";
}

 

메인 윈도우에 원하는 메뉴나 에디터 등을 사용자가 원하는 만큼 추가해서 ui를 만들 수 있다

QTextEdit *text = new QTextEdit(this);
    setCentralWidget(text);

    //상단에 메뉴바 생성
    QMenuBar *bar = new QMenuBar(this);
    setMenuBar(bar);
    //메뉴바에 메뉴 넣기
    QMenu *fileMenu1 = bar->addMenu("&파일");
    QMenu *fileMenu2 = bar->addMenu("&편집");
    QMenu *fileMenu3 = bar->addMenu("&서식");
    QMenu *fileMenu4 = bar->addMenu("&보기");
    QMenu *fileMenu5 = bar->addMenu("&도움말");
    QMenu *fileMenu6 = bar->addMenu("&종료");

    //메뉴에 하위 메뉴 넣기
    QMenu *subMenu1 = fileMenu1->addMenu("&subMenu1");
    QMenu *subMenu2 = fileMenu1->addMenu("&subMenu2");
    
    //메뉴에 하위 메뉴 넣기
    QMenu *subMenu1 = fileMenu1->addMenu("&subMenu1");
    QMenu *subMenu2 = fileMenu1->addMenu("&subMenu2");

 

• 액션

 

슬롯 메서드를 만들고 QAction을 추가해서 특정 메뉴를 클릭하면 동작하거나 단축키로 동작하는 시그널을 만들 수 있다

    QAction *act = new QAction(QIcon(":/new/prefix1/resources/bold.png"), "&new",this);
    act->setShortcut(tr("ctrl+N"));
    act->setStatusTip(tr("make new one"));
    connect(act, SIGNAL(triggered()), SLOT(newFile()));
    
    fileMenu2->addAction(act);

ctrl+n이나 클릭하면 newfile 메서드를 실행하는 액션

 

할때마다 저렇게 함수 4줄을 하는 건 액션이 많아질 수록 비효율적이기 때문에 한번에 액션을 추가하는 메서드를 생성한다

QAction *QtEditor::makeAction(QString icon, QString text, QString shortCut, QString toolTip, QObject* recv, const char* slot){
    QAction *act = new QAction(text,this);
    if(icon.length()) act->setIcon(QIcon(icon));
    act->setShortcut(shortCut);
    act->setStatusTip(toolTip);
    connect(act, SIGNAL(triggered()), recv, slot);
    return act;
}
QAction *newAct =  makeAction(":/new/prefix1/resources/create.png", "&new",
	"ctrl+N", "make new one",this ,SLOT(newFile()));
    fileMenu1->addAction(newAct);

 

makeAction 메서드를 이용하면 액션을 함수 하나로 등록할 수 있다

 

• 툴바

new, quit 부분이 툴바 추가한 모습

QToolBar로 툴바를 추가한다

QToolBar *tool = addToolBar("&File");
    tool->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
    tool->addAction(newAct);
    tool->addSeparator();
    tool->addAction(quitAct);

 

- 툴바 on/off (토글) 기능 추가하기

    QMenu *winMenu = bar->addMenu("&window");
    QMenu *toolbarMenu = winMenu->addMenu("&toolbar");
    toolbarMenu->addAction(tool->toggleViewAction());

 

툴바는 toggleViewAction() 메서드로 키고 끌 수 있다

 

• 스테이터스 바

 

!하단바

    QStatusBar *status = statusBar();
    QLabel *statusLabel = new QLabel(tr("Qt Editor"),status);
    statusLabel->setObjectName("statusLabel");
    status->addPermanentWidget(statusLabel);
    status->showMessage("started");

 

 

-- mdi(다중 문서 인터페이스)

현재 가리키는 창에서 복/붙 작업이 가능하게 했다

#ifndef QTEDITOR_H
#define QTEDITOR_H

#include <QMainWindow>
#include <QTextEdit>
#include <QMdiArea>

class QtEditor : public QMainWindow
{
    Q_OBJECT


private:
    QAction *makeAction(QString icon, QString text, QString shortCut, QString toolTip, QObject* recv, const char* slot);
    QMdiArea *mdiArea;

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

public slots:
    void quitProgram();
    QTextEdit * newFile();
    void updateActions();
};

#endif // QTEDITOR_H

 

#include "qteditor.h"
#include <QTextEdit>
#include <QMenuBar>
#include <QMenu>
#include <QAction>
#include <QToolBar>
#include <QStatusBar>
#include <QLabel>
#include <QTextEdit>
#include <QDockWidget>
#include <QMdiSubWindow>

QtEditor::QtEditor(QWidget *parent): QMainWindow(parent)
{
    mdiArea = new QMdiArea(this);
    setCentralWidget(mdiArea);

#if 1
    QTextEdit * textedit = new QTextEdit(this);
    mdiArea->addSubWindow(textedit);

#else
    QTextEdit *textedit = newFile();
#endif

    QWidget* w = new QWidget(this);
    QLabel *label = new QLabel("Dock Widget", w);
    QDockWidget *dock = new QDockWidget("Dock widget", this);
    dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
    addDockWidget(Qt::RightDockWidgetArea,dock);
    dock->setWidget(w);

    QMenuBar *bar = new QMenuBar(this);
    setMenuBar(bar);

    QMenu *fileMenu1 = bar->addMenu("&파일");
    QMenu *fileMenu2 = bar->addMenu("&편집");
    QMenu *fileMenu3 = bar->addMenu("&서식");
    QMenu *fileMenu4 = bar->addMenu("&보기");
    QMenu *fileMenu5 = bar->addMenu("&도움말");
    QMenu *fileMenu6 = bar->addMenu("&종료");

    QAction *newAct = makeAction(":/new/prefix1/resources/create.png", "&new",
                                 "ctrl+N", "make new one", this, SLOT(newFile()));
    fileMenu1->addAction(newAct);

    QAction *copyAct = makeAction(":/new/prefix1/resources/copy.png", "&copy",
                                  "ctrl+1", "file copy", nullptr, SLOT(copy()));
    fileMenu2->addAction(copyAct);

    QAction *pasteAct = makeAction(":/new/prefix1/resources/paste.png", "&paste",
                                   "ctrl+2", "file paste", nullptr, SLOT(paste()));
    fileMenu2->addAction(pasteAct);

    QAction *quitAct = makeAction(":/new/prefix1/resources/exit.png", "&quit",
                                  "ctrl+Q", "quit program", this, SLOT(quitProgram()));
    fileMenu6->addAction(quitAct);

    QToolBar *tool = addToolBar("&File");
    tool->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
    tool->addAction(newAct);
    tool->addAction(copyAct);
    tool->addAction(pasteAct);
    tool->addAction(quitAct);

    QMenu *winMenu = bar->addMenu("&window");
    QMenu *toolbarMenu = winMenu->addMenu("&toolbar");
    toolbarMenu->addAction(tool->toggleViewAction());

    QStatusBar *status = statusBar();
    QLabel *statusLabel = new QLabel(tr("Qt Editor"), status);
    statusLabel->setObjectName("statusLabel");
    status->addPermanentWidget(statusLabel);
    status->showMessage("started");

    tool->addAction(dock->toggleViewAction());

    // mdiArea의 활성화된 서브 윈도우가 변경될 때 호출되는 슬롯 연결
    connect(mdiArea, &QMdiArea::subWindowActivated, this, &QtEditor::updateActions);
}

// 액션 추가 위에 4줄을 한번에 수행하는 메서드
QAction *QtEditor::makeAction(QString icon, QString text, QString shortCut, QString toolTip, QObject* recv, const char* slot) {
    QAction *act = new QAction(text, this);
    if (icon.length()) act->setIcon(QIcon(icon));
    act->setShortcut(shortCut);
    act->setStatusTip(toolTip);
    if (recv && slot) {
        connect(act, SIGNAL(triggered()), recv, slot);
    }
    return act;
}

QtEditor::~QtEditor() {}

// 액션으로 동작할 슬롯 함수들

void QtEditor::quitProgram() {
    qDebug() << "quit Program";
    exit(0);
}

QTextEdit* QtEditor::newFile() {
    qDebug("make new");
    QTextEdit* textedit = new QTextEdit;
    mdiArea->addSubWindow(textedit);
    textedit->show();
    updateActions();
    return textedit;
}


// 현재 활성화된 QTextEdit 인스턴스에 액션 연결
void QtEditor::updateActions() {
    QMdiSubWindow *activeSubWindow = mdiArea->activeSubWindow();
    QWidget *widget = activeSubWindow->widget();
    QTextEdit *activeEditor = dynamic_cast<QTextEdit *>(widget);

    // 각 QAction을 활성화된 QTextEdit와 연결
    QList<QAction*> actions = findChildren<QAction*>();
    for (QAction *action : actions) {
        if (action->text() == "&copy") {
            action->disconnect();
            connect(action, SIGNAL(triggered()), activeEditor, SLOT(copy()));
        } else if (action->text() == "&paste") {
            action->disconnect();
            connect(action, SIGNAL(triggered()), activeEditor, SLOT(paste()));
        }
    }
}

'대외활동 > 시스템프로그래밍' 카테고리의 다른 글

0812 리눅스  (0) 2024.08.12
0808 Qt 메세지박스, 자료구조  (0) 2024.08.08
0805 QT C++ 다양한 ui, 시그널  (0) 2024.08.05
modern c++  (0) 2024.07.31
스마트 포인터  (0) 2024.07.31