PYQT5打包程序,如何设置图标

查看 92|回复 9
作者:ahehaoyu   
我使用GPT帮我生成了一个计时的小工具,效果达到了我的预期,但是在打包的时候遇到一个问题,没有窗体图标(打开软件的左上角)和任务栏托盘图标,在我自己电脑上可以显示,但是在别人电脑上就不行。
[i]
源码如下  最开始设置的self.setWindowIcon(QIcon(r'C:\Users\Administrator\Desktop\计时小工具\icons.ico')) 绝对路径,再使用第三方软件打包是可以实现,后面在改就不行,可能是我忘记了方法吧
[Python] 纯文本查看 复制代码import sys
import json
from PyQt5.QtWidgets import (QApplication, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit,QHeaderView,
                             QDateTimeEdit, QPushButton, QTableWidget, QTableWidgetItem, QDialog,QMainWindow,
                             QSystemTrayIcon, QMenu, QMessageBox)
from PyQt5.QtCore import QTimer, QDateTime, Qt
from PyQt5.QtGui import QIcon
from PyQt5.QtMultimedia import QSound
class EditDialog(QDialog):
    def __init__(self, title, datetime, parent=None):
        super().__init__(parent)
        self.setWindowTitle('修改计时任务')
        self.setGeometry(100, 100, 300, 150)
        layout = QVBoxLayout()
        title_layout = QHBoxLayout()
        title_label = QLabel('任务标题:', self)
        self.title_edit = QLineEdit(self)
        self.title_edit.setText(title)
        title_layout.addWidget(title_label)
        title_layout.addWidget(self.title_edit)
        layout.addLayout(title_layout)
        self.datetime_edit = QDateTimeEdit(self)
        self.datetime_edit.setDisplayFormat("yyyy-MM-dd HH:mm:ss")
        self.datetime_edit.setDateTime(QDateTime.fromString(datetime, "yyyy-MM-dd HH:mm:ss"))
        layout.addWidget(self.datetime_edit)
        button_layout = QHBoxLayout()
        save_button = QPushButton('保存', self)
        save_button.clicked.connect(self.accept)
        cancel_button = QPushButton('取消', self)
        cancel_button.clicked.connect(self.reject)
        button_layout.addWidget(save_button)
        button_layout.addWidget(cancel_button)
        layout.addLayout(button_layout)
        self.setLayout(layout)
    def get_data(self):
        return self.title_edit.text(), self.datetime_edit.dateTime().toString("yyyy-MM-dd HH:mm:ss")
