Python3 и Tkinter - невозможно выделить c 27 байт - PullRequest
5 голосов
/ 17 июня 2020

в части моего кода, мой скрипт генерирует строку, чтобы скопировать ее в виджет прокрученного текста. если размер строки не такой большой, этот процесс работает без каких-либо проблем, но когда строка тяжелая, сценарий не может вставить ее в виджет с прокруткой текста. когда это происходит, скрипт падает, и в терминале появляется сообщение об ошибке: unable to alloc 27 bytes (это не исключительное событие).

до cra sh, я получил размер строки в байтах через sys.getsizeof, и это было 230031360 байт (230 МБ).

в этих случаях пользователь может решить проблему, выбрав запись выходного сообщения в текстовый файл, но что делать, если пользователь пытается все равно писать толстую строку в виджете прокрученного текста? В этом конкретном случае c я бы очень хотел показать окно сообщения, чтобы посоветовать пользователю записать вывод в текстовый файл, но как я могу понять, может ли сценарий записывать строку в виджет с прокруткой текста или нет? каков лимит байтов строки в Python?

UPDATE:

Я написал пример, чтобы показать вам, где возникает проблема. главное окно будет сканировать sh через две минуты с сообщением об ошибке в терминале, unable to alloc 28 bytes:

from tkinter import *
from tkinter import ttk, scrolledtext
import ipaddress

def GiveMeHosts():
    ls = []
    for host in ipaddress.ip_network("10.0.0.0/8").hosts():
        ls.append(str(host))
    return ls

parent = Tk()
parent.geometry("400x350")
parent.title("The window will crash..")

MyWidget=scrolledtext.ScrolledText(parent, wrap=WORD, width=36, height=14, font=("Segoe UI", 9), state="normal")
MyWidget.pack()

parent.update()

# the string "hosts" is too long, and "MyWidget" can't manage it!
hosts = "\n".join(GiveMeHosts())
MyWidget.insert("1.0", hosts) # it makes the script to crash

parent.mainloop()

1 Ответ

0 голосов
/ 27 июня 2020

Я запустил ваш код, и, хотя это заняло довольно много времени, он, наконец, поместил все IP-адреса в прокручиваемое текстовое поле. Никаких ошибок и сбоев. Кстати: unable to alloc 28 bytes, это как раз размер последних двух ip-адресов?!? (10.255.255.253 10.255.255.254).

Я пошел еще дальше. Собственно два шага. Пытался запустить тот же код, но умножил возвращаемое значение ls *= 5. По-прежнему действительные результаты, сбоев нет. Между тем ls имеет размер 1790312344 bytes (1.67 GB).

На ls *=10, однако ls теперь имеет размер 2545286976 bytes (2.37 GB), наконец, он сделал cra sh со следующей трассировкой:

Traceback (most recent call last):
  File "F:\pybin\StackOverflow\so.py", line 28, in <module>
    MyWidget.insert("1.0", hosts) # it makes the script to crash
  File "C:\Program Files\Python36\lib\tkinter\__init__.py", line 3266, in insert
    self.tk.call((self._w, 'insert', index, chars) + args)
OverflowError: string is too long

В целом кажется, что предел действительно существует, но он вполне может зависеть от системы. По крайней мере, это то, что я делаю из этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...