13기 스터디 1주차_파이썬 코드를 EXE와 배치파일로 만드는 GUI 프로그램 만들기

소개

파이썬 코드를 만들다보니

1) 해당 파일을 빠르게 실행하고 싶다든가 (VSCODE와 같은 편집기를 실행하지 않고)

2) EXE 프로그램으로 만들어서 어디든 가지고 다니면서 쓰고 다니고 싶다는

생각이 들었습니다.

그래서 배치 파일과 EXE 프로그램으로 빠르게 만들어주는 GUI 프로그램을 만들기로 하였습니다.

진행 방법

‎​챗지피티 4o를 기본으로 사용하고

필요에 따라 o1-mini 를 사용하여 제작하였습니다.

생성형 인공지능에게

1) 파이썬 전문가로서 역할을 부여하고

2) 아이디어를 제공한뒤 (배치파일이나, exe 파일로 만드는 gui 프로그램을 만들고 싶다는 계획)

3) 해당 아이디어를 기반으로 챗지피티가 어느정도 잘 설계했는지 한번 확인을 받고 최종 코드를 요청하였습니다.

gui는 pyside6로 제작을 요청하였습니다.

# pip install Pyside6

import os
import subprocess
import json
from PySide6.QtWidgets import (QApplication, QWidget, QVBoxLayout, QPushButton, QMessageBox, 
                               QListWidget, QInputDialog, QFileDialog, QHBoxLayout, QLabel,
                               QListWidgetItem, QGroupBox, QMenu)
from PySide6.QtCore import Qt
from datetime import datetime

class FileListItem(QWidget):
    def __init__(self, filename, parent=None):
        super().__init__(parent)
        self.filename = filename
        layout = QHBoxLayout(self)
        self.label = QLabel(filename)
        layout.addWidget(self.label)
        layout.addStretch()
        self.setLayout(layout)

