[QT]example8-Widget-New Windowย (2)

๐Ÿ‘‰ ๋ฒ„ํŠผ ํด๋ฆญ์‹œ ๋‹ค์ด์–ผ๋กœ๊ทธ ์ฐฝ๊ณผ ์ƒˆ๋กœ์šด ์ฐฝ์„ ์˜คํ”ˆํ•ฉ๋‹ˆ๋‹ค.
When you click the button, a dialog window and a new window open.

๐Ÿ‘‰ ์ƒˆ๋กœ์šด ์ฐฝ์—์„œ ํ…์ŠคํŠธ ์ž…๋ ฅํ•˜๊ณ  ๋ฒ„ํŠผ ํด๋ฆญ์‹œ mainwindow์˜ ๋ผ๋ฒจ์— ํ…์ŠคํŠธ๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.
Enter text in a new window and click the button to display the text in the label of the mainwindow.

๐Ÿ‘‰ ์ƒˆ๋กœ์šด์ฐฝ๊ณผ ์ด์ „ ์ฐฝ ์‚ฌ์ด์˜ ๋ณ€์ˆ˜ ์ „๋‹ฌ์€ ์‹œ๊ทธ๋„๊ณผ ์Šฌ๋กฏ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
Passing variables between new and old windows uses signals and slots.

1.ํด๋ž˜์Šค ๋ฐ ํผ ์ถ”๊ฐ€ / Add classes and forms

2.ํผ๋””์ž์ธ / Form Deisgn

โœ”๏ธ ์ขŒ์ธก์€ dialog.ui ์˜ค๋ฅธ์ชฝ์€ mainwinodw.ui
On the left is dialog.ui and on the right is mainwinodw.ui

3.Header Files

โœ”๏ธ Dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

public:
    // ์•”์‹œ์  ํ˜•๋ณ€ํ™˜๋ฐฉ์ง€,์‹ค์ˆ˜ ๋ฐฉ์ง€์šฉ
    // To prevent implicit type conversion and mistakes
    explicit Dialog(QWidget *parent = nullptr);

    // ์†Œ๋ฉธ์ž:๊ฐ์ฒด ์‚ญ์ œ์‹œ ํ˜ธ์ถœ
    // Destructor: Called when the object is deleted
    ~Dialog();

private:
    Ui::Dialog *ui;
};

#endif // DIALOG_H

โœ”๏ธ 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

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

    private:
        Ui::MainWindow *ui;

    private slots:
        // ์ƒˆ์ฐฝ ์—ด๊ธฐ ์Šฌ๋กฏ
        // Open new window slot
        void openNewWindow();

        // Label์ถœ๋ ฅ ์Šฌ๋กฏ
        // Label output slot
        void updateLabel(const QString text);

        // Dialog์Šฌ๋กฏ
        // Dialog slot
        void openDialog();

};
#endif // MAINWINDOW_H

โœ”๏ธ newwindow.h

#ifndef NEWWINDOW_H
#define NEWWINDOW_H

// <QWidget์˜ ํ—ค๋”ํŒŒ์ผ์„ ํฌํ•จ
#include <QWidget>


// ์ „๋ฐฉ ์„ ์–ธ(forward declaration)
// class <className> ์ด๋Ÿฐ ํ˜•์‹๋งŒ ์žˆ๋Š” ๊ฒฝ์šฐ ์ „๋ฐฉ ์„ ์–ธ์ด๋ผ๊ณ ํ•ฉ๋‹ˆ๋‹ค.
// QLineEdit๊ณผ QPushButton์„ ํฌ์ธํ„ฐ๋กœ๋งŒ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ, ์ „์ฒด ํ—ค๋”๋ฅผ ํฌํ•จํ•˜์ง€ ์•Š์•„๋„ ๋ฉ๋‹ˆ๋‹ค.
// ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ปดํŒŒ์ผ ์†๋„๊ฐ€ ๋นจ๋ผ์ง€๊ณ , ์˜์กด์„ฑ์ด ์ค„์–ด๋“ญ๋‹ˆ๋‹ค.


// Forward declaration
// If the format is only class <className>, it is called a forward declaration.
// If you only use QLineEdit and QPushButton as pointers, you don't need to include the entire header.
// This speeds up compilation and reduces dependencies.


