Récemment, des cours et des conférences ont été de plus en plus organisés à l'aide de systèmes de conférence Web tels que le zoom. Cependant, le principal inconvénient des cours en ligne est que l'écriture du tableau partagée à l'écran coulera peu de temps après que vous ayez pris une note. Afin de résoudre un tel problème, j'ai essayé de créer une application exe ** qui peut être enregistrée au format pdf en pressant la plage enregistrée (partie d'écran partagée, etc.) en un seul clic. (* Ne serrez que ceux qui ont la permission de presser)
L'application et ses détails peuvent être trouvés sur GitHub, alors j'apprécierais que vous puissiez l'utiliser et commenter (conseils, etc.). \ <Version de GitHub ↓ >
Cette fois, comme mémo de la procédure de création, j'utiliserai une application de capture d'écran complète simplifiée ** 1. [Conception graphique (apparence)](# 1-Conception graphique) 2. [Paramètres d'événement (action)](# 2-Paramètres d'événement) 3. [Create Icon](# 3-Create Icon Self-style) 4. [Exécution](conversion # 4-exe) ** J'écrirai dans l'ordre de. \ <Version simplifiée ↓ >
・ Windows10 ・ Python 3.7.9 (jusqu'à 3.7.X si exe est converti avec py2exe) ・ WxPython (phénix) · Power Point ・ Py2exe (les détails de l'installation seront décrits plus tard) (#Installation))
Donnez l'apparence de votre application avec ** wxpython **. La bibliothèque standard a tkinter, qui est facile à gérer, mais wxpython a beaucoup de traitement d'événements et vous pouvez créer des applications élaborées.
Fondamentalement, wx.Panel
(panneau) est réparti dans wx.Frame
(cadre, squelette), et des widgets tels que wx.Button
(bouton) y sont placés.
Les cadres, les panneaux et les widgets prennent presque les mêmes arguments, mais nous nous concentrerons sur ceux que nous utiliserons cette fois.
argument | La description |
---|---|
parent | parent. Placez-vous sur le cadre ou le panneau que vous placez ici. Lorsque le parent disparaît, l'enfant lui-même disparaît également. |
label / value | Définissez les caractères à afficher sur vous-même et les valeurs que vous détenez. Lequel peut être utilisé ou non peut être utilisé pour chaque widget. La valeur est[Widget].GetLabel() /[Widget].GetValue() Entrer,[Widget].SetLabel([valeur]) /[Widget].SetValue([valeur]) Peut être changé avec. |
pos | (x, y)Sous la forme d'un écran, ouparent Posséder x contre-Définissez la coordonnée y. Coin supérieur gauche |
size | (w, h)Définissez votre propre largeur et hauteur sous la forme de. |
Il existe également un moyen d'organiser des widgets avec un "sizer" tel que "wx.BoxSizer" sans utiliser "pos". Ensuite, lorsque l'utilisateur modifie la taille de la fenêtre, chaque pièce peut être déplacée ou mise à l'échelle en fonction de la taille. (Cette fois, je ne l'utiliserai pas car la taille de la fenêtre est fixe)
Voyons l'utilisation spécifique ci-dessous.
sample_1.py
# coding: utf-8
import wx #Importer wxpython
try: # ⏋
from ctypes import windll #| Réglage de la résolution de l'application
windll.shcore.SetProcessDpiAwareness(True) #| (Empêche la mise au point)
except: # |
pass # ⏌
app = wx.App() #Écrivez ceci au début et démarrez wx
#Paramètres de l'interface graphique ────────────────────────────────────────────────── - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
frame = wx.Frame(parent=None, #Créer un cadre (cadre extérieur)
title='Application Sukusho',
pos=(0, 0), # pos=(x, y)Est le x de la position du cadre avec le coin supérieur gauche de l'écran comme origine-coordonnée y
size=(400, 230), # size=(w, h)Est la largeur du cadre(w)Et hauteur(h)
style=wx.DEFAULT_FRAME_STYLE & ~(wx.RESIZE_BORDER | wx.MAXIMIZE_BOX))
#le style est un paramètre supplémentaire.Cette fois, désactiver le redimensionnement de la fenêtre
panel = wx.Panel(parent=frame) #Créer un panneau sur le cadre
wx.StaticText(parent=panel, label='Destination:', #Créer une chaîne sur le panneau.pos est parent(panel)Coordonnées relatives sur
pos=(20, 20))
wx.TextCtrl(parent=panel, value='Non sélectionné', #Créer un champ de saisie de dossier sur le panneau
pos=(150, 17), size=(160, -1), #à la taille"-1"Entrez et laissez-le à wx
style=wx.TE_READONLY) # TE_L'entrée peut être désactivée avec READONLY
wx.Button(parent=panel, label='...',
pos=(320, 16), size=(40, 35))
wx.StaticText(parent=panel, label='Dernière fois:', pos=(20, 70))
wx.StaticText(parent=panel, label='―', pos=(150, 70), size=(210, -1),
style=wx.TE_CENTER) # TE_Au CENTRE,Les caractères peuvent être centrés dans la largeur donnée par la taille
wx.Button(parent=panel, label='Sukusho',
pos=(20, 120), size=(340, 40))
# ───────────────────────────────────────────────────────────────────────────────────────────────────────
frame.Show() #Afficher le cadre quand il est beau
app.MainLoop() #Terminé en acceptant l'entrée d'événement
Lorsque vous l'exécutez, il aura l'air bien. Comme je n'ai pas défini d'événement, il n'y a pas de réponse même si j'appuie sur le bouton.
Définissez un événement dans le bouton ou le champ de saisie.
Fondamentalement, le contenu à traiter pour chaque opération est résumé dans la fonction func_1 (événement, [second argument], ...)
et lié avec [widget] .Bind ([type d'événement], func_1)
. Je vais.
Les types d'événements vont de ceux spécifiques à chaque widget, tels que wx.EVT_BUTTON
(lorsque le bouton est enfoncé) et'wx.EVT_SLIDER '(lorsque la valeur du curseur change), à wx.EVT_CLOSE
(la fenêtre se ferme). Quand) et ainsi de suite.
sample_2.py
# coding: utf-8
import os
import re
from glob import glob
from datetime import date
from PIL import ImageGrab
import wx
try:
from ctypes import windll
windll.shcore.SetProcessDpiAwareness(True)
except:
pass
TODAY = format(date.today()) #La date d'aujourd'hui
last_pic_num = 0 #Numéro de photo
#Définition de la fonction événementielle - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def open_folder_dialog(event): #Le premier argument de la fonction utilisée dans l'événement"event"Écrire
"""
Dossier le chemin du dossier sélectionné dans la boîte de dialogue_Affiché dans txctrl,
Obtenez le dernier numéro de photo dans le dossier, picture_Fonction pour mettre à jour les informations d'informations
"""
global last_pic_num
dlg = wx.DirDialog(parent=None, message='Sélectionnez la destination d'enregistrement') #Paramètres de la boîte de dialogue
if dlg.ShowModal() == wx.ID_OK: # ShowModal()Commencer avec,Une fois sélectionné, procédez comme suit: ↓
dirpath = dlg.GetPath() #Obtenez le chemin d'accès au dossier sélectionné,
folder_txctrl.SetValue(dirpath) #Mettre à jour le champ de saisie,
os.chdir(dirpath) #Déplacez-vous dans ce dossier,
all_pictures = [p for p in glob(os.path.join(dirpath, '*.png')) #Créez une liste de photos avec la date du jour
if re.search('{}_\\d'.format(TODAY), p)]
if all_pictures: #Si vous avez une photo,
last_pic_num = max(list(map(lambda x: int(re.findall('_(\\d+)', x)[0]), #Obtenez le dernier numéro,
all_pictures)))
picture_info.SetLabel(str(last_pic_num)) #Mettre à jour les informations de la photo
else:
last_pic_num = 0
picture_info.SetLabel('─')
scshot_button.Enable() #Activer le bouton de compression
def screen_shot(event):
"""
Appuyez sur l'écran,Enregistrer avec le numéro de photo avancé, picture_Fonction pour mettre à jour les informations d'informations
"""
global last_pic_num
last_pic_num += 1 #Augmenter le nombre de un,
picture_info.SetLabel(str(last_pic_num)) #Mettre à jour les informations de la photo
screen_picture = ImageGrab.grab() #Écraser,
save_name = TODAY + '_{}.png'.format(last_pic_num) # "2020-01-23_(nombre)"Au format de,
screen_picture.save(save_name) #sauvegarder
# ───────────────────────────────────────────────────────────────────────────────────────────────────────
app = wx.App()
#Paramètres de l'interface graphique ────────────────────────────────────────────────── - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
frame = wx.Frame(parent=None, title='Application Sukusho', pos=(0, 0), size=(400, 230),
style=wx.DEFAULT_FRAME_STYLE & ~(wx.RESIZE_BORDER | wx.MAXIMIZE_BOX))
panel = wx.Panel(parent=frame)
wx.StaticText(parent=panel, label='Destination:', pos=(20, 20))
folder_txctrl = wx.TextCtrl(parent=panel, value='Non sélectionné', pos=(100, 17), size=(210, -1), #Appelle plus tard
style=wx.TE_READONLY)
folder_button = wx.Button(parent=panel, label='...', pos=(320, 16), size=(40, 35)) #Appelle plus tard
wx.StaticText(parent=panel, label='Numéro de squash final d'aujourd'hui:', pos=(20, 70))
picture_info = wx.StaticText(parent=panel, label='―', pos=(200, 70), size=(160, -1), #Appelle plus tard
style=wx.TE_CENTER)
scshot_button = wx.Button(parent=panel, label='Sukusho', pos=(20, 120), size=(340, 40)) #Appelle plus tard
# ───────────────────────────────────────────────────────────────────────────────────────────────────────
scshot_button.Disable() #Désactivez le bouton presser jusqu'à ce que la destination d'enregistrement soit sélectionnée
#Réglage de l'événement ────────────────────────────────────────────────── - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
folder_button.Bind(wx.EVT_BUTTON, open_folder_dialog) #Lorsque vous appuyez sur le bouton,Exécute la fonction du deuxième argument
scshot_button.Bind(wx.EVT_BUTTON, screen_shot) #Remarque)À la fin de la fonction"()"Ne pas mettre.
# ───────────────────────────────────────────────────────────────────────────────────────────────────────
frame.SetIcon(wx.Icon('sample_icon.ico')) #Paramétrage de l'icône (erreur si le chemin spécifié n'existe pas)
frame.Show()
app.MainLoop()
Je n'ai pas créé d'icône, donc j'obtiens une erreur lorsque je l'exécute, mais lorsque j'appuie sur le bouton de compression, les photos sont enregistrées dans le dossier sélectionné.
Un fichier avec l'extension .ico
est requis, mais heureusement, il y a un site sur le net qui peut convertir .png
→ .ico
, alors faites du png avec Powerpo et convertissez-le. (Il n'est pas nécessaire que ce soit powerpo)
.png
avec. Vous pouvez le convertir en .ico
en utilisant ce site de conversion Faisons un favicon.ico semi-transparent multi-icône!. .. Cette fois, enregistrez-le sous "sample_icon.ico" dans le même répertoire ** que sample_2.py
**. (Si vous mettez le chemin approprié dans wx.Icon ([PATH])
, c'est correct n'importe où)
Lorsque vous exécutez "sample_2.py", vous pouvez voir que l'icône est définie dans le coin supérieur gauche de la fenêtre.Utilisez ** py2exe **, qui a un temps de démarrage court.
Si vous utilisez des versions jusqu'à python 3.4
pip install py2exe
Lorsque vous utilisez python 3.5-3.7 (ci-après dénommé 3.X), accédez au site de publication de py2exe et py2exe-0.9.3.2-cp3X-none- Téléchargez win_amd64.whl
(64 bits) ou py2exe-0.9.3.2-cp3X-none-win32.whl
(32 bits) et
py -3.X -m pip install 'Chemin du fichier téléchargé'
Vous devez créer un fichier d'installation appelé setup.py
. (Bref à dire)
Remettez-le dans le même répertoire ** que sample_2.py
**.
setup.py
from distutils.core import setup
import py2exe
option = {'compressed': 1, 'optimize': 2 , 'bundle_files': 3, 'excludes': ['email', 'numpy', 'test', 'tkinter']}
setup(
options={'py2exe': option},
windows=[{'script': 'sample_2.py', 'icon_resources': [(1, 'sample_icon.ico')]}],
zipfile='lib\\libs.zip'
)
Démarrez une invite de commande dans le répertoire contenant sample_2.py
et setup.py
,
py -3.X -m setup py2exe
Ensuite, je pense qu'un dossier dist
sera créé dans le dossier, alors mettez-y le fichier .ico
(ou placez-le à l'emplacement du chemin de description) et vous avez terminé!
Créez également un raccourci pour .exe
et placez-le sur votre bureau!
En plus de ce qui précède, j'ai appris à utiliser Threading pour gérer le traitement des événements fastidieux dans un thread séparé. Il n'acceptera pas d'entrée tant que le traitement ne sera pas terminé, et l'application sera gelée lol
Recommended Posts