Так что это часть моего кода, и теоретически он должен работать хорошо, потому что я не мог воспроизвести проблему где-либо еще.
Проблема в том, что, хотя print(string)
работает очень хорошо и печатает по порядку, когда я пытаюсь создать интерфейс kivy и вместо этого распечатывать результаты на textbox
, интерфейс работает какое-то время, затем все тормозит, а затем Window сообщает мне, что программа не отвечает. Но если я посмотрю на print
результаты, они работают нормально.
Также, когда я жду завершения программы, когда она завершается, она выводит весь текст в одну большую кучу, а затем завершает свою работу.
Итак, есть ли способ заставить textbox
распечатать результаты в том же порядке, в каком будет работать обычный print
?
ex)
обычная печать: print('hello')
печать текстового поля: self.work.text += '\nhello'
P.S. Если вам нужно знать функции, которые используются в этом коде, спросите
Код Python
import kivy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.core.window import Window
from kivy.uix.togglebutton import ToggleButton
Window.clearcolor = (1, 1, 1, 1)
from kivy.uix.popup import Popup
from datetime import date
import requests
from bs4 import BeautifulSoup
import sys
import urllib.request
import urllib.parse
import re
import os
import time
from pytube import YouTube
from pydub import AudioSegment
AudioSegment.converter = "/FFmpeg/bin/ffmpeg.exe"
import eyed3
############################### functions #########################################
just some functions that work
################################################################################################################
class MyGrid(Widget):
# url = ObjectProperty(None)
# mod = ObjectProperty(None)
# submit = ObjectProperty(None)
def submit(self):
self.work.text='starting...'
if self.mod.state=='down':
info=get_name_list(self.url.text,'single')
print(info)
self.high_audio(info)
if self.mod.state=='normal':
info=get_name_list(self.url.text,'playlist')
print(info)
self.high_audio(info)
def high_audio(self,song_album_artist_list):
for item in song_album_artist_list:
song = str(item[0])
artist_name = str(item[1])
album = str(item[2])
print(song+" : "+artist_name+" : "+album)
self.work.text += song+" : "+artist_name+" : "+album
print('............................')
youtube_url=get_top_url(song,artist_name)
# print(youtube_url)
download_high_audio(youtube_url,song)
convert(youtube_url,song)
self.work.text += 'converting finished, applying metadata...'
song_file = eyed3.load(output_path+"/"+song+".mp3")
song_file.tag.artist = artist_name
song_file.tag.album = album
self.work.text += 'searching music...'
art=get_music_inf(song,artist_name,album)
if art=='':
art=get_album_art_high(song,artist_name,album)
if art=='':
art=get_album_art_low(song,artist_name,album)
if art=='':
self.work.text += '****************************No artwork availiable****************************'
self.work.text+=art
try:
response = requests.get(art)
imagedata = response.content
song_file.tag.images.set(3,imagedata,"image/png",u"None")
song_file.tag.save()
except requests.exceptions.MissingSchema:
pass
song_file.tag.save()
self.work.text+='done'
class MyApp(App):
def build(self):
return MyGrid()
if __name__ == "__main__":
MyApp().run()
Код Киви
<RoundButton@Button>:
background_color: 0,0,0,0
canvas.before:
Color:
rgba: (.7,.7,.7,0.7) if self.state=='normal' else (0.82,0.96,0.92,1)
RoundedRectangle:
pos: self.pos
size: self.size
radius: [10,]
<RoundToggleButton@ToggleButton>:
background_color: 0,0,0,0
canvas.before:
Color:
rgba: (.7,.7,.7,0.7) if self.state=='normal' else (0.82,0.96,0.92,1)
RoundedRectangle:
pos: self.pos
size: self.size
radius: [10,]
<MyTextInput@TextInput>:
background_normal: "textinput.png"
background_color: (0.82,0.96,0.92,1) if self.focus else (1,1,1,0.5)
<MyGrid>:
url:url
mod:mod
work:work
FloatLayout:
size: root.width, root.height
MyTextInput:
id: url
pos_hint: {"x": 0.25, "top":0.85}
size_hint: 0.5,0.1
text:"Paste url"
RoundButton:
text: "submit"
on_press: root.submit()
pos_hint: {"x":0.4, "top":0.7}
size_hint: 0.2,0.1
RoundToggleButton:
id: mod
text: 'Playlist' if self.state=='normal' else 'Single'
pos_hint: {"x":0.4, "top":0.45}
size_hint: 0.2,0.1
MyTextInput:
id:work
text:''
pos_hint: {"x": 0.25,"top":0.3}
size_hint: 0.5,0.25
Подскажите, пожалуйста, в чем проблема? Я потратил почти день, пытаясь понять это :(
Button
press - одно из таких событий, поэтому ваши методыsubmit()
иhigh_audio()
запускаются в основном потоке. Если эти методы не возвращаются быстро, то графический интерфейс не может быть обновлен (потому что цикл зависает при выполнении вашего кода). Лучшим подходом может быть запуск методаsubmit()
в другом потоке и использованиеClock.schedule_once()
для обновленияMyTextInput
. - person John Anderson   schedule 30.04.2020submit
в основном потоке и создаю новый поток каждый раз, когда хочу напечатать что-то, что добавляет текст в текстовое поле? это сработает? - person Andy_ye   schedule 01.05.2020TextInput
должны выполняться в основном потоке, и все, что связывает основной поток для другой обработки, может привести к тому, что ваш графический интерфейс перестанет отвечать. - person John Anderson   schedule 01.05.2020