class QLineEdit;
class QPushButton;

class NewWindow : public QWidget
{
    // ๋งคํฌ๋กœ / macro
    Q_OBJECT

public:
    // ์•”์‹œ์  ํ˜•๋ณ€ํ™˜ ๊ธˆ์ง€ : ์‹ค์ˆ˜ ๋ฐฉ์ง€, ์ฝ”๋“œ ๋ช…ํ™•์„ฑ, ์•ˆ์ „ํ•œ ์ƒ์„ฑ์ž ํ˜ธ์ถœ
    // ์•”์‹œ์  ํ˜•๋ณ€ํ™˜์ด๋ž€ QT์ž์ฒด์—์„œ ํŒŒ๋ผ๋ฉ”ํ„ฐ๋กœ ๋Œ€์ž…๋˜๋Š” ๊ฐ’์„ ์ž๋™์œผ๋กœ ์ถ”์ •ํ•˜๋Š” ๊ธฐ๋Šฅ

    // Implicit type conversions are prohibited: Preventing mistakes, improving code clarity, and ensuring safe constructor calls.
    // Implicit type conversion is a feature of QT itself that automatically infers the values โ€‹โ€‹assigned to parameters.

    explicit NewWindow(QWidget *parent = nullptr);

signals:
    // ๋ฉ”์ธ์ฐฝ์œผ๋กœ ๋ณด๋‚ผ ์‹œ๊ทธ๋„
    // Signal to send to the main window
    void textSubmitted(const QString &text);

private:
    QLineEdit* inputField;
    QPushButton* confirmButton;

};

#endif // NEWWINDOW_H

4. Source FIles

โœ”๏ธ dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"

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


// ์†Œ๋ฉธ์ž
// destructor
Dialog::~Dialog()
{
    delete ui;
}

โœ”๏ธ main.cpp

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

// -- ์ฝ”๋“œ ์ˆ˜์ • ์—†์Œ / No code modification --

โœ”๏ธ mainwindow.cpp

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

// ์ƒˆ ์ฐฝ ํด๋ž˜์Šค ํฌํ•จ / Include a new window class
#include "newwindow.h"

// dialog ํด๋ž˜์Šค ํฌํ•จ / Includes dialog class
#include "dialog.h"

// cout๊ณผ ์œ ์‚ฌํ•œ ๋””๋ฒ„๊น… ํด๋ž˜์Šค / Debugging class similar to cout
#include <QDebug>

// ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ alert๊ณผ ์œ ์‚ฌํ•œ ๋””๋ฒ„๊น… ํด๋ž˜์Šค
// A debugging class similar to JavaScript Alert
#include <QMessageBox>


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

    // ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ์ƒˆ ์ฐฝ ์—ด๊ธฐ
    // Open a new window when the button is clicked
    connect(ui->pushButton, &QPushButton::clicked, this, &MainWindow::openNewWindow);

    // ๋ฒ„ํŠผ ํด๋ฆญ์‹œ ๋‹ค์ด์–ผ๋กœ๊ทธ ๋„์šฐ๊ธฐ
    // Pop up a dialog when a button is clicked
    connect(ui->pushButton_2, &QPushButton::clicked, this, &MainWindow::openDialog);
}

// ์ƒˆ์ฐฝ ๋„์šฐ๋Š” ์Šฌ๋กฏ ํ•จ์ˆ˜
// Slot function to open a new window
void MainWindow::openNewWindow(){

    // === ๋””๋ฒ„๊น… / Debugging ===
    qDebug() << "openNewWindow ์Šฌ๋กฏ ์‹คํ–‰๋จ/slot executed!";

    //QMessageBox::information(this, "ํ…Œ์ŠคํŠธ/test", "์Šฌ๋กฏ์ด ์‹คํ–‰๋˜์—ˆ์Šต๋‹ˆ๋‹ค/The slot has been run.!");

    // ๋ถ€๋ชจ ์—†์ด ๋…๋ฆฝ ์ฐฝ(๋””๋ฒ„๊น…)
    // Independent window without parent (debugging)
    //NewWindow* window = new NewWindow(nullptr);


    NewWindow* window = new NewWindow(this);

    // ๋…๋ฆฝ๋œ ์ฐฝ์œผ๋กœ ์„ค์ •
    // Set as independent window
    window->setWindowFlags(Qt::Window);

    // ์‹œ๊ทธ๋„๊ณผ ์Šฌ๋กฏ ์—ฐ๊ฒฐ(๋ผ๋ฒจ ์ถœ๋ ฅ์šฉ)
    // Connecting signals and slots (for label output)
    connect(window, &NewWindow::textSubmitted, this, &MainWindow::updateLabel);

    // ๋‹ซ์„ ๋•Œ ๋ฉ”๋ชจ๋ฆฌ ์ž๋™ ํ•ด์ œ
    // Automatically free memory when closing
    window->setAttribute(Qt::WA_DeleteOnClose);
    window->show();

}

