栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Pyqt5实践:实现快捷方式软件

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Pyqt5实践:实现快捷方式软件

Pyqt5实践:实现快捷方式软件@TOC

工具准备

Python3.x;
Python库:pyqt5

代码展示:

直接贴代码,由于工作繁忙,实在没时间写文档0.0,代码里面都有注释,有不懂评论区问。(先看看反响咋样,如果看的人多我再写具体思路。)

界面代码,使用QtDesigner画的,再通过pyuic转换的。

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'Form.ui'
#
# Created by: PyQt5 UI code generator 5.13.0
#
# WARNING! All changes made in this file will be lost!


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(250, 500)
        Form.setStyleSheet("#Form{n"
" border-top-left-radius:10px;n"
" border-bottom-left-radius:10px;n"
"n"
"}n"
"QGroupBox{n"
"border-top:0px solid rgb(190, 190, 190);n"
"border-right:0px solid rgb(190, 190, 190);n"
"border-bottom:2px solid rgb(190, 190, 190);n"
"border-left:0px solid rgb(190, 190, 190);n"
"font: 75 10pt "微软雅黑";n"
"}")
        self.verticalLayout = QtWidgets.QVBoxLayout(Form)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setSpacing(0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.choose_exe_btn = QtWidgets.QPushButton(Form)
        self.choose_exe_btn.setObjectName("choose_exe_btn")
        self.horizontalLayout.addWidget(self.choose_exe_btn)
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem)
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.scrollArea = QtWidgets.QScrollArea(Form)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.scrollArea.sizePolicy().hasHeightForWidth())
        self.scrollArea.setSizePolicy(sizePolicy)
        self.scrollArea.setMinimumSize(QtCore.QSize(250, 475))
        self.scrollArea.setMaximumSize(QtCore.QSize(250, 475))
        self.scrollArea.setWidgetResizable(True)
        self.scrollArea.setObjectName("scrollArea")
        self.main_widget = QtWidgets.QWidget()
        self.main_widget.setGeometry(QtCore.QRect(0, 0, 248, 473))
        self.main_widget.setMinimumSize(QtCore.QSize(240, 470))
        self.main_widget.setStyleSheet("#main_widget{n"
"    background-color:rgb(68, 68, 68);n"
"}n"
"n"
"QPushButton{n"
"    border:1px solid lightgray;n"
"    background:rgb(255, 255, 255);n"
"}n"
"QPushButton::hover{n"
"    border-color:rgb(0, 170, 255);n"
"    background:transparent;n"
"}")
        self.main_widget.setObjectName("main_widget")
        self.main_layout = QtWidgets.QVBoxLayout(self.main_widget)
        self.main_layout.setContentsMargins(0, 0, 0, 6)
        self.main_layout.setObjectName("main_layout")
        spacerItem1 = QtWidgets.QSpacerItem(20, 464, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        self.main_layout.addItem(spacerItem1)
        self.scrollArea.setWidget(self.main_widget)
        self.verticalLayout.addWidget(self.scrollArea)

        self.retranslateUi(Form)
        QtCore.QmetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.choose_exe_btn.setText(_translate("Form", "选择程序"))

主要代码:

import sys, os
if hasattr(sys, 'frozen'):
    os.environ['PATH'] = sys._MEIPASS + ";" + os.environ['PATH']
from Form import Ui_Form
from PyQt5.QtWidgets import QWidget, QApplication, QGroupBox, QLabel, QPushButton, QAction, QMenu, QSystemTrayIcon
from PyQt5.QtCore import Qt, QRect
from PyQt5.QtGui import QCursor, QPixmap, QIcon
from PyQt5.Qt import QPropertyAnimation
from win32 import win32api, win32gui, win32print
from win32.lib import win32con
from win32.win32api import GetSystemMetrics
import win32ui
import win32gui
import win32con
import win32api

SCREEN_WEIGHT = 1920
SCREEN_HEIGHT = 1080
WINDOW_WEIGHT = 250
WINDOW_HEIGHT = 500
class mainwindow(QWidget, Ui_Form):
    def __init__(self):
        super(mainwindow, self).__init__()  # 初始化父类
        self.setupUi(self)
        self.setWindowOpacity(0.8)  # 设置窗口透明度
        self.choose_exe_btn.clicked.connect(self.choose_exe_func)
        self.choose_exe_btn.hide()
        self.setAcceptDrops(True)
        self.setWindowFlags(Qt.framelessWindowHint|Qt.WindowStaysOnTopHint) #顶层显示
        self.setAutoFillBackground(False)
        self.setAttribute(Qt.WA_TranslucentBackground, True)
        # 设置退出选项
        iconpath = "icon.png"
        quit_action = QAction('退出', self, triggered=self.quit)
        quit_action.setIcon(QIcon(iconpath))
        self.tray_icon_menu = QMenu(self)
        self.tray_icon_menu.addAction(quit_action)
        self.tray_icon = QSystemTrayIcon(self)
        self.tray_icon.setIcon(QIcon(iconpath))
        self.tray_icon.setContextMenu(self.tray_icon_menu)
        self.tray_icon.show()
        self.mouse_drag_pos = None
        self.is_left_mouse = False
        self.resize(WINDOW_WEIGHT, WINDOW_HEIGHT)
        SCREEN_WEIGHT, SCREEN_HEIGHT = self.get_real_resolution()
        self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.moved = False
        self.init()

    def init(self):
    # 读取配置
        f = open("config.ini", "r", encoding="utf-8")
        s =f.read()
        f.close()
        l1 = s.split(";")
        for l in l1:
            if len(l) > 0:
                file_path = l.split(",")[0]
                file_name = l.split(",")[1]
                self.append_shortcut(file_path, file_name)

    def choose_exe_func(self):
    # 这里原先有个按钮,我没做功能,隐藏了
        sener = self.sender()
        print(sener)

    def get_real_resolution(self):
        """获取真实的分辨率"""
        hDC = win32gui.GetDC(0)
        # 横向分辨率
        w = win32print.GetDeviceCaps(hDC, win32con.DESKTOPHORZRES)
        # 纵向分辨率
        h = win32print.GetDeviceCaps(hDC, win32con.DESKTOPVERTRES)
        return w, h

    def get_screen_size(self):
        """获取缩放后的分辨率"""
        w = GetSystemMetrics(0)
        h = GetSystemMetrics(1)
        return w, h

    def dragEnterEvent(self, QDragEnterEvent):
    # 这是拖拽文件相关的
        QDragEnterEvent.acceptProposedAction() #放行,否则不会执行dropEvent()函数

    def dropEvent(self, QDropEvent):
    # 这是拖拽文件相关的
        file_url_list = QDropEvent.mimeData().urls()
        if len(file_url_list) <= 0:
            return
        for file_url in file_url_list:
            file_path = str(file_url.path().lstrip('/'))
            file_name = str(file_url.fileName())
            if file_name.endswith(".lnk") or file_name.endswith(".exe"):
                self.append_shortcut(file_path, file_name)

    def mousePressEvent(self, QMouseEvent):
    # 移动窗体相关的
        if QMouseEvent.button() == Qt.LeftButton:
            self.mouse_drag_pos = QMouseEvent.globalPos() - self.pos()
            self.is_left_mouse = True
            self.setCursor(QCursor(Qt.OpenHandCursor))
            QMouseEvent.accept()

    def mouseMoveEvent(self, QMouseEvent):
    # 移动窗体相关的
        if Qt.LeftButton and self.is_left_mouse:
            self.move(QMouseEvent.globalPos() - self.mouse_drag_pos)
            QMouseEvent.accept()

    def mouseReleaseEvent(self, QMouseEvent):
    # 移动窗体相关的
        self.is_left_mouse = False
        self.setCursor(QCursor(Qt.ArrowCursor))

    def enterEvent(self, event):
    # 隐藏界面相关的
        self.hide_or_show('show', event)

    def leaveEvent(self, event):
    # 隐藏界面相关的
        self.hide_or_show('hide', event)

    def hide_or_show(self, mode, event):
    # 隐藏界面相关的
        pos = self.frameGeometry().topLeft()
        if mode == 'show' and self.moved:
            if pos.x() + WINDOW_WEIGHT >= SCREEN_WEIGHT:  # 右侧显示
                self.startAnimation(SCREEN_WEIGHT - WINDOW_WEIGHT + 2, pos.y())
                event.accept()
                self.moved = False
            elif pos.x() <= 0:  # 左侧显示
                self.startAnimation(0, pos.y())
                event.accept()
                self.moved = False
            elif pos.y() <= 0:  # 顶层显示
                self.startAnimation(pos.x(), 0)
                event.accept()
                self.moved = False
        elif mode == 'hide':
            if pos.x() + WINDOW_WEIGHT >= SCREEN_WEIGHT:  # 右侧隐藏
                self.startAnimation(SCREEN_WEIGHT - 2, pos.y())
                event.accept()
                self.moved = True
            elif pos.x() <= 2:  # 左侧隐藏
                self.startAnimation(2 - WINDOW_WEIGHT, pos.y())
                event.accept()
                self.moved = True
            elif pos.y() <= 2:  # 顶层隐藏
                self.startAnimation(pos.x(), 2 - WINDOW_HEIGHT)
                event.accept()
                self.moved = True

    def startAnimation(self, width, height):
    # 隐藏界面相关的
        animation = QPropertyAnimation(self, b"geometry", self)
        startpos = self.geometry()
        animation.setDuration(200)
        newpos = QRect(width, height, startpos.width(), startpos.height())
        animation.setEndValue(newpos)
        animation.start()

    def append_shortcut(self, file_path, file_name):
    # 增加新的快捷方式
        index = len(self.main_widget.children()) -1
        if index > 3:
            self.main_widget.setMinimumSize(240, 100*(index+1))
        for child in self.main_widget.children():
            if child.property("file_path") == file_path:
                return
        print(file_path,file_name)
        self.save_icon(file_path,file_name)
        group_box = QGroupBox()
        group_box.setFixedSize(240,100)
        group_box.setProperty("file_name", file_name) #添加自定义属性,我这里使用是为了储存文件路径和文件名,方便后面打开
        group_box.setProperty("file_path", file_path)
        icon_lab = QLabel(group_box)
        #icon_lab.setText("icon")
        if os.path.exists(r"icon/%s.bmp" % file_name.split(".")[0]):
            pix = QPixmap(r"icon/%s.bmp" % file_name.split(".")[0])
        else:
            pix = QPixmap(r"icon.png")
        icon_lab.setPixmap(pix)
        icon_lab.setScaledContents(True)
        #self.update()
        icon_lab.setGeometry(10,10,50,50)
        title_lab = QLabel(group_box)
        title_lab.setText(file_name)
        title_lab.setGeometry(10, 70, 200, 20)
        start_btn = QPushButton(group_box)
        start_btn.setText("运行")
        start_btn.setGeometry(130, 40, 50, 20)
        start_btn.clicked.connect(self.start_func)
        start_btn.setProperty("file_name", file_name)
        start_btn.setProperty("file_path", file_path)
        del_btn = QPushButton(group_box)
        del_btn.setText("删除")
        del_btn.setGeometry(185, 40, 50, 20)
        del_btn.clicked.connect(self.del_func)
        del_btn.setProperty("file_name", file_name)
        del_btn.setProperty("file_path", file_path)
        del_btn.setProperty("index", index+1)
        self.main_layout.insertWidget(index, group_box)
        self.save_icon(file_path, file_name)

    def del_func(self):
    # 删除快捷方式
        btn = self.sender()
        index = btn.property("index")
        file_name = btn.property("file_name")
        try:
            os.remove(r"icon/%s.bmp" % file_name.split(".")[0])
        except Exception:
            pass
        self.main_layout.removeWidget(self.main_widget.children()[index])
        for child in self.main_widget.children()[index].children():
            child.deleteLater()
        self.main_widget.children()[index].deleteLater()

    def start_func(self):
    # 打开软件
        btn = self.sender() # sebder()是Qt5的方法,通过该方法可获取触发该槽函数信号来源对象,说简单点就是获取触发该函数的按钮对象
        file_path = btn.property("file_path")# 通过自定义属性名获取其值
        file_name = btn.property("file_name")
        cmd = 'cd %s&%s:&start "" "%s"' % (file_path.rstrip(file_name), file_path[0], file_name)
        os.system(cmd)

    def save_icon(self, file_path, file_name):
    # 保存图标
        large, small = win32gui.ExtractIconEx(file_path, 0)
        try:
            useIcon = large[0]
            destroyIcon = small[0]
        except Exception:
            return
        win32gui.DestroyIcon(destroyIcon)

        hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))
        hbmp = win32ui.CreateBitmap()
        hbmp.CreateCompatibleBitmap(hdc, 32, 32)
        hdc = hdc.CreateCompatibleDC()

        hdc.SelectObject(hbmp)
        hdc.DrawIcon((0, 0), useIcon)
        savePath = r"icon/%s.bmp" % file_name.split(".")[0]
        hbmp.SaveBitmapFile(hdc, savePath)

    def save_config(self):
    # 保存当前所有的快捷方式
        f = open("config.ini", "w", encoding='utf-8')
        s = ""
        for child in self.main_widget.children():
            file_path = child.property("file_path")
            file_name = child.property("file_name")
            if file_name:
                s = s + "%s,%s;" % (file_path, file_name)
        f.write(s)
        f.close()

    def quit(self):
    # 退出,这里感觉还有点问题,但有说不出来
        self.save_config()
        self.close()
        sys.exit()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = mainwindow()
    w.show()
    sys.exit(app.exec_())

icon图标文件网上自己找,随便一张都可以。软件使用方法是将软件直接拖到软件里面,即可生成快捷方式。当软件处于窗口最左端和最右端时,会自动隐藏。
如果需要打包好的软件和软件源码,私信发我你的邮件地址,我邮件发给你(不要钱…)。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/740916.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号