PySide6์ผ๋ก ๋๋ง์ ํ์ด์ฌ ์น๋ธ๋ผ์ฐ์ ๋ง๋ค๊ธฐ
ํ์ด์ฌ์ผ๋ก ์น ๋ธ๋ผ์ฐ์ ๋ฅผ ์ง์ ๋ง๋ค๊ณ , ์น ๋ธ๋ผ์ฐ์ ์๋จ์ ์ฃผ์์ฐฝ๊ณผ ํ๋/์ถ์๊ธฐ๋ฅ์ ๊ตฌํํ ์ ์๋ ์ฝ๋ ์๋ฃ์ ๋๋ค. ์น ๋ธ๋ผ์ฐ์ ์ ์ ์ ์์ฃผ ์ฌ์ฉ๋๋ ์ฝ๋์ด๊ธฐ๋ ํฉ๋๋ค. ์น ๋ธ๋ผ์ฐ์ ๋ ์ฐ๋ฆฌ๊ฐ ์ผ์์ ์ผ๋ก ์ฌ์ฉํ๋ ํฌ๋กฌ(Chrome), ์ฃ์ง(Edge), ํ์ด์ดํญ์ค(Firefox)์ ๊ฐ์ ํ๋ก๊ทธ๋จ๋ค์ ๋๋ค.
์ด ํ๋ก๊ทธ๋จ๋ค์ ์น ์๋ฒ์์ ๋ฐ์ HTML, CSS, JavaScript๋ฅผ ํด์ํ์ฌ ์ฐ๋ฆฌ๊ฐ ๋ณด๋ ์น ํ์ด์ง ํํ๋ก ํ์ํด์ค๋๋ค. ์ด๋ฒ ๊ธ์์๋ ์ง์ ์น๋ธ๋ผ์ฐ์ ๋ฅผ ํ์ด์ฌ์ผ๋ก ์ ์ํ๊ณ ์น ์ฃผ์(URL)๋ฅผ ์ ๋ ฅํ๊ณ , ํ์ด์ง๋ฅผ ํ๋ํ๊ฑฐ๋ ์ถ์ํ ์ ์๋ ๊ธฐ๋ฅ์ ๊ฐ์ถ ์ฃผ์์ฐฝ๊ณผ ์ค ์ปจํธ๋กค ํจ๋์ ๋ง๋๋ ๋ฐฉ๋ฒ์ ์๊ฐํฉ๋๋ค.
PySide6์ผ๋ก ๋๋ง์ ํ์ด์ฌ ์น๋ธ๋ผ์ฐ์ ๋ง๋ค๊ธฐ
ํ์ด์ฌ์์๋ ๋ค์๊ณผ ๊ฐ์ ๋ค์ํ ๋ฐฉ๋ฒ์ผ๋ก ์น ๋ธ๋ผ์ฐ์ ๊ธฐ๋ฅ์ ๊ตฌํํ ์ ์์ต๋๋ค:
PyQt5 / PySide6 ํ์ด์ฌ GUI ๋ผ์ด๋ธ๋ฌ๋ฆฌ
PyQt5 / PySide6 ๋ ๋ค Qt๋ผ๋ GUI ํ๋ ์์ํฌ๋ฅผ ํ์ด์ฌ์์ ์ฌ์ฉํ ์ ์๊ฒ ํด์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค. ํ์ด์ฌ์ผ๋ก ํ๋ก๊ทธ๋จ์ ๋ง๋ค๋ค ๋ณด๋ฉด ๋จ์ํ ํ ์คํธ ๊ธฐ๋ฐ ์ฝ์ ํ๋ฉด๋ง์ผ๋ก๋ ๋ถ์กฑํ ๋๊ฐ ์์ต๋๋ค. ์ด๋ด ๋ "์๋์ฐ ์ฐฝ์ด ์๋ ํ๋ก๊ทธ๋จ", ์ฆ ๊ทธ๋ํฝ ์ฌ์ฉ์ ์ธํฐํ์ด์ค(GUI)๊ฐ ํ์ํ ๋๊ฐ ์๋๋ฐ, ๊ทธ๋ด ๋ ์ฌ์ฉํ๋ ๋ํ์ ์ธ ํ์ด์ฌ ๋๊ตฌ๊ฐ ๋ฐ๋ก PyQt5์ PySide6์ ๋๋ค.
ํญ๋ชฉ | PyQt5 | PySide6 |
---|---|---|
๊ฐ๋ฐ์ฌ | Riverbank | Qt Company (Qt ๊ณต์) |
๋ผ์ด์ ์ค | GPL ๋๋ ์์ฉ | LGPL (์์ ์ฉ์๋ ์์ ๋กญ๊ฒ ์ฌ์ฉ ๊ฐ๋ฅ) |
๋ฒ์ | Qt 5 ๊ธฐ๋ฐ | Qt 6 ๊ธฐ๋ฐ |
์ค์น | pip install pyqt5 | pip install pyside6 |
๊ธฐ๋ฅ | ๊ฑฐ์ ๋์ผ (๋ฒํผ, ์ฐฝ, ์ ๋ ฅ์ฐฝ, ๋ ์ด์์ ๋ฑ ๋ชจ๋ ๊ฐ๋ฅ) | ๊ฑฐ์ ๋์ผ (๋ฒํผ, ์ฐฝ, ์ ๋ ฅ์ฐฝ, ๋ ์ด์์ ๋ฑ ๋ชจ๋ ๊ฐ๋ฅ) |
๊ฐ์ธ ํ์ต ๋ฐ ์คํ์์ค ํ๋ก์ ํธ์ ์ ํฉํ ์ ํ
- ๊ฐ์ธ ๊ณต๋ถ์ฉ, ์คํ์์ค ํ๋ก์ ํธ๋ผ๋ฉด ๋ ์ค ์๋ฌด๊ฑฐ๋ ์จ๋ ๊ด์ฐฎ์ต๋๋ค.
- ์์ ์ฉ ์ํํธ์จ์ด๋ฅผ ๋ง๋ค ์์ ์ด๋ผ๋ฉด PySide6์ด ๋ ์ ๋ฆฌํฉ๋๋ค. ๋ผ์ด์ ์ค ์ ํ์ด ๋ํฉ๋๋ค.
- ์ต์ ๊ธฐ์ ๊ณผ ์ฅ๊ธฐ์ ์ธ ์ง์์ ๊ณ ๋ คํ๋ค๋ฉด PySide6์ด ๋ ์ถ์ฒ๋ฉ๋๋ค. (Qt 6 ๊ธฐ๋ฐ)
Qt ํ๋ ์์ํฌ๋ก GUI ์ ํ๋ฆฌ์ผ์ด์ ๊ฐ๋ฐํ๊ธฐ
- Qt ํ๋ ์์ํฌ ๊ธฐ๋ฐ GUI ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ง๋ค ์ ์๋ ๋๊ตฌ์ ๋๋ค.
- ๋ด๋ถ์ ์ผ๋ก QWebEngineView ๋ผ๋ ์น ๋ทฐ ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํด ์นํ์ด์ง๋ฅผ ํ์ํ ์ ์์ต๋๋ค.
- ์ค์ ๋ก ํฌ๋กฌ ์์ง(Chromium) ์ ๊ธฐ๋ฐ์ผ๋ก ํ๊ธฐ์ ๋งค์ฐ ๊ฐ๋ ฅํฉ๋๋ค.
๊ฐ์ฅ ์ถ์ฒํ๋ ๋ฐฉ๋ฒ์ PySide6 ๋๋ PyQt5๋ฅผ ํ์ฉํ๋ ๊ฒ์ ๋๋ค. ์ด ๋ฐฉ์์ ํฌ๋กฌ ๊ธฐ๋ฐ ์น ๋ทฐ๋ฅผ ์ฌ์ฉํ ์ ์๊ณ , ์ฌ์ฉ์๊ฐ ์ง์ ์กฐ์ํ ์ ์๋ ๋ธ๋ผ์ฐ์ ํํ๋ก ๋ง๋ค ์ ์์ต๋๋ค.
- URL ์ ๋ ฅ์ฐฝ ๋ง๋ค๊ธฐ
- ์ด์ /๋ค์ ์ด๋, ์๋ก๊ณ ์นจ ๋ฒํผ ๊ตฌํ
- ํ์ด์ง ํ๋/์ถ์ (Zoom In/Out) ๊ธฐ๋ฅ ์ถ๊ฐ
- ์ฃผ์ ์๋ ์ ๋ฐ์ดํธ ๊ตฌํ
์ฝ๋ฉํ๊ธฐ
1. PySide6 ์ค์น
pip install PySide6
2. ์น ์์ง ๋ชจ๋ ํฌํจ ํ์ธ
PySide6์๋ ์น ๋ธ๋ผ์ฐ์ ๋ฅผ ๊ตฌ์ฑํ ์ ์๋ QWebEngineView๊ฐ ํฌํจ๋์ด ์์ต๋๋ค.
3. ์ ์ฒด ์ฝ๋ ์์ (์ฃผ์์ฐฝ + ์ค ์ปจํธ๋กค)
from PySide6.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout,
QPushButton, QLineEdit
)
from PySide6.QtWebEngineWidgets import QWebEngineView
from PySide6.QtCore import QUrl
class BrowserWidget(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("PySide6 ์น ๋ธ๋ผ์ฐ์ ")
self.resize(1000, 800)
self.webview = QWebEngineView()
self.webview.setUrl(QUrl("https://www.google.com"))
layout = QVBoxLayout(self)
layout.addWidget(self._create_url_input_with_zoom(self.webview, "URL์ ์
๋ ฅํ์ธ์..."))
layout.addWidget(self.webview)
def _load_url(self, webview, url_input):
url = url_input.text()
if not url.startswith("http"):
url = "https://" + url
webview.setUrl(QUrl(url))
def _create_url_input_with_zoom(self, webview, placeholder):
widget = QWidget()
layout = QVBoxLayout(widget)
layout.setContentsMargins(5, 5, 5, 5)
widget.setFixedHeight(90)
# ๋ค๋น๊ฒ์ด์
๋ฒํผ ๋ฐ
nav_bar = QHBoxLayout()
buttons = [
("←", webview.back),
("→", webview.forward),
("โป", webview.reload),
("-", lambda: webview.setZoomFactor(webview.zoomFactor() - 0.1)),
("+", lambda: webview.setZoomFactor(webview.zoomFactor() + 0.1)),
]
for i, (text, action) in enumerate(buttons):
btn = QPushButton(text)
btn.setFixedSize(40, 30)
btn.clicked.connect(action)
nav_bar.addWidget(btn)
if i == 2:
nav_bar.addStretch()
# URL ์
๋ ฅ ํ๋
url_input = QLineEdit()
url_input.setPlaceholderText(placeholder)
url_input.setFixedHeight(50)
url_input.returnPressed.connect(lambda: self._load_url(webview, url_input))
layout.addLayout(nav_bar)
layout.addWidget(url_input)
def update_url():
url_input.setText(webview.url().toString())
nav_bar.itemAt(0).widget().setEnabled(webview.history().canGoBack())
nav_bar.itemAt(1).widget().setEnabled(webview.history().canGoForward())
webview.urlChanged.connect(update_url)
webview.loadFinished.connect(update_url)
update_url()
return widget
ํ์ด์ฌ ์ฝ๋ ์ค๋ช
QWebEngineView๋?
QWebEngineView๋ ์น ๋ธ๋ผ์ฐ์ ์ฒ๋ผ ์น ํ์ด์ง๋ฅผ ํ์ํ ์ ์๊ฒ ํด์ฃผ๋ ์์ ฏ์ ๋๋ค. ๊ตฌ๊ธ, ๋ค์ด๋ฒ, ์ ํ๋ธ ๋ฑ ์ค์ ์น์ฌ์ดํธ๋ฅผ ๊ทธ๋๋ก ํ์ํ ์ ์์ด์. ๋จ ์๋ฒฝํ์ง๋ ์์ต๋๋ค.
URL ์ ๋ ฅ์ฐฝ (QLineEdit)
- ์ฌ์ฉ์๊ฐ ์น ์ฃผ์๋ฅผ ์ ๋ ฅํ๋ ๊ณณ์ ๋๋ค.
- returnPressed.connect()๋ฅผ ์ฌ์ฉํด ์ํฐ๋ฅผ ๋๋ฅด๋ฉด ์ ๋ ฅ๋ URL๋ก ์ด๋ํ๊ฒ ๋ง๋ญ๋๋ค.
- ์ฃผ์์ฐฝ์ https://๊ฐ ์์ผ๋ฉด ์๋์ผ๋ก ๋ถ์ฌ์ค๋๋ค.
๋ค๋ก, ์์ผ๋ก, ์๋ก๊ณ ์นจ ๋ฒํผ
- ๊ฐ๊ฐ ์น๋ธ๋ผ์ฐ์ ์ ๊ธฐ๋ณธ ๊ธฐ๋ฅ๊ณผ ์ฐ๊ฒฐํฉ๋๋ค.
- webview.back()
- webview.forward()
- webview.reload()
ํ๋ฉด ํ๋/์ถ์ (Zoom In/Out)
- webview.zoomFactor()๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ฐฐ์จ์ ์กฐ์ ํฉ๋๋ค.
- ๊ธฐ๋ณธ ๋ฐฐ์จ์ 1.0 (100%)์ด๊ณ , ์ฌ๊ธฐ์ +0.1 ๋๋ -0.1์ฉ ๊ฐ๊ฐํฉ๋๋ค.
- ์: 1.2๋ฉด 120%, 0.8์ด๋ฉด 80%
์ฃผ์ ์๋ ๊ฐฑ์
์น ํ์ด์ง๋ฅผ ์ด๋ํ ๋๋ง๋ค ์ฃผ์์ฐฝ์ด ์๋์ผ๋ก ๋ฐ๋๊ฒ ํ๊ธฐ ์ํด ๋ค์ ์๊ทธ๋์ ์ฐ๊ฒฐํฉ๋๋ค:
webview.urlChanged.connect(update_url)
webview.loadFinished.connect(update_url)
์คํ ์ฝ๋
์๋ ์ฝ๋๋ฅผ ์ถ๊ฐํ๋ฉด ๋ธ๋ผ์ฐ์ ๋ฅผ ์คํํ ์ ์์ต๋๋ค.
if __name__ == "__main__":
import sys
from PySide6.QtWidgets import QApplication
app = QApplication(sys.argv)
browser = BrowserWidget()
browser.show()
sys.exit(app.exec())