DeliveryFeeCalc/delv.py

1275 lines
54 KiB
Python

import sys
import configparser
import os, signal
import pandas as pd
import logging
from PyQt5.QtCore import Qt
from qasync import QEventLoop # qasync 이벤트 루프 임포트
from PyQt5 import QtWidgets, QtCore
from PyQt5.QtGui import QFont
import re, json
from src.toggleSwitch import ToggleSwitch # toggleSwitch.py 파일에서 ToggleSwitch 클래스를 임포트
from src.logger_module import setup_logger
import ctypes
from src.kipris_settingUI import SettingsDialog
from src.kipris_api_from_publicdata import Kipris_API
# from src.kipris_web_from_playwright import Kipris_WEB
from src.kiprisThread import *
# from src.search_display import TrademarkSearchDisplay
from src.OptionTranslator import optionTrans
from src.result_widget import ResultWidget
from forex_python.converter import CurrencyRates
from currency_converter import CurrencyConverter
from src.kiprisEvent import LineEditWithHistory
from qfluentwidgets import IndeterminateProgressRing, setTheme, toggleTheme, Theme
# def minimize_console():
# """ 콘솔 창을 최소화하는 함수 """
# hwnd = ctypes.windll.kernel32.GetConsoleWindow()
# if hwnd != 0:
# ctypes.windll.user32.ShowWindow(hwnd, 6) # SW_MINIMIZE
class DeliveryFeeCalculator(QtWidgets.QWidget):
def __init__(self, logger):
super().__init__()
self.logger = logger
# self.config = configparser.ConfigParser()
self.config_path = 'config.ini'
self.is_dark_theme = False # 다크 테마 상태 저장
self.dialogs = [] # 열린 다이얼로그와 창들을 저장할 리스트
self.use_kipris = False
self.usage_mode = "web"
self.api_key = ""
self.kiprisAPI = None
self.searchThread = None # 스레드 객체를 저장할 멤버 변수 추가
self.asyncWorker = None
self.search_keyword = None
self.set_status =[]
self.web_scraper = None # 웹방식 Playwright 객체 미리 초기화
self.currentURL = ""
self.config_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'config.json')
self.history_model = QtCore.QStringListModel()
self.maxWeightSet = 25
self.maxLengthSet = 100
self.maxVolumeSet = 160
self.currentMaxLength = 1
self.roundVolume = 1
self.currentWeight = 1
self.currentVolume = 1
self.fontSize = 14
self.weightInterval = 0.5
self.setSaveSetting = True
self.addFee = 1000
self.addFeeSetting = 20
self.addFeeInterval = 5
self.setUSD = None
self.setCNY = None
self.currentCurrency = None
# self.searchDisplay = TrademarkSearchDisplay()
self.searchDisplayWidget = ResultWidget()
self.currencyInfo = CurrencyRates()
self.currencyConv = CurrencyConverter()
self.favoriteDelv = ""
self.cargo_font = QFont()
self.cargo_font_size = self.fontSize + 2
self.deliveryFees = {}
self.initSettings()
self.initUI()
self.loadDeliveryFees()
self.setDefaultValues()
self.kipris_Visible()
self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint)
# self.setAddInterval(self.addFeeInterval)
# self.setAddMoneySetting(self.addFee)
self.setFontSize(self.fontSize)
self.font_size_spinbox.setValue(self.fontSize)
self.addMoney1_spinbox.setValue(self.addFeeSetting)
self.addMoney2_spinbox.setValue(self.addFeeInterval)
self.addMoney3_spinbox.setValue(self.addFee)
self.saveSettingSwitch.setChecked(self.setSaveSetting)
self.step_interval_spinbox.setValue(self.weightInterval)
self.maxVolume_spinbox.setValue(self.maxVolumeSet)
self.maxWeight_spinbox.setValue(self.maxWeightSet)
self.maxLength_spinbox.setValue(self.maxLengthSet)
self.setComboBox()
def initSettings(self):
# self.settings = QtCore.QSettings('When_Ride_Mycar_Tanya', 'DeliveryFeeCalculator')
self.loadSettings()
self.load_history()
self.user_settings = {
'use_kipris': self.use_kipris,
'usage_mode': self.usage_mode,
'api_key': self.api_key,
'set_status': self.set_status,
}
self.settingDialog = SettingsDialog(parent=self, initial_settings=self.user_settings)
currencis = ['USD', 'CNY']
try:
# CurrencyConverter로 환율 정보 가져오기
self.setUSD = int(self.currencyConv.convert(1, 'USD', 'KRW'))
logger.debug(f"CurrencyConverter USD to KRW: {self.setUSD}")
self.setCNY = int(self.currencyConv.convert(1, 'CNY', 'KRW'))
logger.debug(f"CurrencyConverter CNY to KRW: {self.setCNY}")
except Exception as e:
logger.error(f"CurrencyConverter 에서 환율 조회 중 에러발생: {e}")
print(f"CurrencyConverter 에러, forex-python에서 값을 가져옵니다.")
try:
# forex-python으로 환율 정보 가져오기
self.setUSD = int(self.currencyRates.get_rate('USD', 'KRW'))
logger.debug(f"forex-python USD to KRW: {self.setUSD}")
self.setCNY = int(self.currencyRates.get_rate('CNY', 'KRW'))
logger.debug(f"forex-python CNY to KRW: {self.setCNY}")
except Exception as e2:
logger.error(f"forex-python 에서 환율 조회 중 에러발생: {e2}")
print(f"forex-python 에러, 기본값을 사용합니다.")
# 기본 환율 설정
self.setUSD = 1350
self.setCNY = 195
logger.debug(f"기본 USD: {self.setUSD}, 기본 CNY: {self.setCNY}")
# 현재 통화를 CNY로 설정
self.currentCurrency = self.setCNY
def saveSettings(self):
""" 설정을 JSON 파일에 저장합니다. """
try:
settings = {
'Settings': {
'maxWeightSet': self.maxWeightSet,
'maxLengthSet': self.maxLengthSet,
'maxVolumeSet': self.maxVolumeSet,
'addFeeInterval': self.addFeeInterval,
'addFeeSetting': self.addFeeSetting,
'addFee': self.addFee,
'fontSize': self.fontSize,
'weightInterval': self.weightInterval,
'setSaveSetting': self.setSaveSetting,
'favoriteDelv': self.favoriteDelv,
},
'Kipris': {
'use_kipris': self.use_kipris,
'usage_mode': self.usage_mode,
'api_key': self.api_key,
'set_status': self.set_status,
}
}
with open(self.config_path, 'w') as config_file:
json.dump(settings, config_file, indent=4)
logger.info("설정이 성공적으로 저장되었습니다.")
except Exception as e:
logger.error(f"설정을 저장하는 중 오류가 발생했습니다: {e}", exc_info=True)
def loadSettings(self):
""" 설정 파일을 불러옵니다. """
try:
if not os.path.exists(self.config_path):
self.create_default_settings()
with open(self.config_path, 'r') as config_file:
settings = json.load(config_file)
s = settings['Settings']
self.maxWeightSet = s['maxWeightSet']
self.maxLengthSet = s['maxLengthSet']
self.maxVolumeSet = s['maxVolumeSet']
self.addFeeInterval = s['addFeeInterval']
self.addFeeSetting = s['addFeeSetting']
self.addFee = s['addFee']
self.fontSize = s['fontSize']
self.weightInterval = s['weightInterval']
self.setSaveSetting = s['setSaveSetting']
self.favoriteDelv = s['favoriteDelv']
k = settings['Kipris']
self.use_kipris = k['use_kipris']
self.usage_mode = k['usage_mode']
self.api_key = k['api_key']
self.set_status = k['set_status']
logger.info("설정이 성공적으로 불러와졌습니다.")
except Exception as e:
logger.error(f"설정을 불러오는 중 오류가 발생했습니다: {e}", exc_info=True)
def create_default_settings(self):
""" 기본 설정을 생성합니다. """
settings = {
'Settings': {
'maxWeightSet': 25,
'maxLengthSet': 100,
'maxVolumeSet': 160,
'addFeeInterval': 5,
'addFeeSetting': 20,
'addFee': 1000,
'fontSize': 14,
'weightInterval': 0.5,
'setSaveSetting': False,
'favoriteDelv': "노빠꾸해운(배송비)"
},
'Kipris': {
'use_kipris': False,
'usage_mode': 'web',
'api_key': '',
'set_status': ['등록'],
}
}
with open(self.config_path, 'w') as config_file:
json.dump(settings, config_file, indent=4)
logger.info("기본 설정이 생성되었습니다.")
def add_history(self, keyword):
if keyword:
current_history = self.history_model.stringList()
if keyword not in current_history: # 중복된 검색어가 아니면 추가
current_history.append(keyword)
self.history_model.setStringList(current_history)
logger.debug(f"검색어 [{keyword}] 히스토리에 추가")
def load_history(self):
try:
with open("search_history.json", "r") as file:
history_list = json.load(file)
self.history_model.setStringList(history_list)
logger.debug(f"self.history file loaded: {history_list}")
except (FileNotFoundError, json.JSONDecodeError):
self.history_model.setStringList([])
logger.debug(f"self.history: []")
def save_history(self):
with open("search_history.json", "w") as file:
json.dump(self.history_model.stringList(), file)
def show_history_menu(self, event):
current_history = self.history_model.stringList()
if current_history:
menu = QtWidgets.QMenu(self)
for keyword in current_history:
menu.addAction(keyword, lambda k=keyword: self.kipris_edit.setText(k))
menu.exec_(self.kipris_edit.mapToGlobal(event.pos()))
def closeEvent(self, event):
# 설정 저장 여부 로그 기록
if self.setSaveSetting:
logger.debug("설정값 저장")
self.saveSettings() # 설정 저장
# self.saveWindowSettings() # 필요한 경우 윈도우 설정 저장
else:
logger.debug("설정값 저장하지 않음")
# 검색 히스토리 저장
self.save_history()
# 부모 클래스의 종료 이벤트 처리 호출
super().closeEvent(event)
# 이벤트 처리 완료를 알림
event.accept()
# 프로그램 완전히 종료
QtWidgets.QApplication.quit() # Qt 애플리케이션 종료
# 프로세스 강제 종료 (필요 시 사용)
os.kill(os.getpid(), signal.SIGTERM)
def add_dialog(self, dialog):
"""열린 다이얼로그나 창을 리스트에 추가"""
self.dialogs.append(dialog)
def initUI(self):
self.resize(300, 600) # 창 크기 조정
self.center()
# 메뉴바 생성
menubar = QtWidgets.QMenuBar(self)
helpMenu = menubar.addMenu('도움말')
kiprisMenu = menubar.addMenu('키프리스')
# 도움말 - 도움말 보기 메뉴 아이템
helpnemu_helpAction = QtWidgets.QAction('도움말 보기', self)
helpnemu_helpAction.triggered.connect(self.showHelp)
helpMenu.addAction(helpnemu_helpAction)
# 도움말 - ChangeLog 메뉴 아이템
helpnemu_changelogAction = QtWidgets.QAction('ChangeLog', self)
helpnemu_changelogAction.triggered.connect(self.showChangeLog)
helpMenu.addAction(helpnemu_changelogAction)
# 도움말 - 기본값 설정 메뉴 아이템
helpnemu_defaultAction = QtWidgets.QAction('기본값 설정', self)
helpnemu_defaultAction.triggered.connect(self.setttingTosetDefaultValues)
helpMenu.addAction(helpnemu_defaultAction)
# # '설정창 열기' 메뉴 아이템
openSettingsAction = QtWidgets.QAction('설정창 열기', self)
openSettingsAction.triggered.connect(self.showSettingsDialog)
kiprisMenu.addAction(openSettingsAction)
# # 키프리스 - APIKEY 메뉴 아이템
# kiprismenu_settingAction = QtWidgets.QAction('키프리스 ', self)
# kiprismenu_settingAction.triggered.connect(self.showHelp)
# kiprisMenu.addAction(kiprismenu_settingAction)
# # 도움말 - ChangeLog 메뉴 아이템
# changelogAction = QtWidgets.QAction('ChangeLog', self)
# changelogAction.triggered.connect(self.showChangeLog)
# kiprisMenu.addAction(changelogAction)
# # 도움말 - 기본값 설정 메뉴 아이템
# defaultAction = QtWidgets.QAction('기본값 설정', self)
# defaultAction.triggered.connect(self.setttingTosetDefaultValues)
# kiprisMenu.addAction(defaultAction)
# 레이아웃 전체 설정
self.layout = QtWidgets.QVBoxLayout(self)
self.layout.setMenuBar(menubar)
# 사용자 인터페이스 프레임
self.user_frame = QtWidgets.QFrame(self)
self.user_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.user_frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.user_layout = QtWidgets.QVBoxLayout(self.user_frame)
# 콤보박스 초기화
self.comboBox = QtWidgets.QComboBox()
self.comboBox.currentIndexChanged.connect(self.updateComboBox) # 값이 변경될 때 이벤트 연결
self.user_layout.addWidget(self.comboBox)
# 무게입력 박스 초기화
self.weightInput = QtWidgets.QDoubleSpinBox()
self.weightInput.setMinimum(0.5)
self.weightInput.setMaximum(1000)
self.weightInput.setSingleStep(self.weightInterval)
self.weightInput.setSuffix(" Kg")
self.weightInput.valueChanged.connect(self.updateDeliveryFee) # 값이 변경될 때 이벤트 연결
self.user_layout.addWidget(self.weightInput)
# 부피 입력 칸: 가로, 세로, 높이
self.dimension_layout = QtWidgets.QHBoxLayout()
# 길이 레이아웃
self.lengthInput = QtWidgets.QSpinBox()
self.lengthInput.setMinimum(1)
self.lengthInput.setMaximum(10000)
self.lengthInput.setSuffix(" cm")
self.lengthInput.valueChanged.connect(self.updateVolume)
self.lengthInput_layout = self.create_label_and_spin_in_QV("가로(cm):", self.lengthInput)
self.dimension_layout.addLayout(self.lengthInput_layout)
# 넓이 레이아웃
self.widthInput = QtWidgets.QSpinBox()
self.widthInput.setMinimum(1)
self.widthInput.setMaximum(10000)
self.widthInput.setSuffix(" cm")
self.widthInput.valueChanged.connect(self.updateVolume)
self.widthInput_layout = self.create_label_and_spin_in_QV("세로(cm):", self.widthInput)
self.dimension_layout.addLayout(self.widthInput_layout)
# 높이 레이아웃
self.heightInput = QtWidgets.QSpinBox()
self.heightInput.setMinimum(1)
self.heightInput.setMaximum(10000)
self.heightInput.setSuffix(" cm")
self.heightInput.valueChanged.connect(self.updateVolume)
self.heightInput_layout = self.create_label_and_spin_in_QV("높이(cm):", self.heightInput)
self.dimension_layout.addLayout(self.heightInput_layout)
# 리셋 레이아웃
self.reset_layout = QtWidgets.QVBoxLayout()
self.reset_label = QtWidgets.QLabel("리셋")
self.reset_layout.addWidget(self.reset_label)
self.reset_button = QtWidgets.QPushButton("Reset")
self.reset_label.setAlignment(QtCore.Qt.AlignCenter)
self.reset_button.clicked.connect(self.reset_action)
self.reset_layout.addWidget(self.reset_button)
self.dimension_layout.addLayout(self.reset_layout)
self.user_layout.addLayout(self.dimension_layout)
# 레이아웃 비율 설정
self.dimension_layout.setStretch(0, 3) # 길이 입력 칸
self.dimension_layout.setStretch(1, 3) # 너비 입력 칸
self.dimension_layout.setStretch(2, 3) # 높이 입력 칸
self.dimension_layout.setStretch(3, 1) # 새로 추가된 리셋 레이아웃
# 사용자 정보 프레임
self.user_info_frame = QtWidgets.QFrame(self)
self.user_info_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.user_info_frame.setFrameShadow(QtWidgets.QFrame.Sunken)
self.user_info_layout = QtWidgets.QVBoxLayout(self.user_info_frame)
# 배송비 레이이웃 추가 설정 중
self.final_delv_fee_layout = QtWidgets.QHBoxLayout()
self.deliveryFeeLabel = QtWidgets.QLabel("배송비: 정보 없음")
self.deliveryFeeADDLabel = QtWidgets.QLabel(f"가중치: {self.addFee}")
self.deliveryFeeADDLabel.setVisible(False)
self.final_delv_fee_layout.addWidget(self.deliveryFeeLabel)
self.final_delv_fee_layout.addWidget(self.deliveryFeeADDLabel)
self.user_info_layout.addLayout(self.final_delv_fee_layout)
# 부피 라벨
self.volumeLabel = QtWidgets.QLabel("부피무게: 정보 없음")
self.user_info_layout.addWidget(self.volumeLabel)
# 크기 라벨
self.maxLengthLabel = QtWidgets.QLabel("한 변의 최대길이 : 정보없음")
self.maxLengthLabel.setVisible(False)
self.user_info_layout.addWidget(self.maxLengthLabel)
# 추가운임 정보 라벨
self.additionalFeeTextLabel = QtWidgets.QLabel("화물택배(경동)추가운임 발생. 모든값은 참고치입니다.")
self.additionalFeeTextLabel.setVisible(False)
self.user_info_layout.addWidget(self.additionalFeeTextLabel)
# 추가운임 라벨
self.additionalFeeLabel = QtWidgets.QLabel("화물택배(경동)추가운임")
self.additionalFeeLabel.setVisible(False)
self.user_info_layout.addWidget(self.additionalFeeLabel)
# 설정 프레임
self.setting_frame = QtWidgets.QFrame(self)
self.setting_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.setting_frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.setting_layout = QtWidgets.QVBoxLayout(self.setting_frame)
# 폰트 크기 설정 스핀박스
self.font_size_spinbox = QtWidgets.QSpinBox()
self.font_size_spinbox.setRange(10, 50)
self.font_size_spinbox.setValue(self.fontSize)
self.font_size_spinbox.valueChanged.connect(self.setFontSize)
self.font_size_spinbox_layout = self.create_label_and_spin("폰트 크기", self.font_size_spinbox)
self.setting_layout.addLayout(self.font_size_spinbox_layout)
# 스텝 간격 조정 스핀박스
self.step_interval_spinbox = QtWidgets.QDoubleSpinBox()
self.step_interval_spinbox.setRange(0.5, 10)
self.step_interval_spinbox.setSingleStep(0.5)
self.step_interval_spinbox.setValue(0.5)
self.step_interval_spinbox.setSuffix(" Kg")
self.step_interval_spinbox.valueChanged.connect(self.setStepInterval)
self.step_interval_spinbox_layout = self.create_label_and_spin("무게 간격", self.step_interval_spinbox)
self.setting_layout.addLayout(self.step_interval_spinbox_layout)
# 경동택배 기준설정
self.cargo_Layout = QtWidgets.QHBoxLayout()
self.cargoLabel_upper = QtWidgets.QLabel()
self.cargoLabel = QtWidgets.QLabel()
self.cargoLabel_bottom = QtWidgets.QLabel()
self.cargoLabel.setText("경동택배 설정")
self.cargoLabel.setAlignment(QtCore.Qt.AlignCenter)
self.cargo_font.setPointSize(self.cargo_font_size) # 폰트 크기를 16포인트로 설정
self.cargoLabel.setFont(self.cargo_font)
self.cargoLabel.setStyleSheet("background-color: lightgrey;")
self.cargo_Layout.addWidget(self.cargoLabel_upper)
self.cargo_Layout.addWidget(self.cargoLabel)
self.cargo_Layout.addWidget(self.cargoLabel_bottom)
self.setting_layout.addLayout(self.cargo_Layout)
# 경동택배 길이기준 조정 스핀박스
self.maxLength_spinbox = QtWidgets.QSpinBox()
self.maxLength_spinbox.setRange(80, 200)
self.maxLength_spinbox.setSingleStep(5)
self.maxLength_spinbox.setValue(100)
self.maxLength_spinbox.setSuffix(" cm")
self.maxLength_spinbox.valueChanged.connect(self.setMaxLength)
self.maxLength_spinbox_layout = self.create_label_and_spin("경동한변길이 설정", self.maxLength_spinbox)
self.setting_layout.addLayout(self.maxLength_spinbox_layout)
# 경동택배 부피기준 조정 스핀박스
self.maxVolume_spinbox = QtWidgets.QSpinBox()
self.maxVolume_spinbox.setRange(140, 200)
self.maxVolume_spinbox.setSingleStep(5)
self.maxVolume_spinbox.setValue(160)
self.maxVolume_spinbox.setSuffix(" cm")
self.maxVolume_spinbox.valueChanged.connect(self.setMaxVolume)
self.maxVolume_spinbox_layout = self.create_label_and_spin("경동(세변합)기준 설정", self.maxVolume_spinbox)
self.setting_layout.addLayout(self.maxVolume_spinbox_layout)
# 경동택배 무게기준 조정 스핀박스
self.maxWeight_spinbox = QtWidgets.QSpinBox()
self.maxWeight_spinbox.setRange(10, 50)
self.maxWeight_spinbox.setSingleStep(1)
self.maxWeight_spinbox.setValue(25)
self.maxWeight_spinbox.setSuffix(" Kg")
self.maxWeight_spinbox.valueChanged.connect(self.setMaxWeight)
self.maxWeight_spinbox_layout = self.create_label_and_spin("경동무게기준 설정", self.maxWeight_spinbox)
self.setting_layout.addLayout(self.maxWeight_spinbox_layout)
# 가중치 스핀박스
self.addMoneySetlayout1 = QtWidgets.QHBoxLayout()
self.addMoneySetlayout2 = QtWidgets.QHBoxLayout()
self.addMoneySetlayout3 = QtWidgets.QHBoxLayout()
self.label1 = QtWidgets.QLabel("가중치 기준")
self.label2 = QtWidgets.QLabel(" 초과시 ")
self.label3 = QtWidgets.QLabel(" 마다 ")
self.label4 = QtWidgets.QLabel("추가")
self.addMoney1_spinbox = QtWidgets.QSpinBox()
self.addMoney1_spinbox.setRange(0, 1000)
self.addMoney1_spinbox.setSingleStep(1)
self.addMoney1_spinbox.setValue(20)
self.addMoney1_spinbox.setSuffix(" Kg")
self.addMoney1_spinbox.valueChanged.connect(self.setAddMoneySetting)
self.addMoney2_spinbox = QtWidgets.QSpinBox()
self.addMoney2_spinbox.setRange(0, 1000)
self.addMoney2_spinbox.setSingleStep(1)
self.addMoney2_spinbox.setValue(5)
self.addMoney2_spinbox.setSuffix(" Kg")
self.addMoney2_spinbox.valueChanged.connect(self.setAddInterval)
self.addMoney3_spinbox = QtWidgets.QSpinBox()
self.addMoney3_spinbox.setRange(0, 100000)
self.addMoney3_spinbox.setSingleStep(1000)
self.addMoney3_spinbox.setValue(1000)
self.addMoney3_spinbox.setSuffix("")
self.addMoney3_spinbox.valueChanged.connect(self.setAddMoney)
self.addMoneySetlayout1.addWidget(self.label1)
self.addMoneySetlayout1.addWidget(self.addMoney1_spinbox)
self.addMoneySetlayout2.addWidget(self.label2)
self.addMoneySetlayout2.addWidget(self.addMoney2_spinbox)
self.addMoneySetlayout3.addWidget(self.label3)
self.addMoneySetlayout3.addWidget(self.label4)
self.addMoneySetlayout3.addWidget(self.addMoney3_spinbox)
self.addMoneySetlayout3.setStretch(0, 6)
self.addMoneySetlayout3.setStretch(1, 2)
self.addMoneySetlayout3.setStretch(2, 4)
self.setting_layout.addLayout(self.addMoneySetlayout1)
self.setting_layout.addLayout(self.addMoneySetlayout2)
self.setting_layout.addLayout(self.addMoneySetlayout3)
# 키프리스 프레임
self.kiprisWidget = QtWidgets.QWidget(self)
self.kipris_layout = QtWidgets.QHBoxLayout(self.kiprisWidget)
self.kiprisWidget.setLayout(self.kipris_layout)
self.kiprisWidget.setVisible(False)
self.kipris_label = QtWidgets.QLabel(f"키프리스 검색")
self.kipris_completer = QtWidgets.QCompleter(self.history_model, self)
self.kipris_completer.setCaseSensitivity(Qt.CaseInsensitive)
self.kipris_completer.setCompletionMode(QtWidgets.QCompleter.PopupCompletion)
self.kipris_edit = QtWidgets.QLineEdit()
self.kipris_edit = LineEditWithHistory(self.kipris_completer, self)
self.kipris_edit.setCompleter(self.kipris_completer)
self.kipris_btn = QtWidgets.QPushButton("검색")
self.kipris_btn.clicked.connect(self.kipris_btn_clicked)
self.kipris_edit.returnPressed.connect(self.kipris_btn_clicked)
self.spinner = IndeterminateProgressRing(self)
self.spinner.setFixedSize(50, 50)
self.spinner.setVisible(False)
self.kipris_layout.addWidget(self.spinner)
# self.kipris_edit.mousePressEvent = self.show_history_menu
self.kipris_layout.addWidget(self.kipris_label)
self.kipris_layout.addWidget(self.kipris_edit)
self.kipris_layout.addWidget(self.kipris_btn)
self.kipris_layout.setStretch(0,3)
self.kipris_layout.setStretch(1,6)
self.kipris_layout.setStretch(2,3)
# self.setting_layout.addLayout(self.kipris_layout)
self.setting_layout.addWidget(self.kiprisWidget) # self.kiprisWidget을 설정 레이아웃에 추가
# 추가정보 프레임
self.addInfoWidget = QtWidgets.QWidget(self)
self.addInfo_vlayout = QtWidgets.QVBoxLayout(self.addInfoWidget)
self.addInfo_h1layout = QtWidgets.QHBoxLayout()
self.addInfo_h2layout = QtWidgets.QHBoxLayout()
self.addInfo_vlayout.addLayout(self.addInfo_h2layout)
self.addInfo_vlayout.addLayout(self.addInfo_h1layout)
self.addInfoWidget.setLayout(self.addInfo_vlayout)
self.addInfoWidget.setVisible(True)
self.setUSD_label = QtWidgets.QLabel(f"[{self.setUSD}]USD/KRW")
setUSD_label_font = QFont()
setUSD_label_font.setBold(True) # 굵게
setUSD_label_font.setUnderline(True) # 밑줄
setUSD_label_font.setWeight(12) # 폰트크기
self.setUSD_label.setAlignment(QtCore.Qt.AlignCenter) # 가운데 정렬
self.setUSD_label.setFont(setUSD_label_font) # 폰트 적용
self.addInfo_h1layout.addWidget(self.setUSD_label)
self.setCNY_label = QtWidgets.QLabel(f"[{self.setCNY}]CNY/KRW")
setCNY_label_font = QFont()
setCNY_label_font.setBold(True) # 굵게
setCNY_label_font.setUnderline(True) # 밑줄
setCNY_label_font.setWeight(12) # 폰트크기
self.setCNY_label.setAlignment(QtCore.Qt.AlignCenter) # 가운데 정렬
self.setCNY_label.setFont(setCNY_label_font) # 폰트 적용
self.addInfo_h1layout.addWidget(self.setCNY_label)
self.addInfo1_btn = QtWidgets.QPushButton("금지어")
self.addInfo1_btn.clicked.connect(self.addInfo1_btn_clicked)
self.addInfo_h2layout.addWidget(self.addInfo1_btn)
self.addInfo2_btn = QtWidgets.QPushButton("도량형")
self.addInfo2_btn.clicked.connect(self.addInfo2_btn_clicked)
self.addInfo_h2layout.addWidget(self.addInfo2_btn)
self.addInfo3_btn = QtWidgets.QPushButton("타냐어록")
self.addInfo3_btn.setEnabled(False)
self.addInfo3_btn.clicked.connect(self.addInfo3_btn_clicked)
self.addInfo_h2layout.addWidget(self.addInfo3_btn)
self.addInfo4_btn = QtWidgets.QPushButton("딥러닝번역")
self.addInfo4_btn.setEnabled(True)
self.addInfo4_btn.clicked.connect(self.addInfo4_btn_clicked)
self.addInfo_h2layout.addWidget(self.addInfo4_btn)
# 다크 테마 토글 버튼 추가
self.theme_button = QtWidgets.QPushButton("Dark Theme", self)
self.theme_button.setEnabled(False)
self.theme_button.clicked.connect(self.toggle_theme)
self.addInfo_h2layout.addWidget(self.theme_button, 0, Qt.AlignHCenter)
# self.addInfo_layout.setStretch(0,3)
# self.addInfo_layout.setStretch(1,6)
# self.addInfo_layout.setStretch(2,3)
# self.setting_layout.addLayout(self.addInfo_layout)
self.setting_layout.addWidget(self.addInfoWidget) # self.addInfoWidget 설정 레이아웃에 추가
# 경동택배 무게기준 조정 스핀박스
self.changeCurreny_btn = QtWidgets.QPushButton("CNY/KRW")
self.changeCurreny_btn.clicked.connect(self.changeCurreny_btn_clicked)
self.calcCurrency_label = QtWidgets.QLabel("")
self.calcCurrency_label.setText("")
self.calcCurrency_label.setAlignment(QtCore.Qt.AlignCenter)
calcCurrency_label_font = QFont()
calcCurrency_label_font.setBold(True) # 굵게
calcCurrency_label_font.setUnderline(True) # 밑줄
calcCurrency_label_font.setWeight(16) # 폰트크기
self.calcCurrency_label.setFont(calcCurrency_label_font)
self.currency_calc_box = QtWidgets.QSpinBox()
self.currency_calc_box.setRange(0, 1000000)
self.currency_calc_box.setSingleStep(10)
self.currency_calc_box.setValue(100)
self.currency_calc_box.setSuffix(" CNY")
self.currency_calc_box.setAlignment(QtCore.Qt.AlignRight) # 가운데 정렬
self.currency_calc_box.valueChanged.connect(self.calcCurrency)
self.currency_calc_box_layout = self.create_label_and_spin("환율", self.currency_calc_box)
self.currency_calc_box_layout.addWidget(self.calcCurrency_label)
self.currency_calc_box_layout.addWidget(self.changeCurreny_btn)
self.currency_calc_box_layout.setStretch(0,2)
self.currency_calc_box_layout.setStretch(1,4)
self.currency_calc_box_layout.setStretch(2,4)
self.currency_calc_box_layout.setStretch(3,2)
self.setting_layout.addLayout(self.currency_calc_box_layout)
# 항상 위에 토글 스위치
self.alwaysOnTopSwitch = ToggleSwitch(self.setting_frame)
self.alwaysOnTopSwitch.move(10, 10)
self.alwaysOnTopSwitch.setChecked(True) # 기본 상태는 ON
self.alwaysOnTopSwitch.clicked.connect(self.toggleAlwaysOnTop)
self.alwaysOnTopSwitch_layout = self.create_label_and_switch("항상 위에 표시", self.alwaysOnTopSwitch)
self.setting_layout.addLayout(self.alwaysOnTopSwitch_layout)
# 설정값 저장 토글 스위치
self.saveSettingSwitch = ToggleSwitch(self.setting_frame)
self.saveSettingSwitch.move(10, 10)
self.saveSettingSwitch.setChecked(False) # 기본 상태는 OFF
self.saveSettingSwitch.clicked.connect(self.isSaveSetting)
self.saveSettingSwitch_layout = self.create_label_and_switch("설정값 저장", self.saveSettingSwitch)
self.setting_layout.addLayout(self.saveSettingSwitch_layout)
# 낙인
self.infoLabel4 = QtWidgets.QLabel(" 배송비계산기 by 내차는언제타냐")
self.setting_layout.addWidget(self.infoLabel4)
# 레이아웃 비율 조정
self.layout.addWidget(self.user_frame, 3)
self.layout.addWidget(self.user_info_frame, 3)
self.layout.addWidget(self.setting_frame, 4)
self.setWindowTitle('배송비 계산기')
def toggle_theme(self):
if self.is_dark_theme:
try:
# setTheme(Theme.LIGHT)
toggleTheme()
print("라이트 토글")
self.is_dark_theme = False
except Exception as e:
print(f"라이트 토글 중 에러 : {e}")
else:
try:
# setTheme(Theme.DARK)
toggleTheme()
print("다크 토글")
self.is_dark_theme = True
except Exception as e:
print(f"다크 토글 중 에러 : {e}")
def initSettings_for_kipris(self):
if self.kiprisAPI:
# 현재 객체가 적절한 타입인지 확인
current_type = type(self.kiprisAPI)
target_type = Kipris_API if self.usage_mode == 'api' else AsyncWebSearchWorker
if current_type is not target_type:
# 기존 객체가 다른 타입이면 삭제하고 새로 생성
logger.debug(f"기존 {self.kiprisAPI} 객체를 삭제하고 새 객체를 생성합니다.")
if isinstance(self.kiprisAPI, AsyncWebSearchWorker):
self.kiprisAPI.deleteLater() # 비동기 작업자는 Qt 객체로 관리되므로 deleteLater 사용
self.kiprisAPI = None
if self.usage_mode == 'api':
self.kiprisAPI = Kipris_API(self.api_key) # 새 객체 생성
else:
web_scraper = WebScraper() # WebScraper 인스턴스 생성
self.web_scraper = web_scraper
self.kiprisAPI = AsyncWebSearchWorker(self.web_scraper, "") # 초기 키워드는 비워두기
logger.debug(f"{self.usage_mode.upper()} 방식 kiprisAPI 객체 생성: {self.kiprisAPI}")
else:
logger.debug(f"기존에 적절한 {self.kiprisAPI} 객체가 이미 존재합니다.")
else:
# 객체가 없으면 새로 생성
if self.usage_mode == 'api':
self.kiprisAPI = Kipris_API(self.api_key)
else:
web_scraper = WebScraper() # WebScraper 인스턴스 생성
self.web_scraper = web_scraper
self.kiprisAPI = AsyncWebSearchWorker(web_scraper, "") # 초기 키워드는 비워두기
logger.debug(f"{self.usage_mode.upper()} 방식 kiprisAPI 객체 생성: {self.kiprisAPI}")
def addInfo1_btn_clicked(self):
pass
def addInfo2_btn_clicked(self):
pass
def addInfo3_btn_clicked(self):
pass
def addInfo4_btn_clicked(self):
# optionTrans 클래스를 사용해 다이얼로그 창을 띄움
self.trans_dialog = optionTrans(self)
self.trans_dialog.show()
self.add_dialog(self.trans_dialog) # 열린 다이얼로그를 리스트에 추가
def showSettingsDialog(self):
if self.settingDialog.exec_():
self.use_kipris = self.settingDialog.use_kipris
self.usage_mode = self.settingDialog.usage_mode
self.api_key = self.settingDialog.api_key
self.set_status = self.settingDialog.set_status
self.add_dialog(self.settingDialog) # 열린 다이얼로그를 리스트에 추가
self.kipris_Visible()
def kipris_Visible(self):
if self.use_kipris:
self.kiprisWidget.setVisible(True)
self.initSettings_for_kipris()
self.kipris_label.setText(f"키프리스 검색({self.usage_mode})")
else:
self.kiprisWidget.setVisible(False)
def create_label_and_switch(self, label_text, target_switch):
layout = QtWidgets.QHBoxLayout()
label = QtWidgets.QLabel(label_text)
# label.setAlignment(QtCore.Qt.AlignCenter)
layout.addWidget(label)
layout.addWidget(target_switch)
return layout
def create_label_and_spin(self, label_text, spin):
layout = QtWidgets.QHBoxLayout()
label = QtWidgets.QLabel(label_text)
# label.setAlignment(QtCore.Qt.AlignCenter)
layout.addWidget(label)
layout.addWidget(spin)
return layout
def create_label_and_spin_in_QV(self, label_text, spin):
layout = QtWidgets.QVBoxLayout()
label = QtWidgets.QLabel(label_text)
label.setAlignment(QtCore.Qt.AlignCenter)
layout.addWidget(label)
layout.addWidget(spin)
return layout
def center(self):
qr = self.frameGeometry()
cp = QtWidgets.QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def loadDeliveryFees(self):
try:
excel_file = pd.ExcelFile('delv.xlsx')
sheets = excel_file.sheet_names
for sheet in sheets:
df = excel_file.parse(sheet)
# 시트 내 컬럼 확인 및 데이터 처리
if '무게' in df.columns and '배송비' in df.columns:
self.processSheet(df, sheet, '무게')
if '부피' in df.columns and '배송비' in df.columns:
self.processSheet(df, sheet, '부피')
if sheet.endswith('(배송비)'):
self.comboBox.addItem(sheet)
logger.debug('Excel file loaded successfully.')
except Exception as e:
logger.error(f"Error loading Excel file: {e}", exc_info=True)
QtWidgets.QMessageBox.critical(self, "Error", "Failed to load the Excel file.")
def processSheet(self, df, sheet_name, key):
records = []
for index, row in df.iterrows():
try:
value_str = re.findall(r'\d+[\d,]*', str(row[key]))[0].replace(',', '')
fee_str = re.findall(r'\d+[\d,]*', str(row['배송비']))[0].replace(',', '')
value = float(value_str)
fee = int(fee_str)
records.append({key: value, '배송비': fee})
except ValueError as e:
logger.error(f"Error converting values in row {index} of sheet {sheet_name}: {e}")
continue
self.deliveryFees[sheet_name] = records
def setDefaultValues(self):
self.weightInput.setValue(1)
self.widthInput.setValue(1)
self.lengthInput.setValue(1)
self.heightInput.setValue(1)
self.updateDeliveryFee()
def updateDeliveryFee(self):
try:
weight = self.weightInput.value()
# logger.debug(f"현재 선택된 무게 : {weight}")
selected_sheet = self.comboBox.currentText()
# logger.debug(f"현재 선택된 시트 : {selected_sheet}")
fees = self.deliveryFees.get(selected_sheet, [])
fee = 0
# 가능한 모든 무게를 리스트로 가져오고 정렬
sorted_fees = sorted((float(f['무게']), int(f['배송비'])) for f in fees if '무게' in f and '배송비' in f)
# 입력된 무게보다 작거나 같은 최대 무게 찾기
closest_fee = None
for w, f in sorted_fees:
if weight >= w:
closest_fee = f
else:
break
# 배송비 업데이트
if closest_fee is not None:
fee = closest_fee
# 추가 배송비 계산
if weight > self.addFeeSetting:
# 추가될 배송비 횟수 계산
additional_fee_count = (weight - self.addFeeSetting) // self.addFeeInterval
if (weight - self.addFeeSetting) % self.addFeeInterval != 0:
additional_fee_count += 1
total_add_fee = additional_fee_count * self.addFee
fee += total_add_fee
self.deliveryFeeLabel.setText(f'배송비: {int(fee): ,}원 (추가 배송비 {int(total_add_fee)} 포함)')
else:
self.deliveryFeeLabel.setText(f'배송비: {int(fee): ,}')
# logger.debug(f"배송비 deliveryFeeLabel에 업데이트: {int(fee): ,}원")
# 폰트와 밑줄 설정
font = QFont()
font.setBold(True) # 굵게
font.setUnderline(True) # 밑줄
self.deliveryFeeLabel.setFont(font)
self.currentWeight = weight
self.additionalFee()
except Exception as e:
logger.error(f"Error updating delivery fee: {e}", exc_info=True)
self.deliveryFeeLabel.setText("배송비 업데이트 중 오류 발생")
def updateAdditionalDeliveryFee(self):
try:
weight = self.weightInput.value()
volume = self.currentVolume # 현재 부피
logger.debug(f"현재 선택된 무게 : {weight}")
selected_v_sheet = '경동부피'
selected_w_sheet = '경동무게'
v_fees = self.deliveryFees.get(selected_v_sheet, [])
w_fees = self.deliveryFees.get(selected_w_sheet, [])
# 가능한 모든 무게를 리스트로 가져오고 정렬
sorted_v_fees = sorted((float(f['부피']), int(f['배송비'])) for f in v_fees if '부피' in f and '배송비' in f)
sorted_w_fees = sorted((float(f['무게']), int(f['배송비'])) for f in w_fees if '무게' in f and '배송비' in f)
# logger.debug(f"경동부피무게 가격 : {sorted_v_fees}")
# logger.debug(f"경동무게당 가격 : {sorted_w_fees}")
# 입력된 무게보다 작거나 같은 최대 무게 찾기
closest_v_fee = None
closest_w_fee = None
price_source = ""
# 무게에 따른 최적 배송비 계산
for w_w, w_f in sorted_w_fees:
if weight >= w_w:
closest_w_fee = w_f
else:
break
# 부피에 따른 최적 배송비 계산
for v_w, v_f in sorted_v_fees:
if volume >= v_w:
closest_v_fee = v_f
else:
break
# 최종 가격 결정 및 가격 출처 확인
if closest_v_fee is not None and closest_w_fee is not None:
if closest_v_fee >= closest_w_fee:
closest_final_fee = closest_v_fee
price_source = "부피"
else:
closest_final_fee = closest_w_fee
price_source = "무게"
elif closest_v_fee is not None:
closest_final_fee = closest_v_fee
price_source = "부피"
elif closest_w_fee is not None:
closest_final_fee = closest_w_fee
price_source = "무게"
else:
closest_final_fee = 0
price_source = "데이터 없음"
# 폰트와 밑줄 설정
font = QFont()
font.setBold(True) # 굵게
font.setUnderline(True) # 밑줄
self.additionalFeeLabel.setFont(font)
# 배송비 업데이트 및 라벨 표시
fee = f"{closest_final_fee: ,}"
self.additionalFeeLabel.setText(f'경동 택배비[{price_source}]: {fee}')
except Exception as e:
logger.error(f"Error updating Additional delivery fee: {e}", exc_info=True)
self.additionalFeeLabel.setText("배송비 업데이트 중 오류 발생")
def updateComboBox(self):
selected_Delv = self.comboBox.currentText()
logger.debug(f"선택된 배대지: {selected_Delv}")
self.favoriteDelv = selected_Delv
self.updateDeliveryFee()
def setComboBox(self):
logger.debug(f"self.favoriteDelv: {self.favoriteDelv}")
if self.favoriteDelv:
index = self.comboBox.findText(self.favoriteDelv)
logger.debug(f"저장된 배대지가 존재함: {self.favoriteDelv}")
if index >= 0:
self.comboBox.setCurrentIndex(index)
else:
logger.debug("저장된 배대지가 엑셀시트에 존재하지 않습니다.")
def additionalFee(self):
messages = []
exceeded = False
if self.currentWeight >= self.maxWeightSet:
messages.append(f"무게기준 [{self.maxWeightSet}Kg] 초과")
exceeded = True
if self.currentMaxLength >= self.maxLengthSet:
messages.append(f"길이기준 [{self.maxLengthSet}cm] 초과")
exceeded = True
if self.roundVolume >= self.maxVolumeSet:
logger.debug(f"self.roundVolume : {self.roundVolume}")
logger.debug(f"maxVolumeSet : {self.maxVolumeSet}")
messages.append(f"세변의 합 기준 [{self.maxVolumeSet}cm] 초과")
exceeded = True
if exceeded:
# 모든 메시지를 연결하여 표시
self.additionalFeeTextLabel.setText(", ".join(messages))
self.additionalFeeLabel.setVisible(True)
self.additionalFeeTextLabel.setVisible(True)
self.updateAdditionalDeliveryFee()
else:
self.additionalFeeLabel.setVisible(False)
self.additionalFeeTextLabel.setVisible(False)
def updateVolume(self):
length = self.lengthInput.value()
width = self.widthInput.value()
height = self.heightInput.value()
volume = length * width * height
roundVolume = length + width + height
self.currentVolume = volume
self.roundVolume = roundVolume
self.volumeLabel.setText(f"부피: {volume: ,} cm³")
self.currentMaxLength = max(length,width,height)
if self.currentMaxLength > self.maxLengthSet:
self.maxLengthLabel.setText(f"한 변의 최대길이 : {self.currentMaxLength}cm")
self.maxLengthLabel.setVisible(True)
else:
self.maxLengthLabel.setVisible(False)
self.additionalFee()
def toggleAlwaysOnTop(self, state):
if state:
self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint)
else:
self.setWindowFlags(self.windowFlags() & ~Qt.WindowStaysOnTopHint)
self.show() # 변경된 윈도우 플래그를 적용하기 위해 위젯을 다시 보여줘야 함
def setFontSize(self, value):
font = self.font()
font.setPointSize(value)
self.setFont(font)
self.fontSize = value
self.cargo_font.setPointSize(self.cargo_font_size)
def setStepInterval(self, value):
self.weightInput.setSingleStep(value)
self.weightInterval = value
def setMaxWeight(self, value):
self.maxWeightSet = value
self.updateDeliveryFee()
def setMaxLength(self, value):
self.maxLengthSet = value
self.updateDeliveryFee()
def setMaxVolume(self, value):
self.maxVolumeSet = value
self.updateDeliveryFee()
def setAddMoneySetting(self, value):
self.addFeeSetting = value
if self.addFeeSetting == 0:
self.addFee = 2000
self.updateDeliveryFee()
def setAddMoney(self, value):
self.addFee = value
self.updateDeliveryFee()
def setAddInterval(self, value):
self.addFeeInterval = value
self.updateDeliveryFee()
def changeCurreny_btn_clicked(self):
selected = self.changeCurreny_btn.text()
if selected == 'CNY/KRW':
self.currency_calc_box.setSuffix(" USD")
self.changeCurreny_btn.setText('USD/KRW')
self.currentCurrency = self.setUSD
else:
self.currency_calc_box.setSuffix(" CNY")
self.changeCurreny_btn.setText('CNY/KRW')
self.currentCurrency = self.setCNY
self.calcCurrency(100)
def calcCurrency(self,value):
result = value * self.currentCurrency
result = round(result,0)
result = '{0:,}'.format(result)
# logger.debug(f"result{result}")
# logger.debug(f"round(result,2){str(round(result,0))}")
self.calcCurrency_label.setText(result+'')
def isSaveSetting(self, state):
if state:
self.setSaveSetting = True
else:
self.setSaveSetting = False
logger.debug(f"설정값 저장세팅 : {self.setSaveSetting}")
self.show()
def kipris_btn_clicked(self):
self.search_keyword = self.kipris_edit.text()
logger.debug(f"키프리스 검색버튼 클릭 : 키워드 = [{self.search_keyword}]")
# result = self.kiprisAPI.run(self.search_keyword, self.set_status)
# logger.debug(f"result {result}")
if self.search_keyword.strip(): # 검색어가 비어있지 않은 경우에만 검색 수행
self.spinner.setVisible(True) # Show spinner
logger.debug(f"검색 호출방식 : {self.usage_mode}")
if self.usage_mode == 'web':
self.handle_search_for_web(self.search_keyword)
if self.usage_mode == 'api':
self.handle_search_for_api(self.search_keyword)
def handle_search_for_web(self, keyword):
self.add_history(keyword) # 검색어 히스토리 추가
if self.asyncWorker: # 기존에 비동기 작업자가 존재한다면
self.asyncWorker.thread.quit() # 기존 스레드 종료
logger.debug(f"키프리스 검색버튼 클릭 : 키워드 = [{keyword}]")
self.asyncWorker = AsyncWebSearchWorker(keyword, self.set_status) # 새 비동기 작업자 생성
self.asyncWorker.finished.connect(self.display_results_for_web) # 완료 시그널을 결과 표시 함수에 연결
self.asyncWorker.start() # 비동기 작업 시작
logger.debug("비동기 검색 시작")
def display_results_for_web(self, result, elapsed_time):
# logger.debug(f"result : {result}")
searchType = 'web'
logger.debug(f"display_results_for_web - currentURL : {self.web_scraper.currentURL}")
self.spinner.setVisible(False) # Hide spinner
self.searchDisplayWidget.clear_results()
self.add_dialog(self.searchDisplayWidget) # 열린 다이얼로그를 리스트에 추가
self.searchDisplayWidget.show_results(result, searchType, elapsed_time, self.web_scraper.currentURL)
# self.searchDisplay.display_web_results(result, elapsed_time)
# self.searchDisplay.show()
message = f"검색 결과 : {result}\n검색에 걸린 시간: {elapsed_time:.1f}"
# QtWidgets.QMessageBox.information(self, "Search Results", message)
self.asyncWorker = None # 작업 완료 후 객체 참조 해제
def handle_search_for_api(self, keyword):
self.add_history(keyword)
if self.searchThread is not None and self.searchThread.isRunning():
self.searchThread.quit() # 이전 스레드가 실행 중이라면 안전하게 종료
logger.debug("기존 쓰레드가 존재하므로 기존 쓰레드 종료")
logger.debug(f"키프리스 검색버튼 클릭 : 키워드 = [{keyword}]")
worker = APISearchWorker(self.kiprisAPI, keyword, self.set_status)
# worker = SearchWorker(self.kiprisAPI, keyword, self.set_status)
logger.debug("워커 생성")
self.searchThread = SearchThread(worker)
logger.debug("쓰레드 생성")
worker.finished.connect(self.display_results_for_api)
self.searchThread.finished.connect(self.clear_thread_reference)
self.searchThread.start_search()
logger.debug("검색 시작")
def clear_thread_reference(self):
# 스레드 종료 후 참조를 제거하여 다음 검색을 위해 준비
self.searchThread = None
def display_results_for_api(self, result, elapsed_time):
searchType = 'api'
logger.debug(f"display_results_for_api result: {result}")
self.spinner.setVisible(False) # Hide spinner
self.searchDisplayWidget.clear_results()
self.add_dialog(self.searchDisplayWidget) # 열린 다이얼로그를 리스트에 추가
self.searchDisplayWidget.show_results(result, searchType, elapsed_time)
message = f"검색 결과 : {result}\n검색에 걸린 시간: {elapsed_time:.1f}"
# QtWidgets.QMessageBox.information(self, "Search Results", message)
def reset_action(self):
self.lengthInput.setValue(1)
self.widthInput.setValue(1)
self.heightInput.setValue(1)
self.weightInput.setValue(1)
def showHelp(self):
# 도움말 내용 표시
helpText = "안녕하세요 내차는 언제타냐 입니다. \n - 모든 입력칸에는 마우스 휠로 입력가능하고, \n - 컨트롤+휠 동작시 (기본값x10) 값으로 변경가능합니다.\n - 배대지를 추가하려면 첨부된 엑셀파일 delv.xlsx를 참조하세요 \n - 배대지 순서를 정하려면 시트이름에 번호를 붙이세요."
QtWidgets.QMessageBox.information(self, '도움말', helpText)
def showChangeLog(self):
# ChangeLog 내용 표시
QtWidgets.QMessageBox.information(self, 'ChangeLog', "Version 1.0 \n Inintial Launch\n\nVersion 1.0.1 \n Dimension에 Reset버튼 추가")
def setttingTosetDefaultValues(self):
# 기본값 설정 로직
QtWidgets.QMessageBox.information(self, '기본값 설정', "기본값으로 설정합니다.")
self.font_size_spinbox.setValue(14)
# self.setFontSize
self.addMoney1_spinbox.setValue(20)
self.addMoney2_spinbox.setValue(5)
self.addMoney3_spinbox.setValue(5000)
self.saveSettingSwitch.setChecked(False)
self.step_interval_spinbox.setValue(0.5)
self.maxVolume_spinbox.setValue(160)
self.maxWeight_spinbox.setValue(25)
self.maxLength_spinbox.setValue(100)
self.favoriteDelv = None
self.setComboBox()
if __name__ == '__main__':
# minimize_console()
# enable dpi scale
QtWidgets.QApplication.setHighDpiScaleFactorRoundingPolicy(
Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
QtWidgets.QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
QtWidgets.QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
app = QtWidgets.QApplication(sys.argv)
# qasync 이벤트 루프를 생성하여 PyQt5의 이벤트 루프와 결합
loop = QEventLoop(app)
asyncio.set_event_loop(loop) # asyncio의 이벤트 루프를 qasync로 설정
app.setStyle('Fusion')
logger = setup_logger('default_logger', 'delivery_calc.log', level=logging.DEBUG)
ex = DeliveryFeeCalculator(logger)
ex.show()
# 이벤트 루프 시작
with loop:
loop.run_forever()
sys.exit(app.exec_())