๐ŸŽ†

002 ์ƒ์„  ์ž๋™ ํฌ์žฅ ํ”„๋กœ๊ทธ๋žจ ๋งŒ๋“ค๊ธฐ

0. ์Šคํ† ๋ฆฌ

notion image
"๊ณต์ •์€ ๋ชจ๋‘ ๊ธฐ๊ณ„๋กœ ์ž๋™ํ™” ํ•˜๋”๋ผ๋„, ์•„๋ž˜ ๋ฒ„ํŠผ์€ ๋ƒฅ์ด๋“ค์ด ์ง์ ‘ ๋ˆŒ๋Ÿฌ์•ผ ํ•œ๋‹ค๋ƒฅ!"
๋Œ€๋ฆฌ์ธ No.1์€ ๊ณ ๋ฏผ์— ๋น ์กŒ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ์—…๋ฌด๋ฅผ ์ž๋™ํ™” ํ•˜๊ณ  ์‹ถ์€๋ฐ, ๊ผญ ์ง์ ‘ ๋ˆŒ๋Ÿฌ์•ผ ํ•˜๋Š” ๋ฒ„ํŠผ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด์ฃ .
๊ทธ๋Ÿผ, ์ง์ ‘ ๋ˆŒ๋Ÿฌ์•ผ ํ•˜๋Š” ๋ฒ„ํŠผ์€ ๋งŒ๋“ค ์ˆ˜ ์—†๋Š” ๊ฒƒ์ผ๊นŒ์š”? ํ˜น์‹œ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค๋ฉด, ์ œ๋Œ€๋กœ ๋ˆŒ๋ ธ๋Š”์ง€๋„ ์ฒดํฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ๋„ฃ์„ ์ˆ˜๋Š” ์—†๋Š” ๊ฒƒ์ผ๊นŒ์š”?

1. ๊ธฐํš

notion image

2. ๋””์ž์ธ

notion image

3. ์ฝ”๋“œ