class TimerApp(QWidget):
    def __init__(self):
        super().__init__()
        self.timers = []
        self.initUI()
    def initUI(self):
        self.setWindowTitle('计时小工具')
        self.setWindowIcon(QIcon(r'C:\Users\Administrator\Desktop\计时小工具\icons.ico'))  # 设置任务栏图标
        # 设置窗口大小
        self.resize(600, 300)
        layout = QVBoxLayout()
        self.alert_sound = QSound("alert.wav")
        # 表格
        self.timer_table = QTableWidget()
        self.timer_table.setColumnCount(4)
        self.timer_table.setHorizontalHeaderLabels(['序号', '任务标题', '设定时间', '倒计时'])
        self.timer_table.setSelectionBehavior(QTableWidget.SelectRows)  # 设置为整行选择
        self.timer_table.setSelectionMode(QTableWidget.SingleSelection)  # 设置为单行选择
        self.timer_table.horizontalHeader().setDefaultAlignment(Qt.AlignCenter)  # 表头居中
        layout.addWidget(self.timer_table)
        #隐藏垂直表头
        self.timer_table.verticalHeader().setVisible(False)
        #隐藏水平表头
        #self.timer_table.horizontalHeader().setVisible(False)
        #列宽自动分配
        self.timer_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        title_layout = QHBoxLayout()
        title_label = QLabel('任务标题:', self)
        self.title_edit = QLineEdit(self)
        title_layout.addWidget(title_label)
        title_layout.addWidget(self.title_edit)
        layout.addLayout(title_layout)
        self.datetime_edit = QDateTimeEdit(self)
        self.datetime_edit.setDisplayFormat("yyyy-MM-dd HH:mm:ss")
        self.datetime_edit.setDateTime(QDateTime.currentDateTime())
        layout.addWidget(self.datetime_edit)
        button_layout = QHBoxLayout()
        self.add_button = QPushButton('新增计时任务', self)
        self.add_button.clicked.connect(self.add_timer)
        button_layout.addWidget(self.add_button)
        self.edit_button = QPushButton('修改选中任务', self)
        self.edit_button.clicked.connect(self.edit_selected_timer)
        button_layout.addWidget(self.edit_button)
        self.delete_button = QPushButton('删除选中任务', self)
        self.delete_button.clicked.connect(self.delete_selected_timer)
        button_layout.addWidget(self.delete_button)
        layout.addLayout(button_layout)
        self.setLayout(layout)
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.update_timer_table)
        self.timer.start(10000)  # 每秒更新一次
        # 设置系统托盘图标和菜单
        self.tray_icon = QSystemTrayIcon(QIcon(r'C:\Users\Administrator\Desktop\计时小工具\icons.png'), self)
        tray_menu = QMenu()
        restore_action = tray_menu.addAction('恢复')
        quit_action = tray_menu.addAction('退出')
        restore_action.triggered.connect(self.show)
        quit_action.triggered.connect(QApplication.instance().quit)
        self.tray_icon.setContextMenu(tray_menu)
        self.tray_icon.activated.connect(self.on_tray_icon_activated)
        self.tray_icon.show()
        self.load_timers()  # 加载计时任务
    def closeEvent(self, event):
        event.ignore()
        self.hide()
        self.tray_icon.showMessage('计时软件', '软件已最小化到托盘。', QSystemTrayIcon.Information, 2000)
    def on_tray_icon_activated(self, reason):
        if reason == QSystemTrayIcon.Trigger:
            self.show()
    def add_timer(self):
        title = self.title_edit.text()
        if not title:
            QMessageBox.warning(self, "警告", "任务标题不能为空!")
            return
        datetime = self.datetime_edit.dateTime().toString("yyyy-MM-dd HH:mm:ss")
        self.timers.append({"title": title, "datetime": datetime})
        self.save_timers()
        self.load_timers()
    def edit_selected_timer(self):
        current_row = self.timer_table.currentRow()
        if current_row >= 0:
            self.edit_timer(current_row)
    """  
   def delete_selected_timer(self):
        current_row = self.timer_table.currentRow()
        if current_row >= 0:
            self.delete_timer(current_row)
            """
    def delete_selected_timer(self):
        current_row = self.timer_table.currentRow()
        if current_row >= 0:
            del self.timers[current_row]#从任务列表中删除任务
            self.update_timer_table()
            self.save_timers()
    def edit_timer(self, row):
        task = self.timers[row]
        dialog = EditDialog(task["title"], task["datetime"], self)
        dialog.setWindowModality(Qt.ApplicationModal)
        dialog.setWindowFlags(Qt.Dialog | Qt.WindowStaysOnTopHint)
        dialog.move(QApplication.desktop().screen().rect().center() - dialog.rect().center())
        dialog.exec_()
        if dialog.result() == QDialog.Accepted:
            new_title, new_datetime = dialog.get_data()
            self.timers[row] = {"title": new_title, "datetime": new_datetime}
            self.update_timer_table()
            self.save_timers()
    def delete_timer(self, row):
        del self.timers[row]
        self.save_timers()
        self.load_timers()
    def save_timers(self):
        with open('timers.json', 'w') as f:
            json.dump(self.timers, f, ensure_ascii=False, indent=4)
    def load_timers(self):
        try:
            with open('timers.json', 'r') as f:
                self.timers = json.load(f)
                self.timers = [task for task in self.timers if isinstance(task, dict) and "title" in task and "datetime" in task]
            self.update_timer_table()
        except (FileNotFoundError, json.JSONDecodeError):
            self.timers = []
    def calculate_time_diff(self, task_datetime):
        timer_datetime = QDateTime.fromString(task_datetime, "yyyy-MM-dd HH:mm:ss")
        current_time = QDateTime.currentDateTime()
        time_diff = current_time.secsTo(timer_datetime)
        if time_diff > 0:
            hours = time_diff // 3600
            minutes = (time_diff % 3600) // 60
            seconds = time_diff % 60
            return f"{hours}小时{minutes}分钟{seconds}秒"
        else:
            return "已到期"
    def update_timer_table(self):
       current_time = QDateTime.currentDateTime()
       self.timer_table.setRowCount(len(self.timers))
       expired_tasks = []
       for i, task in enumerate(self.timers):
           timer_datetime = QDateTime.fromString(task["datetime"], "yyyy-MM-dd HH:mm:ss")
           self.timer_table.setItem(i, 0, QTableWidgetItem(str(i + 1)))
           self.timer_table.setItem(i, 1, QTableWidgetItem(task["title"]))
           self.timer_table.setItem(i, 2, QTableWidgetItem(task["datetime"]))
           self.timer_table.setItem(i, 3, QTableWidgetItem(self.calculate_time_diff(task["datetime"])))
           if timer_datetime

