Mycar_Browser/modules/ui/browser_widget.py

157 lines
6.1 KiB
Python

from PySide6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLineEdit, QLabel, QComboBox, QProgressBar
from PySide6.QtCore import Qt, Signal, Slot, QUrl
from PySide6.QtWebEngineWidgets import QWebEngineView
import os
# Fluent 위젯 추가
from qfluentwidgets import (LineEdit, PushButton, ComboBox, ProgressBar, SearchLineEdit,
ToolButton, FluentIcon, PrimaryToolButton, TransparentToolButton,
InfoBar, InfoBarPosition, CardWidget, ExpandLayout, TitleLabel,
SmoothScrollArea, IconWidget, setTheme, Theme)
class BrowserWidget(QWidget):
# 시그널 정의
status_changed = Signal(str)
def __init__(self, parent=None):
super().__init__(parent)
self.parent = parent
self.setup_ui()
def setup_ui(self):
# 메인 레이아웃
main_layout = QVBoxLayout(self)
main_layout.setContentsMargins(0, 0, 0, 0)
main_layout.setSpacing(0)
# 브라우저 주소 및 컨트롤 카드
control_card = CardWidget(self)
control_layout = QVBoxLayout(control_card)
# 주소창 및 버튼 레이아웃
address_layout = QHBoxLayout()
# 네비게이션 버튼
self.back_button = TransparentToolButton(FluentIcon.CHEVRON_LEFT, self)
self.forward_button = TransparentToolButton(FluentIcon.CHEVRON_RIGHT, self)
self.refresh_button = TransparentToolButton(FluentIcon.REFRESH, self)
self.home_button = TransparentToolButton(FluentIcon.HOME, self)
# 주소 입력창
self.address_bar = SearchLineEdit(self)
self.address_bar.setPlaceholderText("웹 주소 입력")
self.address_bar.returnPressed.connect(self.navigate_to_url)
# 즐겨찾기 버튼 및 검색 버튼
self.bookmark_button = TransparentToolButton(FluentIcon.BOOKMARK, self)
self.search_button = PrimaryToolButton(FluentIcon.SEARCH, self)
self.search_button.clicked.connect(self.navigate_to_url)
# 주소창 레이아웃에 위젯 추가
address_layout.addWidget(self.back_button)
address_layout.addWidget(self.forward_button)
address_layout.addWidget(self.refresh_button)
address_layout.addWidget(self.home_button)
address_layout.addWidget(self.address_bar)
address_layout.addWidget(self.bookmark_button)
address_layout.addWidget(self.search_button)
# 컨트롤 레이아웃에 주소창 레이아웃 추가
control_layout.addLayout(address_layout)
# 상태 레이아웃
status_layout = QHBoxLayout()
# 상태 라벨
self.status_label = QLabel("준비됨")
# 로딩 진행바
self.progress_bar = ProgressBar(self)
self.progress_bar.setRange(0, 100)
self.progress_bar.setValue(100)
self.progress_bar.setVisible(False)
# 상태 레이아웃에 위젯 추가
status_layout.addWidget(self.status_label)
status_layout.addWidget(self.progress_bar)
# 컨트롤 레이아웃에 상태 레이아웃 추가
control_layout.addLayout(status_layout)
# 웹뷰 생성
self.web_view = QWebEngineView()
self.web_view.loadStarted.connect(self.load_started)
self.web_view.loadProgress.connect(self.load_progress)
self.web_view.loadFinished.connect(self.load_finished)
self.web_view.urlChanged.connect(self.url_changed)
# 기본 홈페이지 로드
self.load_home_page()
# 네비게이션 버튼 연결
self.back_button.clicked.connect(self.web_view.back)
self.forward_button.clicked.connect(self.web_view.forward)
self.refresh_button.clicked.connect(self.web_view.reload)
self.home_button.clicked.connect(self.load_home_page)
# 메인 레이아웃에 위젯 추가
main_layout.addWidget(control_card)
main_layout.addWidget(self.web_view)
def navigate_to_url(self):
url_text = self.address_bar.text().strip()
if not url_text:
return
if not url_text.startswith(('http://', 'https://')):
# 검색어로 간주하고 검색 페이지로 이동
if ' ' in url_text:
self.search_term(url_text)
return
# http:// 추가
url_text = 'http://' + url_text
self.web_view.setUrl(QUrl(url_text))
self.status_changed.emit(f"이동: {url_text}")
def search_term(self, term):
# 네이버 검색 사용
search_url = f"https://search.naver.com/search.naver?query={term}"
self.web_view.setUrl(QUrl(search_url))
self.status_changed.emit(f"검색: {term}")
def load_started(self):
self.progress_bar.setVisible(True)
self.progress_bar.setValue(0)
self.status_label.setText("로딩 중...")
self.status_changed.emit("페이지 로딩 시작")
def load_progress(self, progress):
self.progress_bar.setValue(progress)
def load_finished(self, success):
self.progress_bar.setVisible(False)
if success:
self.status_label.setText("로딩 완료")
self.status_changed.emit("페이지 로딩 완료")
else:
self.status_label.setText("로딩 실패")
self.status_changed.emit("페이지 로딩 실패")
self.show_error_message("페이지를 로드할 수 없습니다")
def url_changed(self, url):
self.address_bar.setText(url.toString())
def load_home_page(self):
# 기본 홈페이지 설정 (여기서는 네이버)
self.web_view.setUrl(QUrl("https://www.naver.com"))
self.status_changed.emit("홈페이지 로드")
def show_error_message(self, message):
InfoBar.error(
title="오류",
content=message,
parent=self,
position=InfoBarPosition.TOP,
duration=3000
)