TypeError: Невозможно неявно преобразовать объект 'Entry' в str - PullRequest
0 голосов
/ 07 июля 2019

Я пытаюсь сделать небольшое простое приложение, которое шифровало бы текст.Я не могу понять, что не так.

сначала он все-таки работал, но при нажатии кнопки Encrypt выдает ошибку, сообщающую, что ключ и имя файла не определены.

#!/usr/bin/python

import os
from Crypto.Cipher import AES
from Crypto.Hash import SHA256
from Crypto import Random
from appJar import gui
import datetime
import csv

def encrypt(key, filename):
    chunksize = 64*1024
    outputFile = "(encrypted)"+filename
    filesize = str(os.path.getsize(filename)).zfill(16)
    IV = Random.new().read(16)

    encryptor = AES.new(key, AES.MODE_CBC, IV)

    with open(filename, 'rb') as infile:
        with open(outputFile, 'wb') as outfile:
            outfile.write(filesize.encode('utf-8'))
            outfile.write(IV)

            while True:
                chunk = infile.read(chunksize)

                if len(chunk) == 0:
                    break
                elif len(chunk) % 16 != 0:
                    chunk += b' ' * (16 - (len(chunk) % 16))

                outfile.write(encryptor.encrypt(chunk))

with gui('Encryption App', '400x200', font={'size':18}) as app:
    app.label('Simple encryption app')
    app.entry('Type text to encrypt: ', label=True, focus=True)
    filename = app.entry('Save as: ',label=True)
    key = app.entry("Password", label=True, secret=True)
    app.buttons(['Encrypt', 'Cancel'], [encrypt(app.entry('Save as: '),app.entry('Password: ')), app.stop])

Когдапобежал, выдает сообщение об ошибке:

2019-07-07 17:40:44,862 appJar:ERROR [Line 40->1784/__exit__]: ContextManager failed: Can't convert 'Entry' object to str implicitly
Traceback (most recent call last):
  File "/home/skyandstars/Desktop/new_score.py", line 40, in <module>
    app.buttons(['Encrypt', 'Cancel'], [encrypt(app.entry('Save as: '),app.entry('Password: ')), app.stop])
  File "/home/skyandstars/Desktop/new_score.py", line 14, in encrypt
    outputFile = "(encrypted)"+filename
TypeError: Can't convert 'Entry' object to str implicitly

1 Ответ

0 голосов
/ 07 июля 2019

Я проверил это

def encrypt(key, filename):
    print(filename, type(filename))

и это показывает, что filename это tkinter.Entry, а не строка, поэтому вы не можете добавить строку и Entry в

"(encrypted)"+filename

Чтобы получить строку из Entry, вы должны использовать filename.get() во всех местах

outputFile = "(encrypted)" + filename.get()

filesize = str(os.path.getsize( filename.get() )).zfill(16)

Или вы можете сделать это в начале функции encrypt

filename = filename.get()

У вас та же проблема с key


РЕДАКТИРОВАТЬ: когда я запускаю код, я вижу другую распространенную ошибку от tkinter.

Кнопка требует обратного вызова - это означает, что имя функции без () и без аргументов - как app.stop - но вы используете encrypt(..). Он запускает encrypt(..) при запуске и назначает None кнопке, потому что entry(..) возвращает None.

Вы можете использовать lambda, чтобы создать функцию без аргументов и назначить ее без ()

new_function = lambda:encrypt(app.entry('Save as: '), app.entry('Password: '))

[new_function, app.stop]

или напрямую

[lambda:encrypt(app.entry('Save as: '), app.entry('Password: ')), app.stop]

РЕДАКТИРОВАТЬ: еще одна ошибка. Вы создаете два раза записи entry('Save as: ') entry('Password: '). Одна пара будет отображаться, и вы положите текст в них. Вторая пара, которую вы создаете в

[lambda:encrypt(app.entry('Save as: '), app.entry('Password: ')), app.stop]

но они пусты при нажатии кнопки, поэтому вы получаете пустую строку в функции.

Вы должны использовать только одну пару

filename = app.entry('Save as: ', label=True)
key = app.entry("Password", label=True, secret=True)

app.buttons(['Encrypt', 'Cancel'], [lambda:encrypt(key, filename), app.stop])

Вы даже можете использовать get() в этом месте вместо использования внутри encrypt

filename = app.entry('Save as: ', label=True)
key = app.entry("Password", label=True, secret=True)

app.buttons(['Encrypt', 'Cancel'], [lambda:encrypt(key.get(), filename.get()), app.stop])

Полный код

#!/usr/bin/python

import os
from Crypto.Cipher import AES
from Crypto.Hash import SHA256
from Crypto import Random
from appJar import gui
import datetime
import csv

def encrypt(key, filename):

    chunksize = 64*1024

    outputFile = "(encrypted)" + filename
    filesize = str(os.path.getsize(filename)).zfill(16)
    IV = Random.new().read(16)

    encryptor = AES.new(key, AES.MODE_CBC, IV)

    with open(filename, 'rb') as infile:
        with open(outputFile, 'wb') as outfile:
            outfile.write(filesize.encode('utf-8'))
            outfile.write(IV)

            while True:
                chunk = infile.read(chunksize)

                if len(chunk) == 0:
                    break
                elif len(chunk) % 16 != 0:
                    chunk += b' ' * (16 - (len(chunk) % 16))

                outfile.write(encryptor.encrypt(chunk))

with gui('Encryption App', '400x200', font={'size':18}) as app:
    app.label('Simple encryption app')
    app.entry('Type text to encrypt: ', label=True, focus=True)

    filename = app.entry('Save as: ', label=True)
    key = app.entry("Password", label=True, secret=True)
    func = lambda:encrypt(key.get(), filename.get())

    app.buttons(['Encrypt', 'Cancel'], [func, app.stop])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...