// MainWindow์˜ ๋ผ๋ฒจ์— ํ…์ŠคํŠธ ์ถœ๋ ฅํ•˜๋Š” ์Šฌ๋กฏ ํ•จ์ˆ˜
// Slot function that outputs text to the label of MainWindow
// newwindow.cpp์—์„œ ์‹œ๊ทธ๋„ ๋ฐœ์ƒ
// Signal generated in newwindow.cpp
void MainWindow::updateLabel(const QString text){

    // ๋ผ๋ฒจ์— ํ…์ŠคํŠธ ์ถœ๋ ฅ
    // Print text to label
    ui->label->setText(text);
}


// ๋‹ค์ด์–ผ๋กœ๊ทธ ์ฐฝ ๋„์šฐ๋Š” ์Šฌ๋กฏ ํ•จ์ˆ˜
// Slot function to open a dialog window
void MainWindow::openDialog()
{
    Dialog* dialog = new Dialog(this);

    // ๋‹ค์ด์–ผ๋กœ๊ทธ ์ฐฝ์œผ๋กœ ์„ค์ •
    // Set to dialog window
    dialog->setWindowFlags(Qt::Dialog);

    // ๋‹ซ์„๋•Œ ๋ฉ”๋ชจ๋ฆฌํ•ด์ œ
    // Free memory when closing
    dialog->setAttribute(Qt::WA_DeleteOnClose);
    dialog->show();
}


// ์†Œ๋ฉธ์ž / destructor
// ๊ฐ์ฒด๊ฐ€ ์‚ญ์ œ๋˜๊ฑฐ๋‚˜ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚  ๋•Œ ์ž๋™์œผ๋กœ ํ˜ธ์ถœ๋˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.
// A function that is automatically called when an object is deleted or goes out of scope.
MainWindow::~MainWindow()
{
    delete ui;
}

.โœ”๏ธ newwindow.cpp

#include "newwindow.h"
#include <QVBoxLayout>
#include <QLineEdit>
#include <QPushButton>
#include <QDebug>

NewWindow::NewWindow(QWidget *parent) : QWidget(parent)
{
    setWindowTitle("new window");
    resize(400,300);

    // ui์ถ”๊ฐ€,ui๋””์ž์ธ ํŒŒ์ผ ์—†๋Š” ๊ฒฝ์šฐ.
    // Add UI, if there is no UI design file.
    inputField = new QLineEdit(this);
    confirmButton = new QPushButton("ํ™•์ธ/Confirm",this);

    QVBoxLayout* layout = new QVBoxLayout(this);
    layout->addWidget(inputField);
    layout->addWidget(confirmButton);

    //&QPushButton::clicked ์ด ์‹œ๊ทธ๋„ ๋ฐœ์ƒ์‹œ [this]()์Šฌ๋กฏ ํ•จ์ˆ˜ ์‹คํ–‰
    //&QPushButton::clicked When this signal occurs, the [this]() slot function is executed.
    connect(confirmButton, &QPushButton::clicked, this, [this](){
        QString text = inputField->text();
        emit textSubmitted(text); // ์‹œ๊ทธ๋„ ๋ฐœ์ƒ
        qDebug() << "์ž…๋ ฅ๋œ ํ…Œ์ŠคํŠธ/Enterd TExt:" << text;

        //close();// ์ฐฝ๋‹ซ๊ธฐ / Close window
    });
}

5.์‹คํ–‰ / Run

Leave a Reply

Your email address will not be published. Required fields are marked *