Kivy,使用函数并将随机信息获取到文本输入和随机图像?

Kivy, using functions and getting random info to textinput and random image?

我想我找不到解决方案了。我不知道 .kv 页面的功能是如何工作的。 我的示例代码如下。问题是当我点击 "Good Luck" 按钮时出现错误,例如 "AttributeError: 'Button' object has no attribute 'app'" 我尝试将我的功能行替换到不同的地方,例如 class 下,但不断出现不同的错误,我是不是遗漏了什么显而易见还是我的整个方法都是错误的?

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()

My.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()

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

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()

这应该有效。如果不行,我会告诉你一个困难的方法。