class UtilityManager(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("유틸리티 관리 프로그램")
        self.setGeometry(100, 100, 1000, 600)

        main_layout = QHBoxLayout()
        left_layout = QVBoxLayout()
        right_layout = QVBoxLayout()

        # 버튼들 추가
        self.open_current_folder_button = QPushButton('현재 실행 폴더 열기', self)
        self.open_current_folder_button.clicked.connect(self.open_current_folder)

        self.create_batch_button = QPushButton('배치파일 만들기', self)
        self.create_batch_button.clicked.connect(self.create_batch_file)

        self.add_startup_button = QPushButton('자동 실행 설정', self)
        self.add_startup_button.clicked.connect(self.add_to_startup)

        self.check_startup_button = QPushButton('등록 확인', self)
        self.check_startup_button.clicked.connect(self.check_startup_registration)

        self.delete_startup_button = QPushButton('등록 삭제', self)
        self.delete_startup_button.clicked.connect(self.remove_from_startup)

        self.create_exe_button = QPushButton('EXE 생성', self)
        self.create_exe_button.clicked.connect(self.create_exe_file)

        left_layout.addWidget(self.open_current_folder_button)
        left_layout.addWidget(self.create_batch_button)
        left_layout.addWidget(self.add_startup_button)
        left_layout.addWidget(self.check_startup_button)
        left_layout.addWidget(self.delete_startup_button)
        left_layout.addWidget(self.create_exe_button)

        # 배치 파일 목록
        batch_group = QGroupBox("현재 폴더의 배치 파일:")
        batch_layout = QVBoxLayout()
        self.batch_list = QListWidget(self)
        self.batch_list.itemDoubleClicked.connect(self.run_file)
        self.batch_list.setContextMenuPolicy(Qt.CustomContextMenu)
        self.batch_list.customContextMenuRequested.connect(self.show_context_menu)
        batch_layout.addWidget(self.batch_list)
        batch_group.setLayout(batch_layout)

        # EXE 파일 목록
        exe_group = QGroupBox("dist 폴더의 EXE 파일:")
        exe_layout = QVBoxLayout()
        self.exe_list = QListWidget(self)
        self.exe_list.itemDoubleClicked.connect(self.run_file)
        self.exe_list.setContextMenuPolicy(Qt.CustomContextMenu)
        self.exe_list.customContextMenuRequested.connect(self.show_context_menu)
        exe_layout.addWidget(self.exe_list)
        exe_group.setLayout(exe_layout)

        right_layout.addWidget(batch_group)
        right_layout.addWidget(exe_group)

        main_layout.addLayout(left_layout)
        main_layout.addLayout(right_layout)

        self.setLayout(main_layout)

        self.update_file_lists()

    def open_current_folder(self):
        current_dir = os.getcwd()
        os.startfile(current_dir)

    def create_batch_file(self):
        file_path, _ = QFileDialog.getOpenFileName(self, "배치 파일로 만들 파일 선택", "", "Python Files (*.py)")
        if file_path:
            current_dir = os.path.dirname(file_path)
            python_file_name = os.path.splitext(os.path.basename(file_path))[0]
            timestamp = datetime.now().strftime("%Y_%m_%d_%H_%M_%S")
            batch_file_name = f"{python_file_name}_{timestamp}.bat"
            batch_file_path = os.path.join(current_dir, batch_file_name)

            with open(batch_file_path, 'w') as f:
                f.write(f'@echo off\npython "{file_path}"\npause')

            QMessageBox.information(self, "배치파일 생성", f"배치파일이 생성되었습니다: {batch_file_path}")
            self.update_file_lists()

    def add_to_startup(self):
        file_path, _ = QFileDialog.getOpenFileName(
            self, 
            "시작 프로그램으로 등록할 파일 선택", 
            "", 
            "Batch and Executable Files (*.bat *.exe);;Batch Files (*.bat);;Executable Files (*.exe)"
        )
        if file_path:
            startup_path = os.path.join(os.environ['APPDATA'], 'Microsoft', 'Windows', 'Start Menu', 'Programs', 'Startup')
            file_name = os.path.basename(file_path)
            startup_file_path = os.path.join(startup_path, file_name)

            try:
                if file_path.endswith('.bat'):
                    with open(file_path, 'r') as source, open(startup_file_path, 'w') as target:
                        target.write(source.read())
                else:
                    import shutil
                    shutil.copy2(file_path, startup_file_path)
                
                QMessageBox.information(self, "자동 시작 설정", f"{file_name}이(가) 시작 프로그램으로 등록되었습니다.")
            except Exception as e:
                QMessageBox.warning(self, "오류", f"파일을 시작 프로그램 폴더에 복사하는 중 오류가 발생했습니다: {str(e)}")
    def check_startup_registration(self):
        startup_programs = self.get_startup_programs()
        if startup_programs:
            programs_list = "\n".join(startup_programs)
            QMessageBox.information(self, "등록된 시작 프로그램", f"현재 등록된 시작 프로그램:\n{programs_list}")
        else:
            QMessageBox.information(self, "등록된 시작 프로그램", "등록된 시작 프로그램이 없습니다.")

    def remove_from_startup(self):
        startup_programs = self.get_startup_programs()
        if not startup_programs:
            QMessageBox.information(self, "등록 삭제", "삭제할 시작 프로그램이 없습니다.")
            return

        item, ok = QInputDialog.getItem(self, "등록 삭제", "삭제할 프로그램을 선택하세요:", startup_programs, 0, False)
        if ok and item:
            startup_path = os.path.join(os.environ['APPDATA'], 'Microsoft', 'Windows', 'Start Menu', 'Programs', 'Startup')
            file_path = os.path.join(startup_path, item)
            try:
                os.remove(file_path)
                QMessageBox.information(self, "등록 삭제", f"{item}이(가) 시작 프로그램에서 삭제되었습니다.")
            except Exception as e:
                QMessageBox.warning(self, "삭제 오류", f"삭제 중 오류가 발생했습니다: {str(e)}")

    def create_exe_file(self):
        file_path, _ = QFileDialog.getOpenFileName(self, "EXE로 변환할 Python 파일 선택", "", "Python Files (*.py)")
        if file_path:
            options = ["기본 설정", "JSON 설정 파일 선택"]
            choice, ok = QInputDialog.getItem(self, "설정 선택", "EXE 생성 설정을 선택하세요:", options, 0, False)
            
            if ok:
                current_dir = os.getcwd()
                timestamp = datetime.now().strftime("%Y_%m_%d_%H_%M_%S")
                python_file_name = os.path.splitext(os.path.basename(file_path))[0]
                
                if choice == "JSON 설정 파일 선택":
                    json_path, _ = QFileDialog.getOpenFileName(self, "JSON 설정 파일 선택", "", "JSON Files (*.json)")
                    if not json_path:
                        return
                    with open(json_path, 'r') as json_file:
                        config = json.load(json_file)
                    config_name = os.path.basename(json_path).split('.')[0]
                else:
                    config = {"cmd_open": False, "one_file": True, "files_to_include": []}
                    config_name = "기본 설정"

                exe_file_name = f"[{config_name}]_{python_file_name}_{timestamp}.exe"
                
                pyinstaller_command = [
                    'pyinstaller',
                    '--name', exe_file_name,
                    '--distpath', os.path.join(current_dir, 'dist'),
                    '--workpath', os.path.join(current_dir, 'build'),
                    '--specpath', current_dir,
                    '--onefile',
                    file_path
                ]
                
                if config.get('cmd_open', False):
                    pyinstaller_command.append('--console')
                else:
                    pyinstaller_command.append('--windowed')
                
                for file in config.get('files_to_include', []):
                    pyinstaller_command.extend(['--add-data', f'{file}:.'])

                # 생성된 명령 출력
                print("생성된 PyInstaller 명령:")
                print(" ".join(pyinstaller_command))

                try:
                    subprocess.run(pyinstaller_command, check=True, cwd=current_dir)
                    
                    dist_path = os.path.join(current_dir, 'dist', exe_file_name)
                    QMessageBox.information(self, "EXE 생성", f"EXE 파일이 성공적으로 생성되었습니다: {dist_path}")
                    self.update_file_lists()
                except subprocess.CalledProcessError as e:
                    QMessageBox.warning(self, "EXE 생성 오류", f"EXE 파일 생성 중 오류가 발생했습니다: {str(e)}")
                except Exception as e:
                    QMessageBox.warning(self, "EXE 생성 오류", f"오류가 발생했습니다: {str(e)}")

    def get_startup_programs(self):
        startup_path = os.path.join(os.environ['APPDATA'], 'Microsoft', 'Windows', 'Start Menu', 'Programs', 'Startup')
        return [f for f in os.listdir(startup_path) if f.endswith('.bat') or f.endswith('.lnk') or f.endswith('.exe')]

    def update_file_lists(self):

        # 배치 파일 목록 업데이트
        self.batch_list.clear()
        current_dir = os.getcwd()
        for item in os.listdir(current_dir):
            full_path = os.path.join(current_dir, item)
            if os.path.isfile(full_path) and item.endswith('.bat'):
                item_widget = FileListItem(item)
                list_item = QListWidgetItem(self.batch_list)
                list_item.setSizeHint(item_widget.sizeHint())
                self.batch_list.addItem(list_item)
                self.batch_list.setItemWidget(list_item, item_widget)
        # EXE 파일 목록 업데이트
        self.exe_list.clear()
        dist_dir = os.path.join(current_dir, 'dist')
        if os.path.exists(dist_dir):
            for item in os.listdir(dist_dir):
                full_path = os.path.join(dist_dir, item)
                if os.path.isfile(full_path) and item.endswith('.exe'):
                    item_widget = FileListItem(item)
                    list_item = QListWidgetItem(self.exe_list)
                    list_item.setSizeHint(item_widget.sizeHint())
                    self.exe_list.addItem(list_item)
                    self.exe_list.setItemWidget(list_item, item_widget)

    def run_file(self, item):
        file_widget = item.listWidget().itemWidget(item)
        if item.listWidget() == self.batch_list:
            file_path = os.path.join(os.getcwd(), file_widget.filename)
        else:  # EXE list
            file_path = os.path.join(os.getcwd(), 'dist', file_widget.filename)
        
        try:
            if file_path.endswith('.bat'):
                subprocess.Popen(['cmd', '/c', file_path], creationflags=subprocess.CREATE_NEW_CONSOLE)
            elif file_path.endswith('.exe'):
                subprocess.Popen([file_path], shell=True)


        except Exception as e:
            QMessageBox.warning(self, "실행 오류", f"파일 실행 중 오류가 발생했습니다: {str(e)}")

    def show_context_menu(self, position):
        list_widget = self.sender()
        item = list_widget.itemAt(position)
        if item is not None:
            context_menu = QMenu(self)
            open_folder_action = context_menu.addAction("폴더 열기")
            action = context_menu.exec(list_widget.mapToGlobal(position))
            if action == open_folder_action:
                self.open_file_folder(item)

    def open_file_folder(self, item):
        file_widget = item.listWidget().itemWidget(item)
        if item.listWidget() == self.batch_list:
            folder_path = os.getcwd()
        else:  # EXE list
            folder_path = os.path.join(os.getcwd(), 'dist')
        os.startfile(folder_path)
        
def main():
    app = QApplication([])
    window = UtilityManager()
    window.show()
    app.exec()

if __name__ == '__main__':
    main()

vscode에서 실행하면 다음과 같은 gui가 뜹니다. 실제로 한번 테스트 해보세요!

한국어가 표시된 컴퓨터 화면의 스크린샷

결과와 배운 점

‎​시작 프로그램으로 등록하는 기능도 추가했습니다만

파이썬 코드일 때와 exe 파일이 되었을 때 파일을 참고(텍스트 파일이나 json 파일)하는 부분이 달라서 해당 부분에 대한 고려가 없는 경우 오류가 나타나곤 했습니다.

241116 이후 기능 개선된 코드

# pip install Pyside6

import os
import subprocess
import json
from PySide6.QtWidgets import (QApplication, QWidget, QVBoxLayout, QPushButton, QMessageBox, 
                               QListWidget, QInputDialog, QFileDialog, QHBoxLayout, QLabel,
                               QListWidgetItem, QGroupBox, QMenu)
from PySide6.QtCore import Qt
from datetime import datetime

class FileListItem(QWidget):
    def __init__(self, filename, parent=None):
        super().__init__(parent)
        self.filename = filename
        layout = QHBoxLayout(self)
        self.label = QLabel(filename)
        layout.addWidget(self.label)
        layout.addStretch()
        self.setLayout(layout)

class UtilityManager(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("유틸리티 관리 프로그램")
        self.setGeometry(100, 100, 1000, 600)

        main_layout = QHBoxLayout()
        left_layout = QVBoxLayout()
        right_layout = QVBoxLayout()

        # 버튼들 추가
        self.open_current_folder_button = QPushButton('현재 실행 폴더 열기', self)
        self.open_current_folder_button.clicked.connect(self.open_current_folder)

        self.create_batch_button = QPushButton('배치파일 만들기', self)
        self.create_batch_button.clicked.connect(self.create_batch_file)

        self.add_startup_button = QPushButton('자동 실행 설정', self)
        self.add_startup_button.clicked.connect(self.add_to_startup)

        self.check_startup_button = QPushButton('등록 확인', self)
        self.check_startup_button.clicked.connect(self.check_startup_registration)

        self.delete_startup_button = QPushButton('등록 삭제', self)
        self.delete_startup_button.clicked.connect(self.remove_from_startup)

        self.create_exe_button = QPushButton('EXE 생성', self)
        self.create_exe_button.clicked.connect(self.create_exe_file)

        left_layout.addWidget(self.open_current_folder_button)
        left_layout.addWidget(self.create_batch_button)
        left_layout.addWidget(self.add_startup_button)
        left_layout.addWidget(self.check_startup_button)
        left_layout.addWidget(self.delete_startup_button)
        left_layout.addWidget(self.create_exe_button)

        # 배치 파일 목록
        batch_group = QGroupBox("현재 폴더의 배치 파일:")
        batch_layout = QVBoxLayout()
        self.batch_list = QListWidget(self)
        self.batch_list.itemDoubleClicked.connect(self.run_file)
        self.batch_list.setContextMenuPolicy(Qt.CustomContextMenu)
        self.batch_list.customContextMenuRequested.connect(self.show_context_menu)
        batch_layout.addWidget(self.batch_list)
        batch_group.setLayout(batch_layout)

        # EXE 파일 목록
        exe_group = QGroupBox("dist 폴더의 EXE 파일:")
        exe_layout = QVBoxLayout()
        self.exe_list = QListWidget(self)
        self.exe_list.itemDoubleClicked.connect(self.run_file)
        self.exe_list.setContextMenuPolicy(Qt.CustomContextMenu)
        self.exe_list.customContextMenuRequested.connect(self.show_context_menu)
        exe_layout.addWidget(self.exe_list)
        exe_group.setLayout(exe_layout)

        right_layout.addWidget(batch_group)
        right_layout.addWidget(exe_group)

        main_layout.addLayout(left_layout)
        main_layout.addLayout(right_layout)

        self.setLayout(main_layout)

        self.update_file_lists()

    def open_current_folder(self):
        current_dir = os.getcwd()
        os.startfile(current_dir)

    def create_batch_file(self):
        file_path, _ = QFileDialog.getOpenFileName(self, "배치 파일로 만들 파일 선택", "", "Python Files (*.py)")
        if file_path:
            current_dir = os.path.dirname(file_path)
            python_file_name = os.path.splitext(os.path.basename(file_path))[0]
            timestamp = datetime.now().strftime("%Y_%m_%d_%H_%M_%S")
            batch_file_name = f"{python_file_name}_{timestamp}.bat"
            batch_file_path = os.path.join(current_dir, batch_file_name)

            with open(batch_file_path, 'w') as f:
                f.write(f'@echo off\npython "{file_path}"\npause')

            QMessageBox.information(self, "배치파일 생성", f"배치파일이 생성되었습니다: {batch_file_path}")
            self.update_file_lists()

    def add_to_startup(self):
        file_path, _ = QFileDialog.getOpenFileName(
            self, 
            "시작 프로그램으로 등록할 파일 선택", 
            "", 
            "Batch and Executable Files (*.bat *.exe);;Batch Files (*.bat);;Executable Files (*.exe)"
        )
        if file_path:
            startup_path = os.path.join(os.environ['APPDATA'], 'Microsoft', 'Windows', 'Start Menu', 'Programs', 'Startup')
            file_name = os.path.basename(file_path)
            startup_file_path = os.path.join(startup_path, file_name)

            try:
                if file_path.endswith('.bat'):
                    with open(file_path, 'r') as source, open(startup_file_path, 'w') as target:
                        target.write(source.read())
                else:
                    import shutil
                    shutil.copy2(file_path, startup_file_path)
                
                QMessageBox.information(self, "자동 시작 설정", f"{file_name}이(가) 시작 프로그램으로 등록되었습니다.")
            except Exception as e:
                QMessageBox.warning(self, "오류", f"파일을 시작 프로그램 폴더에 복사하는 중 오류가 발생했습니다: {str(e)}")
    def check_startup_registration(self):
        startup_programs = self.get_startup_programs()
        if startup_programs:
            programs_list = "\n".join(startup_programs)
            QMessageBox.information(self, "등록된 시작 프로그램", f"현재 등록된 시작 프로그램:\n{programs_list}")
        else:
            QMessageBox.information(self, "등록된 시작 프로그램", "등록된 시작 프로그램이 없습니다.")

    def remove_from_startup(self):
        startup_programs = self.get_startup_programs()
        if not startup_programs:
            QMessageBox.information(self, "등록 삭제", "삭제할 시작 프로그램이 없습니다.")
            return

        item, ok = QInputDialog.getItem(self, "등록 삭제", "삭제할 프로그램을 선택하세요:", startup_programs, 0, False)
        if ok and item:
            startup_path = os.path.join(os.environ['APPDATA'], 'Microsoft', 'Windows', 'Start Menu', 'Programs', 'Startup')
            file_path = os.path.join(startup_path, item)
            try:
                os.remove(file_path)
                QMessageBox.information(self, "등록 삭제", f"{item}이(가) 시작 프로그램에서 삭제되었습니다.")
            except Exception as e:
                QMessageBox.warning(self, "삭제 오류", f"삭제 중 오류가 발생했습니다: {str(e)}")

    def create_exe_file(self):
        file_path, _ = QFileDialog.getOpenFileName(self, "EXE로 변환할 Python 파일 선택", "", "Python Files (*.py)")
        if file_path:
            options = ["기본 설정", "JSON 설정 파일 선택"]
            choice, ok = QInputDialog.getItem(self, "설정 선택", "EXE 생성 설정을 선택하세요:", options, 0, False)
            
            if ok:
                current_dir = os.getcwd()
                timestamp = datetime.now().strftime("%Y_%m_%d_%H_%M_%S")
                python_file_name = os.path.splitext(os.path.basename(file_path))[0]
                
                if choice == "JSON 설정 파일 선택":
                    json_path, _ = QFileDialog.getOpenFileName(self, "JSON 설정 파일 선택", "", "JSON Files (*.json)")
                    if not json_path:
                        return
                    with open(json_path, 'r') as json_file:
                        config = json.load(json_file)
                    config_name = os.path.basename(json_path).split('.')[0]
                else:
                    config = {"cmd_open": False, "one_file": True, "files_to_include": []}
                    config_name = "기본 설정"

                exe_file_name = f"[{config_name}]_{python_file_name}_{timestamp}.exe"
                
                pyinstaller_command = [
                    'pyinstaller',
                    '--name', exe_file_name,
                    '--distpath', os.path.join(current_dir, 'dist'),
                    '--workpath', os.path.join(current_dir, 'build'),
                    '--specpath', current_dir,
                    '--onefile',
                    file_path
                ]
                
                if config.get('cmd_open', False):
                    pyinstaller_command.append('--console')
                else:
                    pyinstaller_command.append('--windowed')
                
                for file in config.get('files_to_include', []):
                    pyinstaller_command.extend(['--add-data', f'{file}:.'])

                # 생성된 명령 출력
                print("생성된 PyInstaller 명령:")
                print(" ".join(pyinstaller_command))

                try:
                    subprocess.run(pyinstaller_command, check=True, cwd=current_dir)
                    
                    dist_path = os.path.join(current_dir, 'dist', exe_file_name)
                    QMessageBox.information(self, "EXE 생성", f"EXE 파일이 성공적으로 생성되었습니다: {dist_path}")
                    self.update_file_lists()
                except subprocess.CalledProcessError as e:
                    QMessageBox.warning(self, "EXE 생성 오류", f"EXE 파일 생성 중 오류가 발생했습니다: {str(e)}")
                except Exception as e:
                    QMessageBox.warning(self, "EXE 생성 오류", f"오류가 발생했습니다: {str(e)}")

    def get_startup_programs(self):
        startup_path = os.path.join(os.environ['APPDATA'], 'Microsoft', 'Windows', 'Start Menu', 'Programs', 'Startup')
        return [f for f in os.listdir(startup_path) if f.endswith('.bat') or f.endswith('.lnk') or f.endswith('.exe')]

    def update_file_lists(self):

        # 배치 파일 목록 업데이트
        self.batch_list.clear()
        current_dir = os.getcwd()
        for item in os.listdir(current_dir):
            full_path = os.path.join(current_dir, item)
            if os.path.isfile(full_path) and item.endswith('.bat'):
                item_widget = FileListItem(item)
                list_item = QListWidgetItem(self.batch_list)
                list_item.setSizeHint(item_widget.sizeHint())
                self.batch_list.addItem(list_item)
                self.batch_list.setItemWidget(list_item, item_widget)
        # EXE 파일 목록 업데이트
        self.exe_list.clear()
        dist_dir = os.path.join(current_dir, 'dist')
        if os.path.exists(dist_dir):
            for item in os.listdir(dist_dir):
                full_path = os.path.join(dist_dir, item)
                if os.path.isfile(full_path) and item.endswith('.exe'):
                    item_widget = FileListItem(item)
                    list_item = QListWidgetItem(self.exe_list)
                    list_item.setSizeHint(item_widget.sizeHint())
                    self.exe_list.addItem(list_item)
                    self.exe_list.setItemWidget(list_item, item_widget)

    def run_file(self, item):
        file_widget = item.listWidget().itemWidget(item)
        if item.listWidget() == self.batch_list:
            file_path = os.path.join(os.getcwd(), file_widget.filename)
        else:  # EXE list
            file_path = os.path.join(os.getcwd(), 'dist', file_widget.filename)
        
        try:
            if file_path.endswith('.bat'):
                subprocess.Popen(['cmd', '/c', file_path], creationflags=subprocess.CREATE_NEW_CONSOLE)
            elif file_path.endswith('.exe'):
                subprocess.Popen([file_path], shell=True)


        except Exception as e:
            QMessageBox.warning(self, "실행 오류", f"파일 실행 중 오류가 발생했습니다: {str(e)}")

    def show_context_menu(self, position):
        list_widget = self.sender()
        item = list_widget.itemAt(position)
        if item is not None:
            context_menu = QMenu(self)
            open_folder_action = context_menu.addAction("폴더 열기")
            action = context_menu.exec(list_widget.mapToGlobal(position))
            if action == open_folder_action:
                self.open_file_folder(item)

    def open_file_folder(self, item):
        file_widget = item.listWidget().itemWidget(item)
        if item.listWidget() == self.batch_list:
            folder_path = os.getcwd()
        else:  # EXE list
            folder_path = os.path.join(os.getcwd(), 'dist')
        os.startfile(folder_path)
        
def main():
    app = QApplication([])
    window = UtilityManager()
    window.show()
    app.exec()

if __name__ == '__main__':
    main()

우선 간편하게 배치파일화 시켜서 파이썬 코드를 즉시 실행시킬 수 있어서 만족스럽습니다.

exe 파일로 만드는 과정도 쉬운 편이라 잘 쓰고 있습니다.

발표를 위한 패들렛: https://padlet.com/sangsang24/padlet-ofjj6km6uodvmfae 

도움 받은 글 (옵션)

‎​pyinstaller를 써야 한다는 점을 블로그와 유튜브 등을 참고하였습니다.

6
3개의 답글

👉 이 게시글도 읽어보세요