【问题标题】:Kivy, using functions and getting random info to textinput and random image?Kivy,使用函数并获取随机信息到文本输入和随机图像?
【发布时间】:2020-02-17 15:56:39
【问题描述】:

我想我迷失了解决方案。我不明白 .kv 页面的功能是如何工作的。 我的示例代码如下。问题是当我单击“Good Luck”按钮时出现错误,例如“AttributeError: 'Button' object has no attribute 'app'”我错过了一些明显的东西还是我的整个方式都错了?

main.py

# -*- coding: utf8 -*-
from trakt.users import User
import random
import imdb
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
import kivy.app
kivy.require('1.9.1')

moviesDB = imdb.IMDb()
myuser = User(str('lunedor'))
watchlist = myuser.watchlist_movies

def dataget():
    global myline
    myline = str(random.choice(watchlist))[9:1000]
    movies = moviesDB.search_movie(str(myline))
    id = movies[0].getID()
    global movie
    movie = moviesDB.get_movie(id)
    global posterurl
    posterurl = movie["full-size cover url"]
    global title
    title = movie['title']
    global year
    year = movie["year"]
    global rating
    rating = movie["rating"]
    global runtime
    runtimes = movie["runtimes"]
    runtime = ' '.join(map(str, runtimes))
    global directStr
    directors = movie["directors"]
    directStr = ' '.join(map(str, directors))
    global writerStr
    writers = movie["writers"]
    writerStr = ', '.join(map(str, writers))
    global casting
    casting = movie["cast"]
    global actors
    actors = ', '.join(map(str, casting))
    global summary
    summary = movie["plot outline"]
    genres = movie["genres"]
    global genre
    genre = ', '.join(map(str, genres))
    print(movie)
    print(id)
    posterurl = movie["full-size cover url"]
    showline1 = title + "\n" + str(year) + " - " + str(rating) + "\n" + str(runtime) + " minutes" + " - " + genre
    showline2 = "Director: " + directStr + "\n" + "\n" + "Writers: " + writerStr
    showline3 = "Cast: " + actors
    showline4 = "Summary: " + "\n" + str(summary)


class RootWidget(GridLayout):
    def __init__(self, **kwargs):
        super(RootWidget, self).__init__(**kwargs)
    try:
        dataget()
    except:
        print('Error')
        dataget()

    posterurl = movie["full-size cover url"]
    showline1 = title + "\n" + str(year) + " - " + str(rating) + "\n" + str(runtime) + " minutes" + " - " + genre
    showline2 = "Director: " + directStr + "\n" + "\n" + "Writers: " + writerStr
    showline3 = "Cast: " + actors
    showline4 = "Summary: " + "\n" + str(summary)


class MyApp(App):
    def build(self):
        return RootWidget()

    def clk(self):
        try:
            dataget()
        except:
            print('Error')
            dataget()

    def clk2(self):
        exit()

if __name__ == '__main__':
    App=MyApp()
    App.run()

我的.kv

<RootWidget>:
    cols: 2
    rows: 1
    orientation: 'horizontal'
    GridLayout:
        cols: 1
        rows: 1
        orientation: 'horizontal'
        AsyncImage:
            id: poster
            source: root.posterurl
            nocache: True
    GridLayout:
        cols: 1
        rows: 5
        orientation: 'vertical'
        spacing: 10
        Label:
            text: root.showline1
            markup: True
            bold: True
            size: self.texture_size
            halign: 'center'
            valign: 'middle'
            id: self.lbl
        TextInput:
            text: root.showline2
            id: self.lbl2
        TextInput:
            text: root.showline3
            id: self.lbl3
            multiline: True
        TextInput:
            text: root.showline4
            id: self.lbl4
            multiline: True
        BoxLayout:
            cols: 2
            rows: 1
            spacing: 5
            padding: 50, 10, 10, 10
            size_hint_max_y: 40
            orientation: 'horizontal'
            Button:
                text: "Good Luck!"
                font_size: 14
                size_hint: None, None
                size: 95, 30
                on_press: root.app.clk()
            Button:
                text: "Exit"
                font_size: 14
                size_hint: None, None
                size: 75, 30
                on_press: root.app.clk2()

已解决的版本:

# -*- coding: utf8 -*-
from trakt.users import User
import random
import imdb
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.properties import StringProperty, ObjectProperty
import kivy.app
kivy.require('1.9.1')

moviesDB = imdb.IMDb()
myuser = User(str('lunedor'))
watchlist = myuser.watchlist_movies

