본문 바로가기
Software/Python

PyQt5 오버레이 레이어 Ver.2

by lovey25 2020. 12. 3.
반응형

어제 업로드했던 오버레이 레이어의 업그레이드 버전입니다.

 

PyQt5 오버레이 레이어

PyQt에서 특정 위젯을 오버레이 하는 레이어를 만드는 방법입니다. 아래 그림과 같은 윈도우에서 하단 PushButton을 누를 때마다 TextEdit창을 덮는 붉은색 레이어가 나타났다가 사라집니다. 먼저 Qt De

kwonkyo.tistory.com

오버레이 레이어 구현 방법을 찾아보게 된 계기는 시간이 오래 걸리는 동작을 하고 있을 때 동작중임을 시각적으로 표현하고 사용자의 추가 입력을 제한해야 하는 상황에 사용하기 위해서였습니다.

그래서 좀 더 로딩 화면처럼 보이도록 수정한 버전입니다. 일정 시간 동안 로딩 동그라미가 돌아가고 동시에 잔여 카운터가 얼마인지 숫자로 표시되도록 만들어 봤습니다. 

아래는 소스코드입니다. 이번엔 별도 ui파일 없이 파이썬으로만 구성되어 있습니다. 

import math, sys
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

class MainWindow(QMainWindow):

    def __init__(self, parent = None):
    
        QMainWindow.__init__(self, parent)
        
        widget = QWidget(self)
        self.editor = QTextEdit()
        self.editor.setWordWrapMode(QTextOption.WrapAnywhere)
        self.editor.setPlainText("https://kwonkyo.tistory.com  "*100)
        layout = QGridLayout(widget)
        layout.addWidget(self.editor, 0, 0, 1, 3)
        button = QPushButton("Wait")
        layout.addWidget(button, 1, 1, 1, 1)
        
        self.setCentralWidget(widget)
        self.overlay = Overlay(self.centralWidget())
        self.overlay.hide()
        button.clicked.connect(self.overlay.show)
    
    def resizeEvent(self, event):
    
        self.overlay.resize(event.size())
        event.accept()

class Overlay(QWidget):
    def __init__(self, parent = None):
        QWidget.__init__(self, parent)
        palette = QPalette(self.palette())
        palette.setColor(palette.Background, Qt.transparent)
        self.setPalette(palette)

        self.cntPreset = 150
        self.label = QLabel('000', self)
        self.label.setAlignment(Qt.AlignCenter | Qt.AlignVCenter)
    
    def paintEvent(self, event):
        painter = QPainter()
        painter.begin(self)
        painter.setRenderHint(QPainter.Antialiasing)
        painter.fillRect(event.rect(), QBrush(QColor(255, 255, 255, 180)))

        self.label.move(self.width()/2 -10, self.height()/2 -5)

        painter.setPen(QPen(Qt.NoPen))
        for i in range(14):
            if (self.counter / 5) % 14 == i:
                painter.setBrush(QBrush(QColor(127 + (self.counter % 5)*32, 0, 127)))
            else:
                painter.setBrush(QBrush(QColor(127, 127, 127)))
            painter.drawEllipse(
                self.width()/2 + 50 * math.cos(2 * math.pi * i / 14.0) - 5,
                self.height()/2 + 50 * math.sin(2 * math.pi * i / 14.0) -10,
                10, 10)
        painter.end()

    # 30 millisecond 간격으로 이벤트가 발생하는 타이머 설정
    def showEvent(self, event):
        self.timer = self.startTimer(30)
        self.counter = 0
    
    # 타이머 콜백
    def timerEvent(self, event):
        self.counter += 1
        self.update()
        self.label.setText(str(self.cntPreset - self.counter))
        if self.counter == self.cntPreset:  # 300번 호출되면
            self.killTimer(self.timer)      # 타이머 종료하고
            self.hide()                     # 오버레이 숨기기

if __name__ == "__main__":

    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

 

끝!

728x90
반응형

댓글3

  • 파린이 2021.05.20 22:24

    안녕하세요, 작성주신 포스팅이 도움 많이 됐습니다.

    혹시 기존 window에 열려있는 창에 오버레이를 생성하려면 어떻게 해야할까요?
    예를 들어,, 메모장이나 크롬 위에 오버레이 텍스트를 출력하는 방법을 알고 싶습니다.

    본문 예제와 다른 페이지에 있는 pywinauto를 통해 window 프로그램과 연동하는 예제 활용해서 해보려고 했는데 쉽지 않네요.
    답글