import pyautogui #pip3 install pyautogui import sys from PyQt5.QtWidgets import * from PyQt5.QtGui import QIcon, QPixmap, QFont from PyQt5.QtCore import QCoreApplication, QTimer class ์ƒ์„ ์ž๋™ํฌ์žฅํ”„๋กœ๊ทธ๋žจ(QWidget): def __init__(self): super().__init__() self.UI์ดˆ๊ธฐํ™”() def UI์ดˆ๊ธฐํ™”(self): self.ํฌ์žฅ์นด์šดํŠธ = 0 self.ํด๋ฆญํšŸ์ˆ˜์นด์šดํŠธ = 0 self.์ƒ์„ ํฌ์žฅ์ˆ˜() self.๋Œ€ํ‘œ์ด๋ฏธ์ง€() self.ํฌ์žฅ๋ฒ„ํŠผ() self.setWindowTitle('์ƒ์„  ์ž๋™ ํฌ์žฅ ํ”„๋กœ๊ทธ๋žจ') self.setGeometry(400, 300, 580, 500) self.show() def ๋Œ€ํ‘œ์ด๋ฏธ์ง€(self): self.๋Œ€ํ‘œ์ด๋ฏธ์ง€๋ผ๋ฒจ = QLabel(self) self.๋Œ€ํ‘œ์ด๋ฏธ์ง€๋ผ๋ฒจ.setPixmap(QPixmap('img/weniv-licat.png').scaled(35, 44)) self.๋Œ€ํ‘œ์ด๋ฏธ์ง€๋ผ๋ฒจ.move(10, 10) def ์ƒ์„ ํฌ์žฅ์ˆ˜(self): self.์ƒ์„ ํฌ์žฅ์ˆ˜๋ผ๋ฒจ = QLabel('00 ๋งˆ๋ฆฌ๊ฐ€ ํฌ์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.', self) self.์ƒ์„ ํฌ์žฅ์ˆ˜๋ผ๋ฒจ.setFont(QFont("Helvetica", pointSize=22, weight=2)) self.์ƒ์„ ํฌ์žฅ์ˆ˜๋ผ๋ฒจ.move(30, 70) def ํฌ์žฅ๋ฒ„ํŠผ(self): self.์ƒ์„ ์ค€๋น„๋ฒ„ํŠผ = QPushButton('์ƒ์„ ์ค€๋น„', self) self.์ƒ์„ ์ค€๋น„๋ฒ„ํŠผ.move(30, 150) self.์ƒ์„ ์ค€๋น„๋ฒ„ํŠผ.setFixedSize(250, 40) self.์ƒ์„ ๋‹ค๋“ฌ๊ธฐ๋ฒ„ํŠผ = QPushButton('์ƒ์„ ๋‹ค๋“ฌ๊ธฐ', self) self.์ƒ์„ ๋‹ค๋“ฌ๊ธฐ๋ฒ„ํŠผ.move(300, 150) self.์ƒ์„ ๋‹ค๋“ฌ๊ธฐ๋ฒ„ํŠผ.setFixedSize(250, 40) self.์ƒ์„ ํฌ์žฅ๋ฒ„ํŠผ = QPushButton('์ƒ์„ ํฌ์žฅ', self) self.์ƒ์„ ํฌ์žฅ๋ฒ„ํŠผ.move(30, 200) self.์ƒ์„ ํฌ์žฅ๋ฒ„ํŠผ.setFixedSize(520, 40) self.์ƒ์„ ํฌ์žฅ๋ฒ„ํŠผ.clicked.connect(self.countClick) self.ํฌ์žฅ์‹œ์ž‘๋ฒ„ํŠผ = QPushButton('ํฌ์žฅ์‹œ์ž‘', self) self.ํฌ์žฅ์‹œ์ž‘๋ฒ„ํŠผ.move(300, 300) self.ํฌ์žฅ์‹œ์ž‘๋ฒ„ํŠผ.setFixedSize(250, 40) self.ํฌ์žฅ์‹œ์ž‘๋ฒ„ํŠผ.clicked.connect(self.startClick) self.๊ฐ„๊ฒฉ์ž…๋ ฅ์ฐฝ = QLineEdit(self) self.๊ฐ„๊ฒฉ์ž…๋ ฅ์ฐฝ.setPlaceholderText('ํด๋ฆญ ๊ฐ„๊ฒฉ/ (์ดˆ)') self.๊ฐ„๊ฒฉ์ž…๋ ฅ์ฐฝ.move(30, 300) self.๊ฐ„๊ฒฉ์ž…๋ ฅ์ฐฝ์„ค๋ช…๋ผ๋ฒจ = QLabel('๋ช‡ ์ดˆ ๊ฐ„๊ฒฉ์œผ๋กœ ํฌ์žฅํ• ์ง€ ์ž…๋ ฅํ•˜์„ธ์š”.', self) self.๊ฐ„๊ฒฉ์ž…๋ ฅ์ฐฝ์„ค๋ช…๋ผ๋ฒจ.setFont(QFont("Helvetica", pointSize=7)) self.๊ฐ„๊ฒฉ์ž…๋ ฅ์ฐฝ์„ค๋ช…๋ผ๋ฒจ.move(30, 340) self.ํšŸ์ˆ˜์ž…๋ ฅ์ฐฝ = QLineEdit(self) self.ํšŸ์ˆ˜์ž…๋ ฅ์ฐฝ.setPlaceholderText('ํด๋ฆญ ํšŸ์ˆ˜') self.ํšŸ์ˆ˜์ž…๋ ฅ์ฐฝ.move(30, 400) self.ํšŸ์ˆ˜์ž…๋ ฅ์ฐฝ์„ค๋ช…๋ผ๋ฒจ = QLabel('๋ช‡ ํšŒ ํฌ์žฅํ• ์ง€ ์ž…๋ ฅํ•˜์„ธ์š”.', self) self.ํšŸ์ˆ˜์ž…๋ ฅ์ฐฝ์„ค๋ช…๋ผ๋ฒจ.setFont(QFont("Helvetica", pointSize=7)) self.ํšŸ์ˆ˜์ž…๋ ฅ์ฐฝ์„ค๋ช…๋ผ๋ฒจ.move(30, 440) def startClick(self): self.timer = QTimer() self.x = 550 #์ „์ฒด ์œˆ๋„์šฐ์—์„œ ์ขŒํ‘œ๊ฐ’์„ ๊ฐ€์ ธ์˜ด self.y = 510 self.delay = int(self.๊ฐ„๊ฒฉ์ž…๋ ฅ์ฐฝ.text()) self.timer.start(self.delay * 1000) self.timer.timeout.connect(self.mouseClick) def mouseClick(self): pyautogui.click(self.x, self.y) self.ํด๋ฆญํšŸ์ˆ˜์นด์šดํŠธ += 1 if self.ํด๋ฆญํšŸ์ˆ˜์นด์šดํŠธ == int(self.ํšŸ์ˆ˜์ž…๋ ฅ์ฐฝ.text()): self.timer.stop() def countClick(self): self.ํฌ์žฅ์นด์šดํŠธ += 1 self.์ƒ์„ ํฌ์žฅ์ˆ˜๋ผ๋ฒจ.setText(f'{str(self.ํฌ์žฅ์นด์šดํŠธ)} ๋งˆ๋ฆฌ๊ฐ€ ํฌ์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.') ํ”„๋กœ๊ทธ๋žจ๋ฌดํ•œ๋ฐ˜๋ณต = QApplication(sys.argv) ์‹คํ–‰์ธ์Šคํ„ด์Šค = ์ƒ์„ ์ž๋™ํฌ์žฅํ”„๋กœ๊ทธ๋žจ() ํ”„๋กœ๊ทธ๋žจ๋ฌดํ•œ๋ฐ˜๋ณต.exec_()
 