图标, 小工具

flying1008   

  bundle_dir = getattr(sys, '_MEIPASS', os.path.abspath(os.path.dirname(__file__)))
  self.setWindowIcon(QIcon(os.path.join(bundle_dir,"icons.ico")))  
设置路径。
,用pyinstaller打包吧。这是spec
[Python] 纯文本查看 复制代码# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
py_files = [
                'tool.py'
]
a = Analysis(py_files,
             pathex=['C:\\Users\\Administrator\\Desktop\\tool'],
             binaries=[],
             datas=[('icons.png', '.'),('icons.ico.','.')],
             hiddenimports=[],
             hookspath=[],
             hooksconfig={},
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
                         
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,  
          [],
          name='tool',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          upx_exclude=[],
          runtime_tmpdir=None,
          console=False,
          disable_windowed_traceback=False,
          target_arch=None,
          codesign_identity=None,
          entitlements_file=None ,icon='icons.ico')
ahehaoyu
OP
  

一开始使用绝对路径,再使用这个第三方工具是可以打包图标的,后面怎么改都不行
[i]
niluelf   

应该是打包的时候没有把图片打包进去,
可以试试换成相对路径,然后没把图片打包进去的话,就把相关材料都打成包拷到另外一个电脑上~
Arcticlyc   

不要在程序中使用绝对路径
ahehaoyu
OP
  


niluelf 发表于 2024-7-9 15:12
应该是打包的时候没有把图片打包进去,
可以试试换成相对路径,然后没把图片打包进去的话,就把相关材料都 ...

改了相对路径依然不行
niluelf   


ahehaoyu 发表于 2024-7-9 15:43
改了相对路径依然不行

应该是你这个打包工具没有把图片打包进去才是真正的问题,我没用过打包程序,不都是命令行命令直接打包吗?
ahehaoyu
OP
  


niluelf 发表于 2024-7-9 15:45
应该是你这个打包工具没有把图片打包进去才是真正的问题,我没用过打包程序,不都是命令行命令直接打包吗 ...

我使用的是这个命令 依旧不行 pyinstaller -F -w -i icons.ico 234.py
niluelf   


ahehaoyu 发表于 2024-7-9 15:51
我使用的是这个命令 依旧不行 pyinstaller -F -w -i icons.ico 234.py

我没遇到这种情况,我打包用的命令行都挺好使~
ahehaoyu
OP
  


niluelf 发表于 2024-7-9 15:55
我没遇到这种情况,我打包用的命令行都挺好使~

老哥能用我的那个源码测试一下吗
您需要登录后才可以回帖 登录 | 立即注册

返回顶部