def dataget():
    global myline
    myline = str(random.choice(watchlist))[9:1000]
    movies = moviesDB.search_movie(str(myline))
    id = movies[0].getID()
    global movie
    movie = moviesDB.get_movie(id)
    global posterurl
    posterurl = movie["full-size cover url"]
    global title
    title = movie['title']
    global year
    year = movie["year"]
    global rating
    rating = movie["rating"]
    global runtime
    runtimes = movie["runtimes"]
    runtime = ' '.join(map(str, runtimes))
    global directStr
    directors = movie["directors"]
    directStr = ' '.join(map(str, directors))
    global writerStr
    writers = movie["writers"]
    writerStr = ', '.join(map(str, writers))
    global casting
    casting = movie["cast"]
    global actors
    actors = ', '.join(map(str, casting))
    global summary
    summary = movie["plot outline"]
    genres = movie["genres"]
    global genre
    genre = ', '.join(map(str, genres))
    print(movie)
    print(id)


class RootWidget(GridLayout):
    def __init__(self, **kwargs):
        super(RootWidget, self).__init__(**kwargs)
    try:
        dataget()
    except:
        print('Error')
        dataget()

    posterurl = ObjectProperty()
    showline1 = StringProperty()
    showline2 = StringProperty()
    showline3 = StringProperty()
    showline4 = StringProperty()

    # make a function to be able to call it
    def update_values(self):
        self.posterurl = movie["full-size cover url"]
        self.showline1 = title + "\n" + str(year) + " - " + str(rating) + "\n" + str(runtime) + " minutes" + " - " + genre
        self.showline2 = "Director: " + directStr + "\n" + "\n" + "Writers: " + writerStr
        self.showline3 = "Cast: " + actors
        self.showline4 = "Summary: " + "\n" + str(summary)

class MyApp(App):
    def build(self):
        # you will need that object later so put in into variable
        self.rw = RootWidget()
        # call update function
        self.rw.update_values()
        return self.rw

    def clk(self):
        try:
            dataget()
            # after you get new values update the variables connected to widgets
            self.rw.update_values()
        except:
            print('Error')
            dataget()

    def clk2(self):
        exit()

if __name__ == '__main__':
    App=MyApp()
    App.run()

【问题讨论】:

    标签: python function random kivy textinput


    【解决方案1】:

    您应该使用 root 或应用程序,而不是同时使用。在您的情况下,它将是 app,因为您的功能在 App 类中:

    on_press: app.clk()
    

    当然它不会自己更新,你更新全局变量但不更新本地变量。试试这个:

    class RootWidget(GridLayout):
        def __init__(self, **kwargs):
            super(RootWidget, self).__init__(**kwargs)
        try:
            dataget()
        except:
            print('Error')
            dataget()
    
        # make a function to be able to call it
        def update_values(self):
            self.posterurl = movie["full-size cover url"]
            self.showline1 = title + "\n" + str(year) + " - " + str(rating) + "\n" + str(runtime) + " minutes" + " - " + genre
            self.showline2 = "Director: " + directStr + "\n" + "\n" + "Writers: " + writerStr
            self.showline3 = "Cast: " + actors
            self.showline4 = "Summary: " + "\n" + str(summary)
    
    class MyApp(App):
        def build(self):
            # you will need that object later so put in into variable
            self.rw = RootWidget()
            # call update function
            self.rw.update_values()
            return self.rw
    
        def clk(self):
            try:
                dataget()
                # after you get new values update the variables connected to widgets
                self.rw.update_values()
            except:
                print('Error')
                dataget()
    

    这应该可行。如果不是,我会告诉你困难的方式。

    【讨论】:

    • 是的,没错,它让我摆脱了错误消息,谢谢,现在单击按钮获取新值(我可以看到 print(movie & id) 但仍然不显示新值文本和图像。
    • 这对我来说看起来很有希望,但我尝试得到错误,例如“AttributeError: 'RootWidget' object has no attribute 'showline4'”,我试图给 showline 项目“StringProperty()”然后应用程序获取打开为空白,但即使在单击按钮后仍保持这种状态:) 我想我会遇到困难 :)
    • @Lunedor 哦,添加自我。到变量posterurl和showlines,看看我的答案,我在那里添加了它
    • 它起作用了,我只是为 posterurl 和 showlines 添加了 ObjectProperty() 和 StringProperty(),添加了 sloved 版本来提问。坦克很多,我试图弄清楚这两天..
    猜你喜欢
    • 1970-01-01
    • 2013-03-07
    • 2021-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-01
    • 1970-01-01
    相关资源
    最近更新 更多