所以这是我的代码的一部分,从理论上讲,它应该可以正常工作,因为我无法在其他任何地方重复该问题。
问题是,尽管print(string)
可以很好地工作并按顺序打印,但是当我尝试创建一个kivy界面并将结果打印到textbox
上时,该界面会工作一会儿,然后一切都会变慢然后,如果Window告诉我程序没有响应。但是,如果我查看print
结果,它们就可以正常工作。
另外,当我等待程序完成时,它会在一个大堆中吐出所有文本,然后完成。
所以有什么方法可以使textbox
以与正常print
相同的顺序打印结果?
ex)
正常打印:print('hello')
文本打印:self.work.text += '\nhello'
P.S。如果您需要了解此代码中使用的功能,请询问
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
有人可以告诉我问题是什么吗?我浪费了几乎一天的时间试图弄清楚:(
[当您运行print()
时,实际发生的是程序将文本作为字节流输出,然后其他程序(即您的终端)可以检查该流并将其显示为字符。程序做什么都不重要,因为该字节流在其控制流的其余部分外部。
当您使用gui绘制文本时,模型是不同的-设置TextInput的文本会告诉它该怎么做,但是文本的实际呈现也是程序流程的一部分。
当您一次运行大量代码时,您将阻塞该流程,因此,在您的函数开始到所有代码完成之间,没有用于更新gui的Kivy代码运行,因此该函数返回。
解决方案是不阻止gui。您可以将函数拆分为多个块,每个块都使用Clock.schedule_once
调用下一个,或者在线程中运行长时间运行的函数。