4. ์ƒ์„ธ ๋‚ด์šฉ

๋งˆ์šฐ์Šค๋ฅผ ์›€์ง์ด๋Š” ์ด๋ฒคํŠธ, ํ‚ค๋ณด๋“œ๋ฅผ ํด๋ฆญํ•˜๋Š” ์ด๋ฒคํŠธ๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์•„๋ž˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. pip3 install pyautogui๋กœ ํ•ด๋‹น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•ด์ฃผ์„ธ์š”.
import pyautogui
 
๊ณต์‹ Docs: https://pyautogui.readthedocs.io/en/latest/
 
์ „์ฒด UI๋ฅผ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ƒ์„ ํฌ์žฅ์ˆ˜()๋Š” ๋ผ๋ฒจ๋กœ ๋ช‡๋งˆ๋ฆฌ๊ฐ€ ํฌ์žฅ๋˜์—ˆ๋Š”์ง€ ํ‘œ์‹œํ•  ๊ฒƒ์ด๊ณ  ๋Œ€ํ‘œ์ด๋ฏธ์ง€()๋Š” ์ด๋ฏธ์ง€๋ฅผ ๋„์šฐ๋Š” ๊ฒƒ์„, ํฌ์žฅ๋ฒ„ํŠผ()์€ ํฌ์žฅ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด self.ํฌ์žฅ์นด์šดํŠธ๊ฐ€ ์˜ฌ๋ผ๊ฐ€๊ฒŒ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์„ ๋Œ€ํ‘œ ๋ผ๋ฒจ์— ์ถœ๋ ฅํ•˜๊ณ ์š”.
def UI์ดˆ๊ธฐํ™”(self): self.ํฌ์žฅ์นด์šดํŠธ = 0 self.ํด๋ฆญํšŸ์ˆ˜์นด์šดํŠธ = 0 self.์ƒ์„ ํฌ์žฅ์ˆ˜() self.๋Œ€ํ‘œ์ด๋ฏธ์ง€() self.ํฌ์žฅ๋ฒ„ํŠผ() self.setWindowTitle('์ƒ์„  ์ž๋™ ํฌ์žฅ ํ”„๋กœ๊ทธ๋žจ') self.setGeometry(400, 300, 580, 500) self.show()
  • self.ํฌ์žฅ์นด์šดํŠธ : ์–ผ๋งˆ๋‚˜ ํฌ์žฅํ•˜์˜€๋Š”์ง€ ์ €์žฅํ•œ ๋ณ€์ˆ˜, ํด๋ฆญํ•˜๋ฉด +1 ๋ฉ๋‹ˆ๋‹ค.
  • self.ํด๋ฆญํšŸ์ˆ˜์นด์šดํŠธ : ํด๋ฆญ์ด ์–ผ๋งˆ๋‚˜ ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ์ž…๋ ฅ๋œ ํšŸ์ˆ˜๋ž‘ ๋น„๊ตํ•˜์—ฌ ํ”„๋กœ๊ทธ๋žจ์„ Stopํ•˜๋Š” ์—ญํ™œ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
 
