Python → Tkinter + PyInstaller. Решение проблемы с кодировкой.
При изучении Tkinter столкнулся с досадной проблемой. Если собрать программу в exe с помощью PyInstaller , то в полях ввода текста вместо кириллицы вводится абракадабра в стиле «. «, хотя текст, заданный из самой программы (Label, Button и т.п.), выглядит нормально. Причём исходный py-скрипт работает адекватно.
Перерыв кучу интернет-ресурсов, испробовал несколько приёмов решения проблемы с кодировкой, но ни один из них не сработал. Так как мой проект уже разросся до солидных размеров, а менять Tkinter на другой GUI мне очень не хотелось, я принялся за поиск решения.
В результате многочисленных проб и ошибок родился этот довольно грязный хак, который, однако, вполне справляется с поставленной задачей.
#!/usr/bin/python # -*- coding: utf-8 -*- from Tkinter import * class FormatStringVar(StringVar): def __init__(self, root): StringVar.__init__(self) self.root = root # Устанавливаем callback-функцию. Она будет выполняться # каждый раз при изменении значения переменной self.trace_variable(«w», self.callback) # CHARMAP # Составляем словарь необходимых символов _CHR = u»АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя» self._CHARMAP = dict() # от ‘А’ до ‘Я’ (192-223) и от ‘а’ до ‘я’ (224-255) i = 192 for c in _CHR: self._CHARMAP[i] = c i += 1 # Остальные символы, включая украинские self._CHARMAP[168] = u»Ё» self._CHARMAP[184] = u»ё» self._CHARMAP[178] = u»І» self._CHARMAP[179] = u»і» self._CHARMAP[175] = u»Ї» self._CHARMAP[191] = u»ї» self._CHARMAP[170] = u»Є» self._CHARMAP[186] = u»є» self._CHARMAP[165] = u»Ґ» self._CHARMAP[180] = u»ґ» # callback-функция def callback(self, name, index, mode): # получаем значение переменной old = self.root.globalgetvar(name) new = u»» # для каждого символа в строке for i in old: # если символ входит в словарь if ord(i[-1]) in self._CHARMAP: # заменяем на правильное значение new += self._CHARMAP[ord(i[-1])] # если символа нет в словаре else: # оставляем символ new += i # записываем результат обратно в переменную self.root.globalsetvar(name, new) # инициализируем Tkinter root = Tk() # устанавливаем в Tkinter кодировку UTF-8 root.tk.call(‘encoding’, ‘system’, ‘utf-8’) mainframe = Frame(root) mainframe.pack() # Инициализируем нашу переменную entry_var = FormatStringVar(root) # Привязываем переменную к полю ввода Entry entry = Entry(mainframe, textvariable=entry_var) entry.pack() # Поехали! root.mainloop()
Уж сколько лет назад UTF-8 появился, а досихпор косяки всплывают… :-/
Не знаю может у кого-то что-то иполучилось так. Но я пошел другим путем.
PyInstaller Ошибки. Детальный разбор
Не буду долго рассказывать… просто при упаковке pyinstaller не добавляет папку C:Python26tcltcl8.5encoding. это можно заметить если запустить прогу и залесть в C:temp_MEI7202_MEItcl8.5, там нет папки encoding. Я просто кинул туда папку encoding и прога сразу подхватира кодеки. Дальше я подумал что гдето эксклюдится эта папка и нашел что это происходит в скрипте Build.py pyinstaller-a там есть такие строки
Компиляция Python в EXE? | Nuitka, Pyinstaller, InnoSetup
#tcltree = Tree(tclroot, tclnm, excludes=[‘demos’,’encoding’,’*.lib’]) #tktree = Tree(tkroot, tknm, excludes=[‘demos’,’encoding’,’*.lib’])
я их заменил на
tcltree = Tree(tclroot, tclnm, excludes=[‘demos’,’*.lib’]) tktree = Tree(tkroot, tknm, excludes=[‘demos’,’*.lib’])
и все… папка encoding пакуется — кирилица вводится.
Но все равно спасибо за этот класс некоторые вещи я не знал… видимо по тому что не надо было 🙂
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.
Прямой эфир
- Комментарии
- Публикации
- fog → Блог им. OGGSmith → Главная проблема открытого ПО нерешаема 5
- fog → Взаимоотношения → Dr.WEB: Вопросы вознаграждения и сообщества 2
- vit1251 → Блог им. fog → Разработчики бегут от Microsoft? 9
- vit1251 → GNU/Linux → Почему люди не используют Linux? 2
- saamich → GNU/Linux → 2015 — год Linux в Smart-устройствах? 3
- deemonizer → Офисные пакеты → Пособие: Оформление дипломной работы в LibreOffice (3-издание) 12
- Procion → Бизнес Open Source → Сооснователь WhatsApp отдал $1000000 на СПО 1
- Procion → GNU/Linux → Леннарт Поттеринг о вражде в сообществе разработчиков СПО 1
- Ghaydn → Блог им. Ghaydn → Звук. Нативные DAW под GNU/Linux (часть 2) 2
- semiletov → Блог им. semiletov → звуковой редактор EKO 1.0.0. 2
Источник: open-life.org
pyinstaller
Вы используете устаревший браузер. Этот и другие сайты могут отображаться в нем неправильно.
Необходимо обновить браузер или попробовать использовать другой.
Валентин
Пользователь
Ноя 13, 2020 113 0 16
после компиляции, когда открываешь ЕХЕшник, он запускается и сразу закрывается. Незнаю что сделать чтобы он работал.
Спойлер: pip list
import pyautogui
import time
import pyautogui import time number = int(input(‘Enter the number of messages: ‘)) text = input(‘Enter messages: ‘) print(«Go to the window and click where to enter. «) time.sleep(7) for i in range(1, number): pyautogui.write(text) pyautogui.press(«enter»)
regnor
Модератор
Команда форума
Модератор
Июл 7, 2020 2 419 429 83
не хватает библиотек скорее всего, где запускаете exe установите pyautogui через командную строку, pip install pyautogui, и все заработает.
и pyinstaller не компилирует, а упаковывает.
Валентин
Пользователь
Ноя 13, 2020 113 0 16
не хватает библиотек скорее всего, где запускаете exe установите pyautogui через командную строку, pip install pyautogui, и все заработает.
и pyinstaller не компилирует, а упаковывает.
У меня установлено 2 версии питона 3.4.0 и 3.9.0. Когда в cmd ввожу
pip install pyautogui
Устанавливается в версию 3.4.0, а не в 3.9.0 Как установить в версию 3.9.0?
VolodinAS
Пользователь
Дек 3, 2020 35 0 6 30 Россия, Тольятти volodinas.ru
У меня установлено 2 версии питона 3.4.0 и 3.9.0. Когда в cmd ввожу
pip install pyautogui
Устанавливается в версию 3.4.0, а не в 3.9.0 Как установить в версию 3.9.0?
Только что искал эту же проблему. Находил рекомендацию запустить Ваш exe через командную строку — выведутся все ошибки. Как у меня, например.
Валентин
Пользователь
Ноя 13, 2020 113 0 16
не хватает библиотек скорее всего, где запускаете exe установите pyautogui через командную строку, pip install pyautogui, и все заработает.
и pyinstaller не компилирует, а упаковывает.
Выдаёт ошибку при установке(
Валентин
Пользователь
Ноя 13, 2020 113 0 16
Выдаёт ошибку при установке(
Посмотреть вложение 913
Уже решил эту проблему, но всё равно ЕХЕшник сразу закрывается(
Валентин
Пользователь
Ноя 13, 2020 113 0 16
Только что искал эту же проблему. Находил рекомендацию запустить Ваш exe через командную строку — выведутся все ошибки. Как у меня, например. Посмотреть вложение 912
Ошибку не выдаёт, но не работает(
stud_55
Модератор
Команда форума
Модератор
Апр 3, 2020 1 522 671 113
Ошибку не выдаёт, но не работает(
Попробуйте запустить скрипт в консоли cmd.exe и посмотрите какую ошибку выдает.
Валентин
Пользователь
Ноя 13, 2020 113 0 16
Попробуйте запустить скрипт в консоли cmd.exe и посмотрите какую ошибку выдает.
Пишет что не установлен модуль PyAutoGUi. А когда устанавливаю выдает эту ошибку:
Вложения
Снимок экрана (77).png
49,7 КБ · Просмотры: 5
stud_55
Модератор
Команда форума
Модератор
Апр 3, 2020 1 522 671 113
Пишет что не установлен модуль PyAutoGUi. А когда устанавливаю выдает эту ошибку:
Судя по логам ошибки установка у вас происходит с помощью питона 3.4, а не 3.9.
Попробуйте установить pyautogui с помощью 3.9:
выполните команду where python — она покажет где находится интерпретатор
потом выберите интерпретатор версии 3.9 (например, D:\python39python.exe ) и установите pyautogui с помощью него
D:\python39python.exe -m pip install pyautogui
Валентин
Пользователь
Ноя 13, 2020 113 0 16
Судя по логам ошибки установка у вас происходит с помощью питона 3.4, а не 3.9.
Попробуйте установить pyautogui с помощью 3.9:
выполните команду where python — она покажет где находится интерпретатор
потом выберите интерпретатор версии 3.9 (например, D:\python39python.exe ) и установите pyautogui с помощью него
D:\python39python.exe -m pip install pyautogui
Всё равно при открытии закрывается.
stud_55
Модератор
Команда форума
Модератор
Апр 3, 2020 1 522 671 113
Всё равно при открытии закрывается.
После того как вы установили pyautogui для питона 3.9 нужно запустить pyinstaller из питона 3.9 чтобы сделать новый exe-файл.
После чего нужно запустить его в консоли cmd чтобы увидеть ошибки.
Валентин
Пользователь
Ноя 13, 2020 113 0 16
После того как вы установили pyautogui для питона 3.9 нужно запустить pyinstaller из питона 3.9 чтобы сделать новый exe-файл.
После чего нужно запустить его в консоли cmd чтобы увидеть ошибки.
Пишет что нет модуля pyautogui(
Вложения
Снимок экрана (85).png
41,4 КБ · Просмотры: 3
VolodinAS
Пользователь
Дек 3, 2020 35 0 6 30 Россия, Тольятти volodinas.ru
Пишет что нет модуля pyautogui(
Если модуля нет, может быть надо его сначала установить?
В командной строке:
pip install pyautogui
А лучше погуглить документацию и посмотреть. У меня Python 3.8, может не подойдет Вашей 3.9
Валентин
Пользователь
Ноя 13, 2020 113 0 16
Если модуля нет, может быть надо его сначала установить?
В командной строке:
А лучше погуглить документацию и посмотреть. У меня Python 3.8, может не подойдет Вашей 3.9
Я конечно тупой, но не настолько. Модуль я установил. И код работает, только после сборки через pyinstaller он перестаёт работать( Но на счёт версии питона посмотрю!
VolodinAS
Пользователь
Дек 3, 2020 35 0 6 30 Россия, Тольятти volodinas.ru
Я конечно тупой, но не настолько. Модуль я установил. И код работает, только после сборки через pyinstaller он перестаёт работать(
Прошу прощения, не увидел сначала.
А в pip list он высвечивается?
Валентин
Пользователь
Ноя 13, 2020 113 0 16
Прошу прощения, не увидел сначала.
А в pip list он высвечивается?
Нет, хотя писало что pyautogui успешно установлен. Попробую установить питон 3.8, может действительно заработает)
VolodinAS
Пользователь
Дек 3, 2020 35 0 6 30 Россия, Тольятти volodinas.ru
Нет, хотя писало что pyautogui успешно установлен. Попробую установить питон 3.8, может действительно заработает)
Вы в PyCharm код пишете?
Валентин
Пользователь
Ноя 13, 2020 113 0 16
Вы в PyCharm код пишете?
VolodinAS
Пользователь
Дек 3, 2020 35 0 6 30 Россия, Тольятти volodinas.ru
Зайдите в настройки (Ctrl Alt S) — Project — Project Interpreter. Посмотрите внимательно на список установленных модулей.
Если запуск Вашего проекта осуществляется через PyCharm, а он говорит, что нет какой-то библиотеки, то скорее всего, проблема в виртуальной среде. У меня такая же проблема была. Она решилась выбором существующей среды во время создания проекта:
Тогда стали совпадать модули из pip list в командной строке и PyCharm:
Конечно, я еще новичок в Python и вполне вероятно, что удобно использовать отдельные виртуальные среды. Но у меня возникало куча проблем, когда я стал использовать их. Поэтому, мне проще было, чтобы всё было в одном месте.
stud_55
Модератор
Команда форума
Модератор
Апр 3, 2020 1 522 671 113
Пишет что нет модуля pyautogui(
Чтобы сделать рабочий exe-файл нужно чтобы pyinstaller и pyautogui были установлены для одного и того же интерпретатора питона.
Попробуйте создать виртуальное окружение для нужно интерпретатора питона.
Установите в него модули pyinstaller и pyautogui.
Запустите файл скрипта (script.py) в виртуальном окружении чтобы убедиться что он работает и все необходимые для него зависимости установлены.
Запустите pyinstaller в виртуальном окружении чтобы создать exe-файл скрипта.
Запустите exe-файл в консоли чтобы убедиться что он работает.
Источник: itfy.org
Русские Блоги
Краткое описание решений проблем упаковки Pyinstaller
Здесь суммированы решения различных проблем упаковки Pyinstaller, что удобно для каждого маленького партнера.
Содержание:
1.Pyinstaller не совместим с версией Python
Такое предложение есть в первом абзаце официального сайта Pyinstaller (https://www.pyinstaller.org/):
Pyinstaller совместим с Python 2.7 и 3.3-3.6. Я вижу, что многие приятели, которые только начали изучать Python, используют Python Pyinstaller для упаковки программ Python3.7 и совершения ошибок, поэтому вам просто нужно изменить версию Python.
Конечно, это не значит, что он не будет совместим с 3.7 в будущем. Вы всегда можете обратить внимание на официальный сайт.
2. Упакованный на 64-битном компьютере не может работать на 32-битном
Упакованные в 64-разрядных системах могут работать только в 64-разрядных системах, но упакованные в 32-разрядных системах могут работать в 32-разрядных и 64-разрядных системах.
Таким образом, если exe-файл не запускается на других компьютерах, вы можете увидеть, совпадают ли цифры двух компьютеров (но это не имеет ничего общего с версией Windows, и пакет на win7 также может работать на win10).
3. На другом компьютере отсутствует chromedriver.exe, и программа не запускается
Если ваша программа использует chromedriver.exe, обратите внимание, что Pyinstaller не будет упаковывать chromedriver.exe вместе.
Поэтому, когда вы помещаете программу на другой компьютер, если на этом компьютере отсутствует программа chromedriver.exe, она может сообщить об ошибке, подобной следующей:
Сообщение об ошибке должно положить в путь chromedriver.exe.
Решение состоит в том, чтобы скопировать копию файла chromedriver.exe на другой компьютер и поместить его в тот же путь, что и упакованный exe-файл.
4.Pyinstaller упаковывает селен, чтобы удалить черный ящик, принесенный chromedriver
5. Упаковка скрапа с помощью Pyinstaller
6. Я не могу упаковать одну и ту же программу, просто упаковываю ее для других
Эта программа может использовать некоторые библиотеки, которые вы еще не установили, и соответствующие библиотеки были установлены в среде Python на компьютерах других людей.
Таким образом, вам просто нужно использовать pip для загрузки соответствующей библиотеки (общая ошибка приведет к появлению модуля Not Found: xxx и т.
7. Некоторые файлы (картинки, текстовые файлы), используемые в вашей программе, должны следовать exe
Файлы, используемые в программе, должны сопровождаться файлом exe после упаковки, в противном случае программа не сможет найти соответствующие файлы и, естественно, не сможет работать.
8. Пакет программ, использующих многопроцессорную библиотеку
Пожалуйста, смотрите код комментария ниже
import multiprocessing class SendeventProcess(multiprocessing.Process): def __init__(self, resultQueue): self.resultQueue = resultQueue multiprocessing.Process.__init__(self) self.start() def run(self): print ‘SendeventProcess’ self.resultQueue.put((1, 2)) print ‘SendeventProcess’ if __name__ == ‘__main__’: # При упаковке в Windows необходима строка multiprocessing.freeze_support () # Нет необходимости пакетировать на Linux и Mac multiprocessing.freeze_support () # Просто добавьте эту строку кода к входу вашей программы print ‘main’ resultQueue = multiprocessing.Queue() SendeventProcess(resultQueue) print ‘main’
9. Модуль PyQt5.sip не отображается при упаковке PyQt5.
До сих пор я так много думал, и буду думать о других в будущем. Вы можете оставить сообщение в разделе комментариев ниже, спасибо.
Была создана новая группа связи Python. Если вы заинтересованы, вы можете присоединиться и учиться вместе: 820934083
Источник: russianblogs.com