소연의_개발일지
article thumbnail

목차

개발환경

개발완료보고서

요구사항 세부내역

일정표

파일 첨부

실행화면

코드 전문

 


개발환경

  • 운영체제: Window 10 64 bit
  • 개발언어: Python 3.11
  • 개발 툴: Pycharm
  • DBSM: SQLite
  • 추가 패키지: PyQt, Pandas

 

개발완료보고서

요구사항분석서

일정표

 

파일 첨부

https://github.com/guaba98/seoul_trip_program

 

GitHub - guaba98/seoul_trip_program

Contribute to guaba98/seoul_trip_program development by creating an account on GitHub.

github.com

 

목업 이미지

실행사진

정보 입력 / 정보가 유효하지 않을 때 경고표시

db에 담기는 부분

메인 화면

음식 구별 리스트 선택창 / 각 구별 음식점 리스트 / 음식점 선택했을 때 상세정보와 지도 보여주기

 

 

 

선택한 구별 숙박시설 리스트 / 선택한 숙박시설 지도 위치

 

서울 관광명소 리스트 / 선택한 관광명소 지도 위치

 

 

서울관련 데이터 자료 확인 / 누르면 그래프에 대한 상세 정보 확인 가능

 

 

지도 선택하면 나오는 화면 / 명소는 사진으로 보여줍니다.

구 검색시 자동완성 기능

 

실행영상

 

 

코드 전문

main.py

더보기
import io
import random
import sqlite3
import folium
import sys
import pandas as pd

from selenium import webdriver
from selenium.webdriver.common.by import By
from seoul_main_page import *
from widget_for_food import *
from widget_for_sleep import *
from widget_for_tour import *
from widget_for_graph import *
from graph_data import *
from map_file import *

gu_list = ['종로구', '중구', '용산구', '성동구', '광진구', '동대문구', '중랑구', '성북구', '강북구', '도봉구',
           '노원구', '은평구', '서대문구', '마포구', '양천구', '강서구', '구로구', '금천구', '영등포구', '동작구',
           '관악구', '서초구', '강남구', '송파구', '강동구']