def ํฌ์žฅ๋ฒ„ํŠผ(self): #...์ค‘๋žต... self.๊ฐ„๊ฒฉ์ž…๋ ฅ์ฐฝ = QLineEdit(self) self.๊ฐ„๊ฒฉ์ž…๋ ฅ์ฐฝ.setPlaceholderText('ํด๋ฆญ ๊ฐ„๊ฒฉ/ (์ดˆ)') self.๊ฐ„๊ฒฉ์ž…๋ ฅ์ฐฝ.move(30, 300) self.๊ฐ„๊ฒฉ์ž…๋ ฅ์ฐฝ์„ค๋ช…๋ผ๋ฒจ = QLabel('๋ช‡ ์ดˆ ๊ฐ„๊ฒฉ์œผ๋กœ ํฌ์žฅํ• ์ง€ ์ž…๋ ฅํ•˜์„ธ์š”.', self) self.๊ฐ„๊ฒฉ์ž…๋ ฅ์ฐฝ์„ค๋ช…๋ผ๋ฒจ.setFont(QFont("Helvetica", pointSize=7)) self.๊ฐ„๊ฒฉ์ž…๋ ฅ์ฐฝ์„ค๋ช…๋ผ๋ฒจ.move(30, 340) self.ํšŸ์ˆ˜์ž…๋ ฅ์ฐฝ = QLineEdit(self) self.ํšŸ์ˆ˜์ž…๋ ฅ์ฐฝ.setPlaceholderText('ํด๋ฆญ ํšŸ์ˆ˜') self.ํšŸ์ˆ˜์ž…๋ ฅ์ฐฝ.move(30, 400) self.ํšŸ์ˆ˜์ž…๋ ฅ์ฐฝ์„ค๋ช…๋ผ๋ฒจ = QLabel('๋ช‡ ํšŒ ํฌ์žฅํ• ์ง€ ์ž…๋ ฅํ•˜์„ธ์š”.', self) self.ํšŸ์ˆ˜์ž…๋ ฅ์ฐฝ์„ค๋ช…๋ผ๋ฒจ.setFont(QFont("Helvetica", pointSize=7)) self.ํšŸ์ˆ˜์ž…๋ ฅ์ฐฝ์„ค๋ช…๋ผ๋ฒจ.move(30, 440)
  • setPlaceholderText : ์›Œํ„ฐ๋งˆํฌ๋ฅผ ํ™œ์šฉํ•œ ํ‘œ์‹œ ์ž…๋ ฅ์‹œ, ํžŒํŠธ๋ฅผ ์ค„ ๋•Œ ์œ ์šฉ
 
