note_Commit
20
gui2.py
|
|
@ -113,23 +113,26 @@ class ProductViewer(QWidget):
|
|||
self.price_label.setText(f"가격: {product[4]}")
|
||||
self.page_button.setText(f"{self.product_index + 1}/{self.total_products}")
|
||||
|
||||
# self.reset_card_widgets() # 상품 카드 리셋
|
||||
|
||||
# 이미지 로드
|
||||
self.load_image_from_url(self.image_label, product[2])
|
||||
|
||||
self.reset_card_widgets() # 상품 카드 리셋
|
||||
|
||||
# 중간 레이아웃에 있는 카드 레이아웃 초기화 및 데이터 로드
|
||||
search_results = self.load_search_results(product[0])
|
||||
for i, card in enumerate(self.card_layouts):
|
||||
if i < len(search_results):
|
||||
result = search_results[i]
|
||||
print(f"f{result}")
|
||||
card["name"].setText(result[0][:30] + "..." if len(result[0]) > 30 else result[2]) # 상품명 길이 제한
|
||||
print(f"card[name], result[0] : {result[0]}")
|
||||
card["price"].setText(result[2])
|
||||
print(f"card[price], result[2] : {result[2]}")
|
||||
|
||||
card["select"].setText("미선택")
|
||||
card["widget"].setStyleSheet("border: 2px solid black;")
|
||||
# 각 카드에 이미지 로드
|
||||
self.load_image_from_url(card["image"], result[3]) # 이미지 URL에 맞춰 수정
|
||||
print(f"card[image], result[3] : {result[3]}")
|
||||
|
||||
else:
|
||||
card["name"].setText("")
|
||||
|
|
@ -150,6 +153,7 @@ class ProductViewer(QWidget):
|
|||
def load_image_from_url(self, label, url):
|
||||
try:
|
||||
response = requests.get(url)
|
||||
print(f"load_image_from_url : {url}")
|
||||
if response.status_code == 200:
|
||||
pixmap = QPixmap()
|
||||
pixmap.loadFromData(BytesIO(response.content).read())
|
||||
|
|
@ -206,7 +210,15 @@ class ProductViewer(QWidget):
|
|||
elif event.key() in [Qt.Key_1, Qt.Key_2, Qt.Key_3, Qt.Key_4, Qt.Key_5]:
|
||||
index = event.key() - Qt.Key_1
|
||||
if index < len(self.card_layouts) and self.card_layouts[index]["name"].text():
|
||||
self.select_card(index)
|
||||
# 현재 product_id와 search_result_id를 함께 전달
|
||||
product_id = self.products[self.product_index][0] # 현재 product_id 가져오기
|
||||
search_results = self.load_search_results(product_id)
|
||||
|
||||
if index < len(search_results):
|
||||
search_result_id = search_results[index][0] # search_result_id 가져오기
|
||||
self.select_card(product_id, search_result_id)
|
||||
else:
|
||||
QMessageBox.warning(self, "경고", "올바른 키를 입력하세요.", QMessageBox.Ok)
|
||||
elif event.key() == Qt.Key_Return or event.key() == Qt.Key_Enter:
|
||||
self.show_product_dialog()
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,163 @@
|
|||
from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QDialog
|
||||
from PySide6.QtCore import Qt
|
||||
import sqlite3
|
||||
import sys
|
||||
from productCard import ProductCard # ProductCard 클래스 임포트
|
||||
from searchResultCard import SearchResultCard # SearchResultCard 클래스 임포트
|
||||
|
||||
class ProductViewer(QWidget):
|
||||
def __init__(self, db_path):
|
||||
super().__init__()
|
||||
self.conn = sqlite3.connect(db_path)
|
||||
self.product_index = 0
|
||||
self.products = self.load_products()
|
||||
self.total_products = len(self.products)
|
||||
|
||||
# UI 초기화
|
||||
self.init_ui()
|
||||
self.load_product_data()
|
||||
|
||||
def init_ui(self):
|
||||
self.setWindowTitle("Product Viewer")
|
||||
main_layout = QVBoxLayout()
|
||||
|
||||
# 상단 레이아웃에 ProductCard를 추가
|
||||
self.product_card = ProductCard()
|
||||
main_layout.addWidget(self.product_card)
|
||||
|
||||
# 중간 레이아웃에 여러 개의 SearchResultCard를 추가
|
||||
self.middle_layout = QHBoxLayout()
|
||||
self.search_result_cards = [SearchResultCard(i+1) for i in range(5)]
|
||||
for card in self.search_result_cards:
|
||||
self.middle_layout.addWidget(card)
|
||||
|
||||
main_layout.addLayout(self.middle_layout)
|
||||
|
||||
# 하단 레이아웃
|
||||
self.bottom_layout = QHBoxLayout()
|
||||
self.left_button = QPushButton("◀")
|
||||
self.left_button.clicked.connect(self.previous_product)
|
||||
self.page_button = QPushButton(f"{self.product_index + 1}/{self.total_products}")
|
||||
self.page_button.clicked.connect(self.show_product_dialog)
|
||||
self.right_button = QPushButton("▶")
|
||||
self.right_button.clicked.connect(self.next_product)
|
||||
self.bottom_layout.addWidget(self.left_button)
|
||||
self.bottom_layout.addWidget(self.page_button)
|
||||
self.bottom_layout.addWidget(self.right_button)
|
||||
|
||||
main_layout.addLayout(self.bottom_layout)
|
||||
self.setLayout(main_layout)
|
||||
|
||||
def load_products(self):
|
||||
# DB에서 products 테이블 데이터를 로드
|
||||
cursor = self.conn.cursor()
|
||||
cursor.execute("SELECT * FROM products")
|
||||
products = cursor.fetchall()
|
||||
return products
|
||||
|
||||
def load_product_data(self):
|
||||
# 현재 상품 데이터를 로드하여 ProductCard에 설정
|
||||
product = self.products[self.product_index]
|
||||
product_name = product[1]
|
||||
product_price = product[4]
|
||||
product_img_url = product[2]
|
||||
self.product_card.set_data(name=product_name, price=product_price, img_url=product_img_url)
|
||||
print(f"product : {product}")
|
||||
print(f"product_name : {product_name}")
|
||||
print(f"product_price : {product_price}")
|
||||
print(f"product_img_url : {product_img_url}")
|
||||
|
||||
# SearchResultCard 초기화 및 데이터 로드
|
||||
self.reset_search_result_cards() # 이전 카드 데이터 리셋
|
||||
search_results = self.load_search_results(product[0])
|
||||
print(f"search_results : {search_results}")
|
||||
for i, result in enumerate(search_results):
|
||||
if i < len(self.search_result_cards):
|
||||
title = result[1]
|
||||
print(f"{i}번째 title : {title}")
|
||||
price = result[3]
|
||||
print(f"{i}번째 price : {price}")
|
||||
source = result[2]
|
||||
print(f"{i}번째 source : {source}")
|
||||
img_url = result[4]
|
||||
print(f"{i}번째 img_url : {img_url}")
|
||||
self.search_result_cards[i].set_data(name=title, price=price, source=source, img_url=img_url)
|
||||
|
||||
# 페이지 버튼 텍스트 업데이트
|
||||
self.page_button.setText(f"{self.product_index + 1}/{self.total_products}")
|
||||
|
||||
def reset_search_result_cards(self):
|
||||
# 각 SearchResultCard를 초기화
|
||||
for card in self.search_result_cards:
|
||||
card.reset()
|
||||
|
||||
def load_search_results(self, product_id):
|
||||
# DB에서 search_results 테이블의 데이터를 로드
|
||||
cursor = self.conn.cursor()
|
||||
cursor.execute("SELECT * FROM search_results WHERE product_id=?", (product_id,))
|
||||
return cursor.fetchall()
|
||||
|
||||
def previous_product(self):
|
||||
if self.product_index > 0:
|
||||
self.product_index -= 1
|
||||
self.load_product_data()
|
||||
|
||||
def next_product(self):
|
||||
if self.product_index < self.total_products - 1:
|
||||
self.product_index += 1
|
||||
self.load_product_data()
|
||||
|
||||
def show_product_dialog(self):
|
||||
# 현재 상품 정보를 다이얼로그로 보여줌
|
||||
dialog = ProductDialog(self)
|
||||
dialog.exec()
|
||||
|
||||
def keyPressEvent(self, event):
|
||||
# 키보드 이벤트 처리
|
||||
if event.key() == Qt.Key_Left:
|
||||
self.previous_product()
|
||||
elif event.key() == Qt.Key_Right:
|
||||
self.next_product()
|
||||
elif event.key() == Qt.Key_Escape:
|
||||
self.close()
|
||||
elif event.key() in [Qt.Key_1, Qt.Key_2, Qt.Key_3, Qt.Key_4, Qt.Key_5]:
|
||||
index = event.key() - Qt.Key_1
|
||||
if index < len(self.search_result_cards) and self.search_result_cards[index].name_value.text():
|
||||
self.select_card(index)
|
||||
elif event.key() == Qt.Key_Return or event.key() == Qt.Key_Enter:
|
||||
self.show_product_dialog()
|
||||
|
||||
def select_card(self, index):
|
||||
# 선택된 카드의 UI 갱신 및 데이터베이스 업데이트
|
||||
for i, card in enumerate(self.search_result_cards):
|
||||
if i == index:
|
||||
card.set_selected(True)
|
||||
else:
|
||||
card.set_selected(False)
|
||||
|
||||
class ProductDialog(QDialog):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setWindowTitle("상품 리스트")
|
||||
layout = QVBoxLayout(self)
|
||||
|
||||
cursor = parent.conn.cursor()
|
||||
cursor.execute("SELECT * FROM products")
|
||||
products = cursor.fetchall()
|
||||
|
||||
for product in products:
|
||||
label = QLabel(f"{product[1]} - {product[3]}원")
|
||||
layout.addWidget(label)
|
||||
|
||||
self.setLayout(layout)
|
||||
|
||||
def keyPressEvent(self, event):
|
||||
if event.key() in {Qt.Key_Escape, Qt.Key_Return, Qt.Key_Enter}:
|
||||
self.accept() # 다이얼로그 닫기
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = QApplication(sys.argv)
|
||||
viewer = ProductViewer("products.db")
|
||||
viewer.show()
|
||||
sys.exit(app.exec())
|
||||
|
|
@ -51,21 +51,29 @@ class BaiduImageSearcher:
|
|||
if self.playwright:
|
||||
self.playwright.stop()
|
||||
|
||||
def upload_image(self, image_path):
|
||||
def check_capcha(self):
|
||||
try:
|
||||
# 현재 URL 확인 및 로그 출력
|
||||
# current_url = self.page.url
|
||||
current_url = self.page.evaluate("() => window.location.href")
|
||||
self.logger.warning(f"Timeout occurred. Current URL: {current_url}")
|
||||
|
||||
self.logger.info(f"Current URL: {current_url}")
|
||||
|
||||
# 에러 페이지 조건 확인
|
||||
if current_url.startswith('https://graph.baidu.com/errpage'):
|
||||
self.logger.warning("Error page detected. Navigating back.")
|
||||
self.page.go_back() # 뒤로 가기
|
||||
# self.page.go_back() # 뒤로 가기
|
||||
# self.page.goto(self.initial_url) # 최초 접속 URL
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
except Exception as e:
|
||||
self.logger.error(f"Finding Error page occured ERROR: {e}", exc_info=True)
|
||||
return False
|
||||
|
||||
|
||||
def upload_image(self, image_path):
|
||||
try:
|
||||
if self.check_capcha():
|
||||
return False
|
||||
|
||||
# 첫 번째 검색과 이후 검색의 선택자를 다르게 설정
|
||||
# if self.is_first_search:
|
||||
|
|
@ -83,27 +91,45 @@ class BaiduImageSearcher:
|
|||
self.page.wait_for_selector(upload_button_xpath)
|
||||
self.page.click(upload_button_xpath)
|
||||
|
||||
if self.check_capcha():
|
||||
return False
|
||||
|
||||
self.page.wait_for_selector(upload_input_xpath)
|
||||
self.page.set_input_files(upload_input_xpath, image_path)
|
||||
return True
|
||||
except Exception as e:
|
||||
self.logger.error(f"Error in upload_image: {e}", exc_info=True)
|
||||
|
||||
def expand_results(self):
|
||||
# 확장 버튼 클릭 및 확장된 상품 카드 요소 로드 대기
|
||||
|
||||
if self.check_capcha():
|
||||
return False
|
||||
|
||||
self.logger.info("expand_results")
|
||||
expand_button_xpath = '//*[@id="app"]/div/div[2]/div/div[1]/ul/li[2]'
|
||||
self.page.wait_for_selector(expand_button_xpath)
|
||||
self.page.click(expand_button_xpath)
|
||||
|
||||
if self.check_capcha():
|
||||
return False
|
||||
|
||||
# 확장된 상품 카드 이미지 요소가 로드될 때까지 대기
|
||||
self.logger.info("확장된 상품 카드 이미지 요소가 로드될 때까지 대기")
|
||||
product_card_selector = 'div.graph-product-list-img img'
|
||||
self.page.wait_for_selector(product_card_selector)
|
||||
|
||||
if self.check_capcha():
|
||||
return False
|
||||
return True
|
||||
|
||||
def extract_product_data(self):
|
||||
# 검색 결과 페이지에서 JSON 데이터 추출
|
||||
if self.check_capcha():
|
||||
return False
|
||||
content = None
|
||||
self.logger.info("검색 결과 페이지에서 JSON 데이터 추출")
|
||||
content = self.page.content()
|
||||
|
||||
soup = BeautifulSoup(content, 'html.parser')
|
||||
script_tag = soup.select_one("html > head > script:nth-of-type(2)")
|
||||
|
||||
|
|
@ -113,7 +139,7 @@ class BaiduImageSearcher:
|
|||
match = re.search(r"window\.cardData\s*=\s*(\[\{.*\}\]);", raw_data, re.DOTALL)
|
||||
if match:
|
||||
json_data_str = match.group(1)
|
||||
|
||||
print(f"[json_data_str]\n{json_data_str}")
|
||||
try:
|
||||
data = json.loads(json_data_str)
|
||||
product_info = []
|
||||
|
|
@ -142,6 +168,8 @@ class BaiduImageSearcher:
|
|||
})
|
||||
self.logger.info("product_info 추출 완료")
|
||||
self.logger.info(f"{product_info}")
|
||||
input("로그를 확인한 후 아무 키나 눌러서 계속하세요...")
|
||||
|
||||
return product_info
|
||||
except json.JSONDecodeError as e:
|
||||
print("JSON 디코딩 오류:", e)
|
||||
|
|
|
|||
|
|
@ -20,6 +20,30 @@ class MainProcessor:
|
|||
|
||||
self.image_searcher.start_browser()
|
||||
|
||||
# # 각 상품에 대해 이미지 검색 수행
|
||||
# for product, product_id in zip(products, product_ids):
|
||||
# try:
|
||||
# if product_id is None:
|
||||
# self.logger.error("Failed to insert product into database.")
|
||||
# continue
|
||||
|
||||
# # 이미지 다운로드 및 검색 실행
|
||||
# image_path = self.image_downloader.download_image(product['image_url'], product_id)
|
||||
# is_success_upload_image = self.image_searcher.upload_image(image_path)
|
||||
# is_success_expand_results = self.image_searcher.expand_results()
|
||||
|
||||
# # 검색 결과를 추출하여 DB에 저장
|
||||
# search_results = self.image_searcher.extract_product_data()
|
||||
# self.db_manager.insert_search_results(product_id, search_results)
|
||||
|
||||
# os.remove(image_path)
|
||||
# self.logger.debug(f"Processed product ID: {product_id}")
|
||||
# time.sleep(1)
|
||||
# except Exception as e:
|
||||
# self.logger.warning(f"Failed to process product ID: {product_id} - {e}", exc_info=True)
|
||||
|
||||
|
||||
|
||||
# 각 상품에 대해 이미지 검색 수행
|
||||
for product, product_id in zip(products, product_ids):
|
||||
try:
|
||||
|
|
@ -29,20 +53,57 @@ class MainProcessor:
|
|||
|
||||
# 이미지 다운로드 및 검색 실행
|
||||
image_path = self.image_downloader.download_image(product['image_url'], product_id)
|
||||
self.image_searcher.upload_image(image_path)
|
||||
self.image_searcher.expand_results()
|
||||
|
||||
# 검색 결과를 추출하여 DB에 저장
|
||||
search_results = self.image_searcher.extract_product_data()
|
||||
# 재시도 횟수 설정
|
||||
max_retries = 3
|
||||
attempt = 0
|
||||
is_success_upload_image = False
|
||||
is_success_expand_results = False
|
||||
search_results = None
|
||||
|
||||
while attempt < max_retries:
|
||||
# upload_image 메서드 실행 및 성공 여부 확인
|
||||
is_success_upload_image = self.image_searcher.upload_image(image_path)
|
||||
if not is_success_upload_image:
|
||||
attempt += 1
|
||||
self.logger.warning(f"Upload image failed for Product ID [{product_id}]. Retry {attempt}/{max_retries}")
|
||||
time.sleep(1)
|
||||
continue # 재시도 시 루프를 다시 시작
|
||||
|
||||
# expand_results 메서드 실행 및 성공 여부 확인
|
||||
is_success_expand_results = self.image_searcher.expand_results()
|
||||
if not is_success_expand_results:
|
||||
attempt += 1
|
||||
self.logger.warning(f"Expand results failed for Product ID [{product_id}]. Retry {attempt}/{max_retries}")
|
||||
time.sleep(1)
|
||||
continue # 재시도 시 루프를 다시 시작
|
||||
|
||||
# 검색 결과 추출
|
||||
search_results = self.image_searcher.extract_product_data()
|
||||
if not search_results:
|
||||
attempt += 1
|
||||
self.logger.warning(f"Extract product data failed for Product ID [{product_id}]. Retry {attempt}/{max_retries}")
|
||||
time.sleep(1)
|
||||
continue # 재시도 시 루프를 다시 시작
|
||||
|
||||
# 모든 작업이 성공하면 루프 종료
|
||||
if is_success_upload_image and is_success_expand_results and search_results:
|
||||
break
|
||||
else:
|
||||
# 재시도 횟수 초과 시 경고 로그 출력 및 다음 제품으로 이동
|
||||
self.logger.error(f"Failed to process Product ID [{product_id}] after {max_retries} attempts.")
|
||||
continue
|
||||
|
||||
# 성공 시 검색 결과를 DB에 저장
|
||||
self.db_manager.insert_search_results(product_id, search_results)
|
||||
|
||||
os.remove(image_path)
|
||||
self.logger.debug(f"Processed product ID: {product_id}")
|
||||
time.sleep(1)
|
||||
|
||||
except Exception as e:
|
||||
self.logger.warning(f"Failed to process product ID: {product_id} - {e}", exc_info=True)
|
||||
|
||||
|
||||
def show_results(self):
|
||||
# 검색 결과 출력
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,167 @@
|
|||
from PySide6.QtWidgets import QWidget, QGridLayout, QLabel
|
||||
from PySide6.QtGui import QPixmap
|
||||
from PySide6.QtCore import Qt
|
||||
import requests
|
||||
|
||||
|
||||
class ProductCard(QWidget):
|
||||
def __init__(self, index=1):
|
||||
super().__init__()
|
||||
self.setFixedSize(220, 300)
|
||||
self.layout = QGridLayout(self)
|
||||
|
||||
# UI 요소 초기화
|
||||
self.index_label = QLabel(str(index))
|
||||
self.index_label.setAlignment(Qt.AlignCenter)
|
||||
self.index_label.setStyleSheet("font-weight: bold; font-size: 16px;")
|
||||
|
||||
self.image_label = QLabel()
|
||||
self.image_label.setFixedSize(200, 140)
|
||||
|
||||
self.name_label = QLabel("상품명:")
|
||||
self.name_value = QLabel("")
|
||||
self.name_value.setWordWrap(True)
|
||||
self.name_value.setFixedSize(120, 50)
|
||||
|
||||
self.price_label = QLabel("가격:")
|
||||
self.price_value = QLabel("")
|
||||
|
||||
self.select_label = QLabel("미선택")
|
||||
self.select_label.setAlignment(Qt.AlignCenter)
|
||||
self.select_label.setStyleSheet("font-weight: bold; color: black;")
|
||||
|
||||
# 레이아웃 구성
|
||||
self.layout.addWidget(self.index_label, 0, 0, 1, 2)
|
||||
self.layout.addWidget(self.image_label, 1, 0, 1, 2)
|
||||
self.layout.addWidget(self.name_label, 2, 0)
|
||||
self.layout.addWidget(self.name_value, 2, 1)
|
||||
self.layout.addWidget(self.price_label, 3, 0)
|
||||
self.layout.addWidget(self.price_value, 3, 1)
|
||||
self.layout.addWidget(self.select_label, 4, 0, 1, 2)
|
||||
|
||||
def reset(self):
|
||||
"""카드의 데이터를 초기화합니다."""
|
||||
self.name_value.setText("")
|
||||
self.price_value.setText("")
|
||||
self.image_label.clear()
|
||||
self.set_selected(False)
|
||||
|
||||
def set_data(self, name, price, img_url):
|
||||
"""카드에 상품 데이터를 설정합니다."""
|
||||
self.name_value.setText(name)
|
||||
self.price_value.setText(str(price))
|
||||
|
||||
# 이미지 설정
|
||||
pixmap = QPixmap()
|
||||
img_data = self.download_image_data(img_url)
|
||||
if img_data:
|
||||
pixmap.loadFromData(img_data)
|
||||
self.image_label.setPixmap(pixmap.scaled(self.image_label.size(), Qt.KeepAspectRatio))
|
||||
else:
|
||||
self.image_label.clear()
|
||||
|
||||
def download_image_data(self, img_url):
|
||||
"""이미지 URL에서 데이터를 다운로드합니다."""
|
||||
try:
|
||||
response = requests.get(img_url)
|
||||
if response.status_code == 200:
|
||||
return response.content
|
||||
except Exception as e:
|
||||
print(f"Image download error: {e}")
|
||||
return None
|
||||
|
||||
def set_selected(self, selected):
|
||||
"""카드의 선택 상태를 설정합니다."""
|
||||
if selected:
|
||||
self.select_label.setText("선택")
|
||||
self.select_label.setStyleSheet("font-weight: bold; color: red;")
|
||||
self.setStyleSheet("border: 2px solid red;")
|
||||
else:
|
||||
self.select_label.setText("미선택")
|
||||
self.select_label.setStyleSheet("font-weight: bold; color: black;")
|
||||
self.setStyleSheet("border: 1px solid grey;")
|
||||
|
||||
|
||||
class SearchResultCard(QWidget):
|
||||
def __init__(self, index=1):
|
||||
super().__init__()
|
||||
self.setFixedSize(220, 300)
|
||||
self.layout = QGridLayout(self)
|
||||
|
||||
# UI 요소 초기화
|
||||
self.index_label = QLabel(str(index))
|
||||
self.index_label.setAlignment(Qt.AlignCenter)
|
||||
self.index_label.setStyleSheet("font-weight: bold; font-size: 16px;")
|
||||
|
||||
self.image_label = QLabel()
|
||||
self.image_label.setFixedSize(200, 140)
|
||||
|
||||
self.name_label = QLabel("상품명:")
|
||||
self.name_value = QLabel("")
|
||||
self.name_value.setWordWrap(True)
|
||||
self.name_value.setFixedSize(120, 50)
|
||||
|
||||
self.price_label = QLabel("가격:")
|
||||
self.price_value = QLabel("")
|
||||
|
||||
self.source_label = QLabel("출처:")
|
||||
self.source_value = QLabel("")
|
||||
|
||||
self.select_label = QLabel("미선택")
|
||||
self.select_label.setAlignment(Qt.AlignCenter)
|
||||
self.select_label.setStyleSheet("font-weight: bold; color: black;")
|
||||
|
||||
# 레이아웃 구성
|
||||
self.layout.addWidget(self.index_label, 0, 0, 1, 2)
|
||||
self.layout.addWidget(self.image_label, 1, 0, 1, 2)
|
||||
self.layout.addWidget(self.name_label, 2, 0)
|
||||
self.layout.addWidget(self.name_value, 2, 1)
|
||||
self.layout.addWidget(self.price_label, 3, 0)
|
||||
self.layout.addWidget(self.price_value, 3, 1)
|
||||
self.layout.addWidget(self.source_label, 4, 0)
|
||||
self.layout.addWidget(self.source_value, 4, 1)
|
||||
self.layout.addWidget(self.select_label, 5, 0, 1, 2)
|
||||
|
||||
def reset(self):
|
||||
"""카드의 데이터를 초기화합니다."""
|
||||
self.name_value.setText("")
|
||||
self.price_value.setText("")
|
||||
self.source_value.setText("")
|
||||
self.image_label.clear()
|
||||
self.set_selected(False)
|
||||
|
||||
def set_data(self, name, price, source, img_url):
|
||||
"""카드에 검색 결과 데이터를 설정합니다."""
|
||||
self.name_value.setText(name)
|
||||
self.price_value.setText(price)
|
||||
self.source_value.setText(source)
|
||||
|
||||
# 이미지 설정
|
||||
pixmap = QPixmap()
|
||||
img_data = self.download_image_data(img_url)
|
||||
if img_data:
|
||||
pixmap.loadFromData(img_data)
|
||||
self.image_label.setPixmap(pixmap.scaled(self.image_label.size(), Qt.KeepAspectRatio))
|
||||
else:
|
||||
self.image_label.clear()
|
||||
|
||||
def download_image_data(self, img_url):
|
||||
"""이미지 URL에서 데이터를 다운로드합니다."""
|
||||
try:
|
||||
response = requests.get(img_url)
|
||||
if response.status_code == 200:
|
||||
return response.content
|
||||
except Exception as e:
|
||||
print(f"Image download error: {e}")
|
||||
return None
|
||||
|
||||
def set_selected(self, selected):
|
||||
"""카드의 선택 상태를 설정합니다."""
|
||||
if selected:
|
||||
self.select_label.setText("선택")
|
||||
self.select_label.setStyleSheet("font-weight: bold; color: red;")
|
||||
self.setStyleSheet("border: 2px solid red;")
|
||||
else:
|
||||
self.select_label.setText("미선택")
|
||||
self.select_label.setStyleSheet("font-weight: bold; color: black;")
|
||||
self.setStyleSheet("border: 1px solid grey;")
|
||||
BIN
products.db
|
|
@ -0,0 +1,167 @@
|
|||
from PySide6.QtWidgets import QWidget, QGridLayout, QLabel
|
||||
from PySide6.QtGui import QPixmap
|
||||
from PySide6.QtCore import Qt
|
||||
import requests
|
||||
|
||||
|
||||
class ProductCard(QWidget):
|
||||
def __init__(self, index=1):
|
||||
super().__init__()
|
||||
self.setFixedSize(220, 300)
|
||||
self.layout = QGridLayout(self)
|
||||
|
||||
# UI 요소 초기화
|
||||
self.index_label = QLabel(str(index))
|
||||
self.index_label.setAlignment(Qt.AlignCenter)
|
||||
self.index_label.setStyleSheet("font-weight: bold; font-size: 16px;")
|
||||
|
||||
self.image_label = QLabel()
|
||||
self.image_label.setFixedSize(200, 140)
|
||||
|
||||
self.name_label = QLabel("상품명:")
|
||||
self.name_value = QLabel("")
|
||||
self.name_value.setWordWrap(True)
|
||||
self.name_value.setFixedSize(120, 50)
|
||||
|
||||
self.price_label = QLabel("가격:")
|
||||
self.price_value = QLabel("")
|
||||
|
||||
self.select_label = QLabel("미선택")
|
||||
self.select_label.setAlignment(Qt.AlignCenter)
|
||||
self.select_label.setStyleSheet("font-weight: bold; color: black;")
|
||||
|
||||
# 레이아웃 구성
|
||||
self.layout.addWidget(self.index_label, 0, 0, 1, 2)
|
||||
self.layout.addWidget(self.image_label, 1, 0, 1, 2)
|
||||
self.layout.addWidget(self.name_label, 2, 0)
|
||||
self.layout.addWidget(self.name_value, 2, 1)
|
||||
self.layout.addWidget(self.price_label, 3, 0)
|
||||
self.layout.addWidget(self.price_value, 3, 1)
|
||||
self.layout.addWidget(self.select_label, 4, 0, 1, 2)
|
||||
|
||||
def reset(self):
|
||||
"""카드의 데이터를 초기화합니다."""
|
||||
self.name_value.setText("")
|
||||
self.price_value.setText("")
|
||||
self.image_label.clear()
|
||||
self.set_selected(False)
|
||||
|
||||
def set_data(self, name, price, img_url):
|
||||
"""카드에 상품 데이터를 설정합니다."""
|
||||
self.name_value.setText(name)
|
||||
self.price_value.setText(price)
|
||||
|
||||
# 이미지 설정
|
||||
pixmap = QPixmap()
|
||||
img_data = self.download_image_data(img_url)
|
||||
if img_data:
|
||||
pixmap.loadFromData(img_data)
|
||||
self.image_label.setPixmap(pixmap.scaled(self.image_label.size(), Qt.KeepAspectRatio))
|
||||
else:
|
||||
self.image_label.clear()
|
||||
|
||||
def download_image_data(self, img_url):
|
||||
"""이미지 URL에서 데이터를 다운로드합니다."""
|
||||
try:
|
||||
response = requests.get(img_url)
|
||||
if response.status_code == 200:
|
||||
return response.content
|
||||
except Exception as e:
|
||||
print(f"Image download error: {e}")
|
||||
return None
|
||||
|
||||
def set_selected(self, selected):
|
||||
"""카드의 선택 상태를 설정합니다."""
|
||||
if selected:
|
||||
self.select_label.setText("선택")
|
||||
self.select_label.setStyleSheet("font-weight: bold; color: red;")
|
||||
self.setStyleSheet("border: 2px solid red;")
|
||||
else:
|
||||
self.select_label.setText("미선택")
|
||||
self.select_label.setStyleSheet("font-weight: bold; color: black;")
|
||||
self.setStyleSheet("border: 1px solid grey;")
|
||||
|
||||
|
||||
class SearchResultCard(QWidget):
|
||||
def __init__(self, index=1):
|
||||
super().__init__()
|
||||
self.setFixedSize(220, 300)
|
||||
self.layout = QGridLayout(self)
|
||||
|
||||
# UI 요소 초기화
|
||||
self.index_label = QLabel(str(index))
|
||||
self.index_label.setAlignment(Qt.AlignCenter)
|
||||
self.index_label.setStyleSheet("font-weight: bold; font-size: 16px;")
|
||||
|
||||
self.image_label = QLabel()
|
||||
self.image_label.setFixedSize(200, 140)
|
||||
|
||||
self.name_label = QLabel("상품명:")
|
||||
self.name_value = QLabel("")
|
||||
self.name_value.setWordWrap(True)
|
||||
self.name_value.setFixedSize(120, 50)
|
||||
|
||||
self.price_label = QLabel("가격:")
|
||||
self.price_value = QLabel("")
|
||||
|
||||
self.source_label = QLabel("출처:")
|
||||
self.source_value = QLabel("")
|
||||
|
||||
self.select_label = QLabel("미선택")
|
||||
self.select_label.setAlignment(Qt.AlignCenter)
|
||||
self.select_label.setStyleSheet("font-weight: bold; color: black;")
|
||||
|
||||
# 레이아웃 구성
|
||||
self.layout.addWidget(self.index_label, 0, 0, 1, 2)
|
||||
self.layout.addWidget(self.image_label, 1, 0, 1, 2)
|
||||
self.layout.addWidget(self.name_label, 2, 0)
|
||||
self.layout.addWidget(self.name_value, 2, 1)
|
||||
self.layout.addWidget(self.price_label, 3, 0)
|
||||
self.layout.addWidget(self.price_value, 3, 1)
|
||||
self.layout.addWidget(self.source_label, 4, 0)
|
||||
self.layout.addWidget(self.source_value, 4, 1)
|
||||
self.layout.addWidget(self.select_label, 5, 0, 1, 2)
|
||||
|
||||
def reset(self):
|
||||
"""카드의 데이터를 초기화합니다."""
|
||||
self.name_value.setText("")
|
||||
self.price_value.setText("")
|
||||
self.source_value.setText("")
|
||||
self.image_label.clear()
|
||||
self.set_selected(False)
|
||||
|
||||
def set_data(self, name, price, source, img_url):
|
||||
"""카드에 검색 결과 데이터를 설정합니다."""
|
||||
self.name_value.setText(name)
|
||||
self.price_value.setText(price)
|
||||
self.source_value.setText(source)
|
||||
|
||||
# 이미지 설정
|
||||
pixmap = QPixmap()
|
||||
img_data = self.download_image_data(img_url)
|
||||
if img_data:
|
||||
pixmap.loadFromData(img_data)
|
||||
self.image_label.setPixmap(pixmap.scaled(self.image_label.size(), Qt.KeepAspectRatio))
|
||||
else:
|
||||
self.image_label.clear()
|
||||
|
||||
def download_image_data(self, img_url):
|
||||
"""이미지 URL에서 데이터를 다운로드합니다."""
|
||||
try:
|
||||
response = requests.get(img_url)
|
||||
if response.status_code == 200:
|
||||
return response.content
|
||||
except Exception as e:
|
||||
print(f"Image download error: {e}")
|
||||
return None
|
||||
|
||||
def set_selected(self, selected):
|
||||
"""카드의 선택 상태를 설정합니다."""
|
||||
if selected:
|
||||
self.select_label.setText("선택")
|
||||
self.select_label.setStyleSheet("font-weight: bold; color: red;")
|
||||
self.setStyleSheet("border: 2px solid red;")
|
||||
else:
|
||||
self.select_label.setText("미선택")
|
||||
self.select_label.setStyleSheet("font-weight: bold; color: black;")
|
||||
self.setStyleSheet("border: 1px solid grey;")
|
||||
BIN
temp/12.jpg
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 116 KiB |
|
After Width: | Height: | Size: 116 KiB |
|
After Width: | Height: | Size: 72 KiB |
BIN
temp/4.jpg
|
Before Width: | Height: | Size: 15 KiB |
BIN
temp/7.jpg
|
Before Width: | Height: | Size: 66 KiB |
BIN
temp/8.jpg
|
Before Width: | Height: | Size: 15 KiB |