class WindowClass(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.map_obj = FoliumMap()  # 맵 객체 생성
        self.setupUi(self)  # ui 관련
        self.var_init()  # 변수 설정부분
        self.Ui_init()  # ui 설정부분
        self.insert_values_in_gridlayout()  # 그리드 레이아웃에 구 넣기
        self.function_init()  # 기능들 (시그널 연결 부분)

    def show_map_as_search(self, user_idx):
        """검색한 값에 따라 자료들이 출력됨"""
        self.user_index = user_idx

        # 레이아웃에 있는 객체를 지움
        if self.whole_map.count():
            self.whole_map.takeAt(0)

        # 유저가 검색한 내용을 가져옴
        user_text = self.map_lineEdit.text()
        print("유저가 선택한 동은", user_text)

        # 사용자가 검색을 하지 않은 경우
        if user_text == "":
            if user_idx == 0:
                self.map_obj.mapping_food_all_show()  # 서울의 모든 음식점을 보여줌
            elif user_idx == 1:
                self.map_obj.mapping_lodges_all_show()  # 서울의 모든 숙박업소를 보여줌
            else:
                self.map_obj.mapping_tour_all_show()  # 서울의 모든 명소를 보여줌

        # 사용자가 구 검색을 한 경우
        else:
            if user_idx == 0:
                self.map_obj.mapping_food_guname_show(user_text)  # 구 이름에 따라 음식점을 보여줌
            elif user_idx == 1:
                self.map_obj.mapping_lodges_guname_show(user_text)  # 구 이름에 따라 숙박업소들을 보여줌
            else:
                self.map_obj.mapping_tour_guname_show(user_text)  # 구 이름에 따라 명소들을 보여줌

        # 레이아웃에 맵 객체를 리턴받아서 로드해 줌
        self.whole_map.addWidget(self.map_obj.load_map())
        del self.map_obj  # map 클래스 객체를 지우고
        self.map_obj = FoliumMap()  # 다시 생성
        print("객체 지움")  # 확인용

    def what_do_you_want_to_know(self, choice):
        """선택한 부분에 따라 페이지를 넘기고, 로드해 줌"""
        self.stackedWidget.setCurrentWidget(self.main_page_2)
        self.gu_btn_clicked(choice)  # 음식, 숙박업소

    # 구 버튼 클릭이벤트
    def gu_btn_clicked(self, choice):
        """유저가 선택한 버튼에 따라 라벨의 내용을 변경해 줌"""
        if choice == 'food':
            self.frame_20.setStyleSheet('background-color:#FFEFB5;border-radius:20px;')
            text = '가고싶은 서울의 장소를 선택하세요!\n인기있는 음식점들만 소개해 드립니다.'
            self.main_2_title_lab.setText(text)
            for idx, btn in enumerate(self.gu_btn_list):
                btn.clicked.connect(lambda event, idx=idx: self.gu_btn_for_food(self.gu_btn_list[idx]))
        elif choice == 'sleep':
            self.frame_20.setStyleSheet('background-color:#B0DAFF;border-radius:20px;')
            text = '가고싶은 서울의 장소를 선택하세요!\n최고의 숙박시설을 소개해 드립니다.'
            self.main_2_title_lab.setText(text)
            for idx, btn in enumerate(self.gu_btn_list):
                btn.clicked.connect(lambda event, idx=idx: self.gu_btn_for_sleep(self.gu_btn_list[idx]))

    def gu_btn_for_food(self, btn):
        """구 버튼을 클릭하면 스크롤 영역에 음식점 리스트를 넣어줌"""
        region = btn.text()
        food_text = f"{region}의 유명한 음식점을 안내해드려요!"
        self.main_3_title_lab.setText(food_text)
        self.main_4_title_lab.setText(food_text)
        datas = self.cur.execute(f'select * from food_list where gu_name = "{region}";')
        self.stackedWidget.setCurrentWidget(self.main_page_3)
        self.clear_scroll_area()
        self.set_data_of_food_in_scrollarea(datas)
        self.scrollArea.ensureVisible(0, 0)

    def gu_btn_for_sleep(self, btn):
        """구 버튼을 클릭하면 스크롤 영역에 숙박업소 리스트를 넣어줌"""
        region = btn.text()
        sleep_text = f'{region}의 최고의 숙박시설을 안내해드려요!'
        self.main_3_title_lab.setText(sleep_text)
        self.main_4_title_lab.setText(sleep_text)
        datas = self.cur.execute(
            f'select 사업장명, 영업상태명, 도로명주소, x_pos, y_pos, img_path from seoul_lodges where 지번주소 like "%{region}%";')
        self.stackedWidget.setCurrentWidget(self.main_page_3)
        self.clear_scroll_area()
        self.set_data_of_sleep_in_scrollarea(datas)
        self.scrollArea.ensureVisible(0, 0)

    def tour_btn_click(self):
        """스크롤 영역에 명소리스트를 넣어줌"""
        self.frame_20.setStyleSheet('background-color:#caffbf; border-radius:20px;')
        self.back_3_btn_clicked = True
        tour_text = '서울시의 유명한 명소를 소개해드려요!'
        self.main_3_title_lab.setText(tour_text)
        self.main_4_title_lab.setText(tour_text)
        self.stackedWidget.setCurrentWidget(self.main_page_3)
        self.clear_scroll_area()
        self.set_data_of_tour_in_scrollarea()
        self.scrollArea.ensureVisible(0, 0)
     # 스크롤 위젯에 데이터 심기
    def set_data_of_food_in_scrollarea(self, datas):
        """스크롤 영역에 음식점 데이터 심기"""
        layout = self.scrollAreaWidgetContents.layout()
        for data in datas:
            name = data[2]
            rate = data[3]
            address = data[4]
            x_pos = data[5]
            y_pos = data[6]
            main_dishes = data[-3]
            price = data[-2]
            img_path = data[-1]
            layout.addWidget(SeoulForFood(name, rate, address, main_dishes, price, x_pos, y_pos, img_path, self))

    def set_data_of_sleep_in_scrollarea(self, datas):
        """스크롤 영역에 숙박업소 리스트 심기"""
        layout = self.scrollAreaWidgetContents.layout()
        for data in datas:
            name = data[0]
            status = data[1]
            address = data[2]
            x_pos = data[3]
            y_pos = data[4]
            image_path = data[-1]
            layout.addWidget(SeoulForSleep(name, status, address, x_pos, y_pos, image_path, self))

    def set_data_of_tour_in_scrollarea(self):
        """스크롤 영역에 명소 리스트 심기"""
        layout = self.scrollAreaWidgetContents.layout()
        datas = self.cur.execute('select 상호명, 신주소, 운영요일, 운영시간, 휴무일, x_pos, y_pos, img_path from seoul_tourist;')
        for data in datas:
            name = data[0]
            address = data[1]
            working_day = data[2]
            working_time = data[3]
            holiday = data[4]
            x_pos = data[-3]
            y_pos = data[-2]
            image_path = data[-1]
            layout.addWidget(
                SeoulForTour(name, address, working_day, working_time, holiday, x_pos, y_pos, image_path, self))

    def clear_scroll_area(self):
        """스크롤 영역 위젯 비워주기"""
        while self.scrollAreaWidgetContents.layout().count():
            item = self.scrollAreaWidgetContents.layout().takeAt(0)
            widget = item.widget()
            self.scrollAreaWidgetContents.layout().removeWidget(widget)

    def insert_values_in_gridlayout(self):
        """그리드 영역에 버튼 생성해서 넣어주기"""
        self.gu_btn_list = list()
        cnt = 0
        for i in range(1, 6):
            for j in range(1, 6):
                button = QPushButton(gu_list[cnt])  # 버튼 생성 및 이름 넣어줌
                button.setFixedSize(100, 100)  # 버튼의 크기 고정
                button.setStyleSheet('''
                border-radius:15px;
                border: 3px solid white;
                ''')
                self.gridLayout.addWidget(button, i, j)
                self.gu_btn_list.append(button)
                cnt += 1

    # 날씨관련
    def wheather_crawling(self):
        """날씨를 크롤링해와서 메인 화면에 지정함"""
        options = webdriver.ChromeOptions()
        options.add_argument("headless")
        self.driver = webdriver.Chrome(options=options)
        self.driver.get("https://weather.naver.com/today/09140104?cpName=KMA")

        temperature = self.driver.find_element(By.CSS_SELECTOR,
                                               '#now > div > div.weather_area > div.weather_now > div > strong')
        wheather = self.driver.find_element(By.CSS_SELECTOR,
                                            '#now > div > div.weather_area > div.weather_now > p > span.weather')
        self.temp_label.setText(f"{temperature.text[-5:]} ")
        self.temp_label_2.setText(f'{wheather.text}')
        self.set_wheather_icon(wheather.text)
        self.driver.close()

    # 날씨 셋업
    def set_wheather_icon(self, wheather):
        """날씨 아이콘을 설정함"""
        wheather_icon_path = {
            '맑음': '../img/wheather_icon/shiny',
            '구름많음': '../img/wheather_icon/cloud',
            '흐림': '../img/wheather_icon/overcast',
            '비': '../img/wheather_icon/rainy'
        }
        idx = wheather_icon_path.get(wheather)
        self.wheather_icon.setPixmap(QPixmap(idx))

    def activate_DB(self):
        """db 활성화함"""
        self.conn = sqlite3.connect('../database/seoul_db.db')
        self.cur = self.conn.cursor()

    def back_3_btn_click_event(self):
        """버튼을 클릭했을 때 조건에 따라 페이지로 이동함"""
        if not self.back_3_btn_clicked:
            self.stackedWidget.setCurrentWidget(self.main_page_2)
        else:
            self.back_3_btn_clicked = False
            self.stackedWidget.setCurrentWidget(self.main_page_1)
            
      def input_personal_information(self):
        """개인정보 넣는 부분"""
        self.check_name() # 이름 확인
        if self.check_name() and self.check_len_phone_number(self.lineEdit_2.text()): #이름, 폰 길이가 True반영시
            self.stackedWidget.setCurrentWidget(self.main_page_1) #페이지 이동
            self.main_sub_title.setText(f"{self.lineEdit.text()}님, \n서울 여행을 준비하세요.")
            self.user_id += 1
            personal_info = (self.user_id, self.lineEdit.text(), self.lineEdit_2.text(), self.dateEdit.text())
            self.cur.execute("insert into user_info values (?, ?, ?, ?);", personal_info) #데이터 넣어주기
            self.conn.commit()
        else:
            pass  # 창이 넘어가지 않음

    def check_name(self):
        """이름 확인하는 부분"""
        name = self.lineEdit.text()
        if len(name) == 0:
            self.user_name_label.setText('이름을 입력해주세요.')
            self.user_name_label.setStyleSheet('color:red;')
            return False
        elif len(name) > 6:
            self.user_name_label.setText('이름이 너무 깁니다.')
            self.user_name_label.setStyleSheet('color:red;')
            return False
        else:
            self.user_name_label.setText(f'{name}님 안녕하세요.')
            self.user_name_label.setStyleSheet('color:blue;')
            print('트루탐')
            return True

    def check_letter_in_number(self, number):
        """연락처 확인하는 부분"""
        # number = self.lineEdit_2.text()
        # check_number = self.check_len_phone_number(number)
        for num in number:
            num = ord(num)
            if 47 < num < 58:
                return True
                pass
            else:
                self.user_number_label('숫자만 입력하실 수 잇습니다.')
                self.user_number_label.setStyleSheet('color:red;')
                return False
        return True

    def check_len_phone_number(self, number):
        """핸드폰 번호 길이 체크하는 부분"""
        if len(number) == 11:
            if self.check_letter_in_number(number):
                return True
        else:
            self.user_number_label.setText('형식에 맞게 핸드폰 번호를 입력해주세요.')
            self.user_number_label.setStyleSheet('color:red;')
            return False

    def set_graph_widget(self):
        """그래프 관련 작업 코드"""
        layout = self.map_frame.layout()
        row = 0
        column = 0
        for name, img_path, desc in zip(self.graph_name_list, self.graph_imgpath_list, self.graph_desc_list):
            layout.addWidget(SeoulforGraph(name, img_path, desc, self), row, column)
            column += 1
            if column == 2:
                row += 1
                column = 0

    def load_whole_map(self):
        """지도 이미지 기본 로드"""
        self.stackedWidget.setCurrentWidget(self.main_page_5)
        self.show_map_as_search(2)
        print(self.user_index)

    # 기능 이니트
    def function_init(self):

        # 날씨 크롤링
        self.wheather_crawling()

        # 버튼에 따라 다른 조건으로 이동
        self.food_btn.clicked.connect(lambda: self.what_do_you_want_to_know('food'))
        self.sleep_btn.clicked.connect(lambda: self.what_do_you_want_to_know('sleep'))
        self.tour_btn.clicked.connect(self.tour_btn_click)

        # 라벨 클릭하면 오픈 페이지로 이동
        self.label.mousePressEvent = lambda event: self.stackedWidget.setCurrentWidget(self.login_page)
        # 버튼 클릭하면 특정 페이지로 이동
        self.back_2_btn.clicked.connect(lambda x: self.stackedWidget.setCurrentWidget(self.main_page_1))
        self.back_3_btn.clicked.connect(self.back_3_btn_click_event)
        self.back_4_btn.clicked.connect(lambda x: self.stackedWidget.setCurrentWidget(self.main_page_3))
        self.back_5_btn.clicked.connect(lambda x: self.stackedWidget.setCurrentWidget(self.main_page_1))
        self.back_btn_6.clicked.connect(lambda x: self.stackedWidget.setCurrentWidget(self.main_page_1))
        self.back_btn_7.clicked.connect(lambda x: self.stackedWidget.setCurrentWidget(self.main_page_6))
        # self.all_show_btn.clicked.connect(lambda x: self.stackedWidget.setCurrentWidget(self.main_page_5))
        self.all_show_btn.clicked.connect(self.load_whole_map)  # 전체 지도를 보여줌
        self.map_back_btn.clicked.connect(lambda x, y=self.user_index: self.show_map_as_search(y))
        self.admit_btn.clicked.connect(self.input_personal_information)

        # db 활성화
        self.activate_DB()

        # 자동완성 기능 추가
        completer = QCompleter(gu_list)
        self.map_lineEdit.setCompleter(completer)

        # 지도버튼 시그널 연결
        map_btn_list = [self.map_food_btn, self.map_lodge_btn, self.map_place_btn]
        for idx, btn in enumerate(map_btn_list):
            btn.clicked.connect(lambda x, y=idx: self.show_map_as_search(y))

            # 그래프 페이지 시그널 연결
            self.set_graph_widget()
# 하단 버튼 시그널 연결
        menu_btn_frame = [self.menu_btns_frame_1, self.menu_btns_frame_2, self.menu_btns_frame_3,
                          self.menu_btns_frame_4, self.menu_btns_frame_5]  # 메뉴 버튼 담긴 프레임
        menu_btns = [frame.findChildren(QPushButton) for frame in menu_btn_frame]  # 해당 프레임에 있는 버튼들 가져오기

        # 버튼에 따라 이동해야 할 페이지
        button_mapping = {
            'menu_home_btn': self.main_page_1,
            'menu_map_btn': self.main_page_5,
            'menu_menu_btn': self.main_page_6,
            # 여기에 4번째 버튼 연결할 것 있으면 추가
        }

        # 버튼에 따라 다른 페이지로 이동(위 button_mapping 딕셔너리 참고)
        for btn_list in menu_btns:
            for btn in btn_list:
                for object_name, widget in button_mapping.items():
                    if object_name in btn.objectName():
                        # map_btn일 때 음식 지도 로드하기
                        btn.clicked.connect(lambda checked, widget=widget: self.stackedWidget.setCurrentWidget(widget))
                        break


    # def show_whole_map(self):
    #     """전체 지도를 보여줍니다"""
    #     self.stackedWidget.setCurrentWidget(self.main_page_5)
    #     print(self.whole_map)
    #     self.map_obj.mapping_tour_all_show() # 모든 관광명소를 지도에 마커+클러스터로 표시함
    #     self.verticalLayout_17.addWidget(self.map_obj.load_map())

    # def back_3_btn_click_event(self):
    #     if not self.back_3_btn_clicked:
    #         self.stackedWidget.setCurrentWidget(self.main_page_2)
    #     else:
    #         self.back_3_btn_clicked = False
    #         self.stackedWidget.setCurrentWidget(self.main_page_1)

    def Ui_init(self):
        """스타일시트 관련"""
        # 스크롤에어리어 레이아웃 넣기
        self.setWindowFlags(
            Qt.WindowType.FramelessWindowHint)  # Qt.WindowType.WindowStaysOnTopHint 프레임 지우기 / 윈도우가 다른 창 위에 항상 최상위로 유지되도록 함
        self.setAttribute(Qt.WA_TranslucentBackground, True)  # 배경 투명하게 함

        v_layout = QVBoxLayout(self)
        self.scrollAreaWidgetContents.setLayout(v_layout)

        # 오픈 페이지 랜덤 지정
        self.stackedWidget.setCurrentWidget(self.open_page)
        random_num = random.randint(1, 4)

        # 라벨에 이미지 넣어주기
        self.label.setPixmap(QPixmap(f'../img/qt_img/background_{random_num}.png'))
        self.back_2_btn.setIcon(QIcon('../img/qt_img/back.png'))
        self.back_3_btn.setIcon(QIcon('../img/qt_img/back.png'))
        self.back_4_btn.setIcon(QIcon('../img/qt_img/back.png'))
        self.back_5_btn.setIcon(QIcon('../img/qt_img/back.png'))

        # 커서 지정
        self.setCursor(QCursor(QPixmap('../img/qt_img/mouse.png').scaled(80, 100)))
        # self.label_1.setFont(QFont('Arial', 10))
        # 폰트 지정
        # self.main_sub_title.setFont(QFont('Pretendard', 28))

        # Qmovie 설정
        movie = QMovie('../img/qt_img/seoul.gif')
        self.seoul_gif_label.setMovie(movie)
        movie.start()


        # 웹엔진뷰
        self.webview = QWebEngineView()
        webview_layout = QVBoxLayout(self)
        self.map_widget.setLayout(webview_layout)

        # 그래프 레이아웃 설정
        graph_layout = QGridLayout(self)
        self.map_frame.setLayout(graph_layout)

        # self.map_lineEdit.returnPressed.connect(lambda x, y=0: self.show_map_as_search(y))
        # btn.clicked.connect(lambda x, y=idx: self.show_map_as_search(y))

        # init 안에
        # self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint)

        # 메소드
    # def mousePressEvent(self, event):
        """화면 이동"""
    #     if event.button() == Qt.LeftButton:
    #         self.m_flag = True
    #         self.m_Position = event.globalPos() - self.pos()
    #         event.accept()
    #         self.setCursor(QCursor(Qt.OpenHandCursor))
    #
    # def mouseMoveEvent(self, QMouseEvent):
    #     if Qt.LeftButton and self.m_flag:
    #         self.move(QMouseEvent.globalPos() - self.m_Position)
    #         QMouseEvent.accept()
    #
    # def mouseReleaseEvent(self, QMouseEvent):
    #     self.m_flag = False
    #     self.setCursor(QCursor(Qt.ArrowCursor))

    def var_init(self):
        """관광버튼 눌렀는지 확인하기"""
        self.user_id = 0
        self.user_index = 2
        self.back_3_btn_clicked = False

        # 그래프 이미지 넣어주기
        self.graph_imgpath_list = GraphData().imgpath_list
        self.graph_name_list = GraphData().graph_name_list
        self.graph_desc_list = GraphData().graph_desc_list


if __name__ == '__main__':
    app = QApplication(sys.argv)
    fontDB = QFontDatabase()
    fontDB.addApplicationFont('../font/Pretendard-Medium.ttf') # 폰트 지정
    app.setFont(QFont('Pretendard Medium'))

    myWindow = WindowClass()
    myWindow.show()
    try:
        sys.exit(app.exec_())
    except SystemExit:
        print('Closing Window...')

map_file.py

더보기
# --- import modules
import io
import sqlite3
import sys
import os
import webbrowser
import folium
import pandas as pd
from PyQt5.QtWebEngineWidgets import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from folium import plugins
from folium.plugins import *


class FoliumMap:
    def __init__(self):
        super().__init__()

        # --- 판다스 옵션
        pd.set_option("display.max_columns", None)
        pd.set_option("display.max_rows", None)

        # --- 레이아웃 & 버튼 & 웹엔진뷰
        self.web = QWebEngineView()
        self.con = sqlite3.connect('../database/seoul_db.db')
        self.cur = self.con.cursor()

        # --- self.seoul_map 지도 설정
        self.latitude = 37.564214  # 위도
        self.longitude = 127.001699  # 경도
        self.zoom_level = 11
        self.titles = "http://mt0.google.com/vt/lyrs=m&hl=ko&x={x}&y={y}&z={z}"
        self.attr = "Google"
        # self.coordinate = (35.19475778198943, 126.8399771747554)

        # --- folium 맵 설정: 서울 전체 맵
        self.seoul_map = folium.Map(
            tiles=self.titles,  # --- 배경지도 tiles에 대한 속성 (기본값: https://www.openstreetmap.org)
            attr=self.attr,
            zoom_start=self.zoom_level,  # --- 화면 보여줄 거리 / 값이 적을수록 가까이 보여줌
            location=[self.latitude, self.longitude],  # --- 현재 화면에 보여줄 좌표 값
            control_scale=True,  # --- contol_scale: True 시 맵 좌측 하단에 배율을 보여줌
            # zoom_control = False,   # --- zoom_control: False 시 줌 컨트롤러가 사라집니다. (단, 마우스 휠 줌은 가능)
            # scrollWheelZoom = False,  # --- scrollWheelZoom: False 시 스크롤을 사용할 수 없음
            # dragging = False  # --- dragging: False 시 마우스 드래그를 사용할 수 없음
        )
        self.marker_cluster = MarkerCluster().add_to(self.seoul_map)
        self.mini_map = MiniMap().add_to(self.seoul_map)


    # --- 메소드 작성 부분
    """
    ▼ 메소드 설명:
    self.mapping_tour_all_show()  -> 모든 관광명소를 지도에 마커+클러스트로 표시합니다.
    self.mapping_tour_guname_show()  -> 특정 관광명소를 지도에 마커+클러스트로 표시합니다.
    self.mapping_lodges_all_show()  -> 모든 숙박업소를 지도에 마커+클러스트로 표시합니다.
    self.mapping_lodges_guname_show()  -> 특정 숙박업소를 지도에 마커+클러스트로 표시합니다.
    self.mapping_food_all_show()  -> 모든 음식점을 지도에 마커+클러스트로 표시합니다.
    self.mapping_food_guname_show(guname: str)  -> 특정 음식점을 지도에 마커+클러스트로 표시합니다.  
    """
    def mapping_tour_all_show(self):
        """DB의 관광명소 목록을 맵에 마커 + 클러스트로 적용시킵니다"""
        tour_query = pd.read_sql("SELECT 상호명, 신주소, 전화번호, 웹사이트, x_pos, y_pos, img_path FROM seoul_tourist", self.con)
        for index, row in tour_query.iterrows():
            x_pos = row['x_pos']
            y_pos = row['y_pos']
            name = row['상호명']
            info = row['신주소'], row['전화번호']
            link = f"<a href={row['웹사이트']}>웹사이트 접속</a>"
            img = row['img_path']
            roadview = f'<a href="https://www.google.com/maps?layer=c&cbll={str(x_pos)},{str(y_pos)}">구글 거리뷰로 보기</a>'
            icon = folium.features.CustomIcon(img, icon_size=(50, 50)) #사진으로 보여주기
            # icon = folium.Icon(color="purple", icon="glyphicon glyphicon-tag", icon_color="white")
            popup = folium.Popup(f"<img src='{img}'>" + "<br>" + name + f"({str(link)})" + "<br><br>" + str(info) + "<br><br>" + roadview, min_width=500, max_width=500)
            folium.Marker([x_pos, y_pos], tooltip=name, popup=popup, icon=icon).add_to(self.marker_cluster)

    def mapping_tour_guname_show(self, guname: str):
        """DB의 관광명소 목록을 맵에 마커 + 클러스트로 적용시킵니다"""
        tour_query = pd.read_sql(f"SELECT 상호명, 신주소, 전화번호, 웹사이트, x_pos, y_pos, img_path FROM seoul_tourist WHERE 신주소 LIKE '%{guname}%'", self.con)
        for index, row in tour_query.iterrows():
            x_pos = row['x_pos']
            y_pos = row['y_pos']
            name = row['상호명']
            info = row['신주소'], row['전화번호']
            link = f"<a href={row['웹사이트']}>웹사이트 접속</a>"
            img = row['img_path']
            roadview = f'<a href="https://www.google.com/maps?layer=c&cbll={str(x_pos)},{str(y_pos)}">구글 거리뷰로 보기</a>'
            icon = folium.features.CustomIcon(img, icon_size=(50, 50))
            # icon = folium.Icon(color="purple", icon="glyphicon glyphicon-tag", icon_color="white")
            popup = folium.Popup(f"<img src='{img}'>" + "<br>" + name + f"({str(link)})" + "<br><br>" + str(info) + "<br><br>" + roadview, min_width=500, max_width=500)
            folium.Marker([x_pos, y_pos], tooltip=name, popup=popup, icon=icon).add_to(self.marker_cluster)
​

    def mapping_lodges_all_show(self):
        """DB의 숙박지 목록을 맵에 마커 + 클러스트로 적용시킵니다"""
        lodge_query = pd.read_sql("SELECT 사업장명, 도로명주소, 전화번호, x_pos, y_pos, img_path FROM seoul_lodges", self.con)
        for index, row in lodge_query.iterrows():
            x_pos = row['x_pos']
            y_pos = row['y_pos']
            name = row['사업장명']
            info = row['도로명주소'], row['전화번호']
            img = row['img_path']
            roadview = f'<a href="https://www.google.com/maps?layer=c&cbll={str(x_pos)},{str(y_pos)}">구글 거리뷰로 보기</a>'
            icon = folium.Icon(color="blue", icon="glyphicon glyphicon-tag", icon_color="white")
            popup = folium.Popup(f"<img src='{img}'>" + "<br><br>" + name + "<br><br>" + str(info) + "<br><br>" + roadview, min_width=400, max_width=400)
            # icon = plugins.BeautifyIcon(
            #     icon='utensils',
            #     border_color='darkblue',
            #     text_color='darkblue',
            #     icon_shape='triangle',
            # )
            folium.Marker([x_pos, y_pos], tooltip=name, popup=popup, icon=icon).add_to(self.marker_cluster)

    def mapping_lodges_guname_show(self, guname: str):
        """DB의 숙박지 목록을 구별로 맵에 마커 + 클러스트로 적용시킵니다"""
        lodge_query = pd.read_sql(f"SELECT 사업장명, 도로명주소, 전화번호, x_pos, y_pos, img_path FROM seoul_lodges WHERE 도로명주소 LIKE '%{guname}%'", self.con)
        for index, row in lodge_query.iterrows():
            x_pos = row['x_pos']
            y_pos = row['y_pos']
            name = row['사업장명']
            info = row['도로명주소'], row['전화번호']
            img = row['img_path']
            roadview = f'<a href="https://www.google.com/maps?layer=c&cbll={str(x_pos)},{str(y_pos)}">구글 거리뷰로 보기</a>'
            popup = folium.Popup(f"<img src='{img}'>" + "<br><br>" + name + "<br><br>" + str(info) + "<br><br>" + roadview, min_width=400, max_width=400)
            icon = folium.Icon(color="blue", icon="glyphicon glyphicon-tag", icon_color="white")
            folium.Marker([x_pos, y_pos], tooltip=name, popup=popup, icon=icon).add_to(self.marker_cluster)

    def mapping_food_all_show(self):
        """DB의 음식점 목록을 맵에 마커 + 클러스트로 적용시킵니다"""
        food_query = pd.read_sql("SELECT name, address, x_pos, y_pos, img_path FROM food_list", self.con)
        for index, row in food_query.iterrows():
            x_pos = row['x_pos']
            y_pos = row['y_pos']
            name = row['name']
            info = row['address']
            img = row['img_path']
            roadview = f'<a href="https://www.google.com/maps?layer=c&cbll={str(x_pos)},{str(y_pos)}">구글 거리뷰로 보기</a>'
            popup = folium.Popup(f"<img src='{img}'>" + "<br><br>" + name + "<br><br>" + str(info) + "<br><br>" + roadview, min_width=400, max_width=400)
            icon = folium.Icon(color="red", icon="glyphicon glyphicon-tag", icon_color="white")
            folium.Marker([x_pos, y_pos], tooltip=name, popup=popup, icon=icon).add_to(self.marker_cluster)

    def mapping_food_guname_show(self, guname: str):
        """DB의 음식점 목록을 구별로 마커 + 클러스트로 적용시킵니다"""
        food_query = pd.read_sql(f"SELECT gu_name, name, rate, address, x_pos, y_pos, img_path FROM food_list WHERE gu_name = '{guname}'", self.con)
        for index, row in food_query.iterrows():
            x_pos = row['x_pos']
            y_pos = row['y_pos']
            name = row['name']
            info = row['address']
            img = row['img_path']
            roadview = f'<a href="https://www.google.com/maps?layer=c&cbll={str(x_pos)},{str(y_pos)}">구글 거리뷰로 보기</a>'
            popup = folium.Popup(f"<img src='{img}'>" + "<br><br>" + name + "<br><br>" + str(info) + "<br><br>" + roadview, min_width=400, max_width=400)
            icon = folium.Icon(color="red", icon="glyphicon glyphicon-tag", icon_color="white")
            folium.Marker([x_pos, y_pos], tooltip=name, popup=popup, icon=icon).add_to(self.marker_cluster)

    def load_map(self):
        """self.seoul_map을 index.html 파일로 저장하고, PyQt 레이아웃에 QWebEngineView를 추가합니다"""
        self.seoul_map.save('index.html', close_file=False)
        self.web.setUrl(QUrl("file:///index.html"))
        return self.web

    def load_map_2(self):
        """미사용"""
        with open('index.html', 'r', encoding="utf-8") as f:
            html = f.read()
            self.web.setUrl(QUrl(html))

    def button_clicked_event(self):
        """구글 스트릿 뷰 상태에서 뒤로가기 버튼을 클릭하면 원래 화면으로 이동합니다"""
        print('탑니까..')
        self.web.page().triggerAction(QWebEnginePage.WebAction.Back)

widget_for_food.py

더보기
import sys
import folium
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from seoul_widget import *


class SeoulForFood(QWidget, Ui_Form):
    def __init__(self, name, rate, address, main_dishes, price, x_pos, y_pos, img_path, parent=None):
        super().__init__(parent)
        self.setupUi(self)

        self.name = name
        self.rate = rate
        self.address = address
        self.main_dishes = main_dishes
        self.price = price
        self.x_pos = x_pos
        self.y_pos = y_pos
        self.img_path = img_path

        # Replace with the actual image path
        self.circular_image = self.circleImage(self.img_path)
        # self.imageLabel.setPixmap(circular_image)

        self.seoul_main = parent
        self.name_lab.setText(f"이 름 : {self.name}   평 점 : {self.rate}")
        self.type_lab.setText(f"메인 메뉴 : {self.main_dishes}   가 격 대 : {self.price}")
        self.location_lab.setText(f"주 소 : {self.address}")
        # self.img_label.setPixmap(QPixmap(f"{self.img_path}"))
        self.img_label.setPixmap(self.circular_image)

    def circleImage(self, imagePath):
        source = QtGui.QPixmap(imagePath)
        size = min(source.width(), source.height())

        target = QtGui.QPixmap(size, size)
        target.fill(QtCore.Qt.transparent)

        qp = QtGui.QPainter(target)
        qp.setRenderHints(qp.Antialiasing)
        path = QtGui.QPainterPath()
        path.addEllipse(0, 0, size, size)
        qp.setClipPath(path)

        sourceRect = QtCore.QRect(0, 0, size, size)
        sourceRect.moveCenter(source.rect().center())
        qp.drawPixmap(target.rect(), source, sourceRect)
        qp.end()

        return target

    def mousePressEvent(self, event):
        self.seoul_main.stackedWidget.setCurrentWidget(self.seoul_main.main_page_4)
        self.seoul_main.name_lab.setText(f"이 름 : {self.name}     평 점 : {self.rate}")
        self.seoul_main.type_lab.setText(f"메인 메뉴 : {self.main_dishes}     가 격 대 : {self.price}")
        self.seoul_main.location_lab.setText(f"주 소 : {self.address}")
        self.seoul_main.img_label.setPixmap(self.circular_image)
        self.create_map()

    def create_map(self):
        map = folium.Map(location=[self.x_pos, self.y_pos], zoom_start=17, scrollWheelZoom=False,
                         zoom_control=False, dragging=False)
        folium.Marker([self.x_pos, self.y_pos], tooltip=self.name, icon=folium.Icon(color="green")).add_to(
            map)

        map.save('map.html')
        self.loadPage()

    def loadPage(self):
        layout = self.seoul_main.map_widget.layout()
        layout.addWidget(self.seoul_main.webview)
        with open('map.html', 'r', encoding='UTF8') as f:
            html = f.read()
            self.seoul_main.webview.setHtml(html)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    myWindow = SeoulForFood()
    myWindow.show()
    app.exec()

widget_for_sleep.py

더보기
import sys
import folium
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from seoul_widget import *

class SeoulForSleep(QWidget, Ui_Form):
    def __init__(self, name, status, address, x_pos, y_pos, image_path,parent=None):
        super().__init__(parent)
        self.setupUi(self)

        self.name = name
        self.status = status
        self.address = address
        self.x_pos = x_pos
        self.y_pos = y_pos
        self.image_path = image_path
        self.seoul_main = parent
        self.circular_img = self.circleImage(image_path)


        self.name_lab.setText(f"이 름 : {self.name}")
        self.type_lab.setText(f"상 태 : {self.status}")
        self.location_lab.setText(f"주 소 : {self.address}")
        self.img_label.setPixmap(self.circular_img)

    def mousePressEvent(self, event):
        self.seoul_main.stackedWidget.setCurrentWidget(self.seoul_main.main_page_4)
        self.seoul_main.name_lab.setText(f"이 름 : {self.name}")
        self.seoul_main.type_lab.setText(f"상 태 : {self.status}")
        self.seoul_main.location_lab.setText(f"주 소 : {self.address}")
        # self.seoul_main.img_label.setPixmap(QPixmap(f"{self.image_path}"))
        self.seoul_main.img_label.setPixmap(self.circular_img)
        self.create_map()

    def circleImage(self, imagePath):
        source = QtGui.QPixmap(imagePath)
        size = min(source.width(), source.height())

        target = QtGui.QPixmap(size, size)
        target.fill(QtCore.Qt.transparent)

        qp = QtGui.QPainter(target)
        qp.setRenderHints(qp.Antialiasing)
        path = QtGui.QPainterPath()
        path.addEllipse(0, 0, size, size)
        qp.setClipPath(path)

        sourceRect = QtCore.QRect(0, 0, size, size)
        sourceRect.moveCenter(source.rect().center())
        qp.drawPixmap(target.rect(), source, sourceRect)
        qp.end()

        return target

    def create_map(self):
        map = folium.Map(location=[self.x_pos, self.y_pos], zoom_start=17, scrollWheelZoom=False,
                         zoom_control=False,  dragging=False)
        folium.Marker([self.x_pos, self.y_pos], tooltip=self.name, icon=folium.Icon(color="green")).add_to(
            map)
        map.save('map.html')
        self.loadPage()

    def loadPage(self):
        layout = self.seoul_main.map_widget.layout()
        layout.addWidget(self.seoul_main.webview)
        with open('map.html', 'r', encoding='UTF8') as f:
            html = f.read()
            self.seoul_main.webview.setHtml(html)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    myWindow = SeoulForSleep()
    myWindow.show()
    app.exec()

widget_for_tour.py

더보기
import sys
import folium
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from seoul_widget import *

class SeoulForTour(QWidget, Ui_Form):
    def __init__(self, name, address, working_day, working_time, holiday, x_pos, y_pos, image_path, parent=None):
        super().__init__(parent)
        self.setupUi(self)

        self.seoul_main = parent
        self.name = name
        self.address = address
        self.working_day = working_day
        self.working_time = working_time
        self.holiday = holiday
        self.x_pos = x_pos
        self.y_pos = y_pos
        self.image_path = image_path

        self.circlular_image = self.circleImage(self.image_path)

        self.name_lab.setText(f"이 름 : {self.name}")
        self.type_lab.setText(f"운영요일 : {self.working_day}\n운영시간 : {self.working_time}\n휴무일 :{self.holiday}")
        self.location_lab.setText(f"주 소 : {self.address}")
        # self.img_label.setPixmap(QPixmap(f"{self.image_path}"))
        self.img_label.setPixmap(self.circlular_image)

    def circleImage(self, imagePath):
        source = QtGui.QPixmap(imagePath)
        size = min(source.width(), source.height())

        target = QtGui.QPixmap(size, size)
        target.fill(QtCore.Qt.transparent)

        qp = QtGui.QPainter(target)
        qp.setRenderHints(qp.Antialiasing)
        path = QtGui.QPainterPath()
        path.addEllipse(0, 0, size, size)
        qp.setClipPath(path)

        sourceRect = QtCore.QRect(0, 0, size, size)
        sourceRect.moveCenter(source.rect().center())
        qp.drawPixmap(target.rect(), source, sourceRect)
        qp.end()

        return target

    def mousePressEvent(self, event):
        self.seoul_main.stackedWidget.setCurrentWidget(self.seoul_main.main_page_4)
        self.seoul_main.name_lab.setText(f"이 름 : {self.name}")
        self.seoul_main.type_lab.setText(f"운영요일 : {self.working_day}\n운영시간 : {self.working_time}\n휴무일 :{self.holiday}")
        self.seoul_main.location_lab.setText(f"주 소 : {self.address}")
        self.seoul_main.img_label.setPixmap(self.circlular_image)
        self.create_map()

    def create_map(self):
        map = folium.Map(location=[self.x_pos, self.y_pos], zoom_start=17, scrollWheelZoom=False,
                         zoom_control=False,  dragging=False)
        folium.Marker([self.x_pos, self.y_pos], tooltip=self.name, icon=folium.Icon(color="green")).add_to(
            map)
        map.save('map.html')
        self.loadPage()

    def loadPage(self):
        layout = self.seoul_main.map_widget.layout()
        layout.addWidget(self.seoul_main.webview)
        with open('map.html', 'r', encoding='UTF8') as f:
            html = f.read()
            self.seoul_main.webview.setHtml(html)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    myWindow = SeoulForTour()
    myWindow.show()
    app.exec()

widget_for_graph.py

더보기
import sys
import folium
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from map_widget import *

class SeoulforGraph(QWidget, Ui_Form):
    def __init__(self, name, img_path, desc, parent=None):
        super().__init__(parent)
        self.setupUi(self)

        self.graph_name = name
        self.img_path = img_path
        self.desc = desc
        self.seoul_main = parent

        self.map_lab.setPixmap(QPixmap(f"{self.img_path}"))
        self.map_info.setText(f"{self.graph_name}")

    def mousePressEvent(self, event):
        self.seoul_main.stackedWidget.setCurrentWidget(self.seoul_main.main_page_7)
        self.seoul_main.graph_img_lab.setPixmap(QPixmap(f"{self.img_path}"))
        self.seoul_main.graph_info_lab.setText(f"{self.desc}")
        self.seoul_main.grahp_title_lab.setText(f'{self.graph_name}')

if __name__ == '__main__':
    app = QApplication(sys.argv)
    myWindow = SeoulforGraph()
    myWindow.show()
    app.exec()
profile

소연의_개발일지

@ssoyxon

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!