def startClick(self): self.timer = QTimer() self.x = 550 #์ „์ฒด ์œˆ๋„์šฐ์—์„œ ์ขŒํ‘œ๊ฐ’์„ ๊ฐ€์ ธ์˜ด self.y = 510 self.delay = int(self.๊ฐ„๊ฒฉ์ž…๋ ฅ์ฐฝ.text()) self.num_click = 0 self.timer.start(self.delay * 1000) self.timer.timeout.connect(self.mouseClick)
์Šคํƒ€ํŠธ ๋ฒ„ํŠผ์ด ํด๋ฆญ๋˜๋ฉด startClick ํ•จ์ˆ˜์™€ ์—ฐ๊ฒฐ๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. QTimer๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  x, y๋ณ€์ˆ˜์— ์ขŒํ‘œ๊ฐ’์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์ขŒํ‘œ๋Š” ์œˆ๋„์šฐ ์ƒ๋‹จ์—์„œ๋ถ€ํ„ฐ x, y๊ฐ’์ž…๋‹ˆ๋‹ค. int๊ฐ’์ด๊ธฐ ๋•Œ๋ฌธ์— ์ •์ˆ˜๋กœ ๋”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹จ์œ„๋Š” px์ž…๋‹ˆ๋‹ค.
์ง€์—ฐ์‹œ๊ฐ„ ๋ณ€์ˆ˜์— ์ž…๋ ฅ๋œ ์ง€์—ฐ์‹œ๊ฐ„ ๊ฐ’์„ ๋„ฃ์Šต๋‹ˆ๋‹ค. ์‹œ๊ฐ„ ๋‹จ์œ„๋Š” ๋ฐ€๋ฆฌ์„ธ์ปจ๋“œ์ž…๋‹ˆ๋‹ค. ํด๋ฆญ๋œ ํšŸ์ˆ˜๋ฅผ ์•Œ์•„๋ณด๊ธฐ ์œ„ํ•œ ๋ณ€์ˆ˜๋ฅผ 0์œผ๋กœ ์ดˆ๊ธฐํ™” ํ•˜๊ณ  ํƒ€์ด๋จธ๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๋‹จ์œ„๊ฐ€ ๋ฐ€๋ฆฌ์„ธ์ปจ๋“œ์ด๊ธฐ ๋•Œ๋ฌธ์— 1000์„ ๊ณฑํ•˜์—ฌ ์ดˆ ๋‹จ์œ„๋กœ ์‹คํ–‰ํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
 
def mouseClick(self): pyautogui.click(self.x, self.y) self.ํด๋ฆญํšŸ์ˆ˜์นด์šดํŠธ += 1 if self.ํด๋ฆญํšŸ์ˆ˜์นด์šดํŠธ == int(self.ํšŸ์ˆ˜์ž…๋ ฅ์ฐฝ.text()): self.timer.stop()
  • pyautogui๋ฅผ ํ†ตํ•ด ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋„˜๊ฒจ๋ฐ›์€ ์ขŒํ‘œ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.
  • ํด๋ฆญ๋œ ํšŸ์ˆ˜๋ฅผ 1์”ฉ ์ฆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค(์—ฌ๊ธฐ์„œ๋Š” 1์ดˆ ๋‹จ์œ„๋กœ 1์”ฉ ์ฆ๊ฐ€)
  • ๋ชฉํ‘œ์ธ ํด๋ฆญํšŸ์ˆ˜์— ๋„๋‹ฌํ•˜๋ฉด ํƒ€์ด๋จธ๋ฅผ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค.
 
self.timer.timeout.connect(self.mouseClick)
 
ํƒ€์ด๋จธ๊ฐ€ ์ข…๋ฃŒ๋˜๋ฉด ๋งˆ์šฐ์Šค๋กœ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๊ฒŒ ๋˜๊ณ  ์•„๋ž˜ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๋ฉด์„œ ํฌ์žฅ ๋งˆ๋ฆฌ์ˆ˜๊ฐ€ ์˜ฌ๋ผ๊ฐ€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
 
def countClick(self): self.ํฌ์žฅ์นด์šดํŠธ += 1 self.์ƒ์„ ํฌ์žฅ์ˆ˜๋ผ๋ฒจ.setText(f'{str(self.ํฌ์žฅ์นด์šดํŠธ)} ๋งˆ๋ฆฌ๊ฐ€ ํฌ์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.')
 

5. ์‹คํ–‰ ํ™”๋ฉด

 
notion image
 
notion image