큐에 대기 중인 사용자 지정 유형
큐에 대기 중인 사용자 지정 유형 예제에서는 큐에 대기 중인 신호와 슬롯이 있는 스레드 간에 사용자 지정 유형을 보내는 방법을 보여 줍니다.
개요
이 예제에서는 값 클래스( Block
)를 만들고 메타객체 시스템에 등록하여 대기열 신호와 슬롯을 사용하여 스레드 간에 인스턴스를 전송할 수 있도록 합니다.
블록 클래스
Block
클래스는 메타객체 시스템에서 요구하는 대로 클래스의 공개 섹션에 기본 생성자, 복사 생성자, 소멸자를 제공합니다. 이 클래스는 색이 지정된 직사각형을 설명합니다.
class Block { public: Block(); Block(const Block &other); ~Block(); Block(const QRect &rect, const QColor &color); QColor color() const; QRect rect() const; private: QRect m_rect; QColor m_color; }; Q_DECLARE_METATYPE(Block);
이 유형을 사용하는 신호 슬롯 연결을 만들기 전에 qRegisterMetaType() 템플릿 함수를 호출하여 런타임에 메타 객체 시스템에 등록해야 합니다. 이 예제에서는 QVariant 에서 이 유형을 사용할 의도는 없지만 Q_DECLARE_METATYPE()을 사용하여 새 유형을 선언하는 것이 좋습니다.
Block
클래스의 구현은 사소한 것이므로 여기서는 인용하지 않겠습니다.
창 클래스
Block
객체를 받아들이는 공용 슬롯이 있는 간단한 Window
클래스를 정의합니다. 나머지 클래스는 사용자 인터페이스 관리와 이미지 처리를 담당합니다.
class Window : public QWidget { Q_OBJECT public: Window(QWidget *parent = nullptr); void loadImage(const QImage &image); public slots: void addBlock(const Block &block); private slots: void loadImage(); void resetUi(); private: QLabel *label; QPixmap pixmap; QPushButton *loadButton; QPushButton *resetButton; QString path; RenderThread *thread; };
Window
클래스에는 RenderThread
객체가 제공하는 워커 스레드도 포함되어 있습니다. 이는 Block
객체를 창의 addBlock(Block)
슬롯으로 전송하는 신호를 보냅니다.
Window
클래스에서 가장 관련성이 높은 부분은 생성자와 addBlock(Block)
슬롯입니다.
생성자는 이미지를 렌더링하기 위한 스레드를 생성하고 레이블과 같은 클래스의 슬롯에 연결된 두 개의 푸시 버튼이 포함된 사용자 인터페이스를 설정합니다.
Window::Window(QWidget *parent) : QWidget(parent), thread(new RenderThread(this)) { label = new QLabel(this); label->setAlignment(Qt::AlignCenter); loadButton = new QPushButton(tr("&Load image..."), this); resetButton = new QPushButton(tr("&Stop"), this); resetButton->setEnabled(false); connect(loadButton, &QPushButton::clicked, this, QOverload<>::of(&Window::loadImage)); connect(resetButton, &QPushButton::clicked, thread, &RenderThread::requestInterruption); connect(thread, &RenderThread::finished, this, &Window::resetUi); connect(thread, &RenderThread::sendBlock, this, &Window::addBlock);
이러한 연결 중 마지막 연결에서는 RenderThread
객체의 신호를 창의 addBlock(Block)
슬롯에 연결합니다.
...
setWindowTitle(tr("Queued Custom Type"));
}
나머지 생성자는 단순히 창의 레이아웃을 설정합니다.
addBlock(Block)
슬롯은 생성자에서 설정한 신호 슬롯 연결을 통해 렌더링 스레드에서 블록을 수신합니다:
void Window::addBlock(const Block &block) { QColor color = block.color(); color.setAlpha(64); QPainter painter; painter.begin(&pixmap); painter.fillRect(block.rect(), color); painter.end(); label->setPixmap(pixmap); }
블록이 도착하는 대로 라벨에 페인팅하기만 하면 됩니다.
렌더 스레드 클래스
RenderThread
클래스는 이미지를 처리하여 Block
객체를 생성하고 sendBlock(Block)
신호를 사용하여 예제에서 다른 컴포넌트로 전송합니다.
class RenderThread : public QThread { Q_OBJECT public: RenderThread(QObject *parent = nullptr); ~RenderThread(); void processImage(const QImage &image); signals: void sendBlock(const Block &block); protected: void run(); private: QImage m_image; };
생성자와 소멸자는 여기서는 인용하지 않았습니다. 이들은 스레드의 내부 상태를 설정하고 스레드가 소멸될 때 정리를 처리합니다.
처리는 RenderThread
클래스의 QThread::run() 함수 재구현을 호출하는 processImage()
함수로 시작됩니다:
void RenderThread::processImage(const QImage &image) { if (image.isNull()) return; m_image = image; start(); } void RenderThread::run() { const int size = qMax(m_image.width()/20, m_image.height()/20); for (int s = size; s > 0; --s) { for (int c = 0; c < 400; ++c) {
이미지가 처리되는 방식에 대한 세부 사항을 무시하고 블록이 포함된 신호가 일반적인 방식으로 방출되는 것을 볼 수 있습니다:
... const Block block(QRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1), QColor(red/n, green/n, blue/n)); emit sendBlock(block); if (isInterruptionRequested()) return; msleep(10); } } }
방출되는 각 신호는 대기열에 대기하고 나중에 창의 addBlock(Block)
슬롯으로 전달됩니다.
유형 등록하기
예제의 main()
함수에서는 qRegisterMetaType() 템플릿 함수를 호출하여 Block
클래스를 메타객체 시스템에 사용자 정의 유형으로 등록합니다:
int main(int argc, char *argv[]) { {. QApplication app(argc, argv); qRegisterMetaType<Block>(); 창 창; window.show(); window.loadImage(createImage(256, 256)); return app.exec(); }
이 호출은 유형을 사용하는 신호 슬롯 연결이 이루어지기 전에 유형이 등록되었는지 확인하기 위해 여기에 배치됩니다.
main()
함수의 나머지 부분은 의사 난수 생성기의 시드 설정, 창 생성 및 표시, 기본 이미지 설정과 관련이 있습니다. createImage()
함수의 구현은 소스 코드를 참조하세요.
추가 자료
이 예에서는 사용자 정의 유형을 메타 객체 시스템에 등록하여 스레드 간 신호 슬롯 연결에 사용할 수 있도록 하는 방법을 보여주었습니다.
실제로는 Q_DECLARE_METATYPE() 매크로와 qRegisterMetaType() 템플릿 함수를 모두 사용하여 사용자 정의 유형을 등록할 수 있지만, qRegisterMetaType()는 신호-슬롯 통신을 수행해야 하거나 런타임에 사용자 정의 유형의 객체를 생성 및 삭제해야 하는 경우에만 필요합니다.
Qt에서 사용자 정의 유형을 사용하는 방법에 대한 자세한 내용은 사용자 정의 Qt 유형 만들기 문서를 참조하십시오.
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.