ObjectProperty没有属性(Kivy, Python 3.x)
ObjectProperty has no attribute (Kivy, Python 3.x)
这个问题经常被问到和回答,但我仍然无法让它工作。我想访问一个作为另一个小部件的子部件的小部件。为此,我使用了一个 ObjectProperty。当我尝试访问 ObjectProperty(通过 FileChooser 弹出窗口打开任何文件)以更改标签的文本时,出现此错误:
self.pdfpages.text = "change to this" AttributeError:
'kivy.properties.ObjectProperty' object has no attribute 'text'
我需要初始化 ObjectProperty 吗?还是我的.kv结构有问题?
main.py
import kivy
kivy.require('1.10.0') # replace with your current kivy version !
# Kivy Imports
from kivy.app import App
#UI Eleemnts
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.popup import Popup
from kivy.uix.scrollview import ScrollView
from kivy.uix.scatter import Scatter
from kivy.uix.image import Image
#Core Elements
from kivy.core.image import Image as CoreImage
from kivy.properties import ObjectProperty
# Python Imports
import os
class Window(BoxLayout):
#add child widgets (in kv file)
pass
class PDFView(ScrollView):
pdfpages = ObjectProperty()
def newPage(self, filepath):
#here the error occurs
self.pdfpages.text = "change to this"
class SideBar(BoxLayout):
def openfile(self):
print("Button pressed")
OpenDialog().open()
class OpenDialog(Popup):
def cancelfile(self):
#close popup
self.dismiss()
print("No file opened")
def openfile(self, path, selection):
#selection can contain multiple files, [0] is first or only
self.dismiss()
print("Opened File: " + os.path.join(path, selection[0]))
#open PDFView class
PDFView.newPage(PDFView, os.path.join(path, selection[0]))
class PDFEditor(App):
title = "PDFEditor"
#gets called on startup
#load program
def build(self):
#return root node
return Window()
if __name__ == '__main__':
PDFEditor().run()
PDFEditor.kv
<Window>:
#this is the main (root) "window"
orientation: "horizontal"
SideBar:
size_hint: (.1, 1)
PDFView:
size_hint: (.9, 1)
<PDFView>:
#handler for ObjectProperty
pdfpages: pdfpages
Scatter:
#only zoom
BoxLayout:
#add Images in here somehow
orientation: "vertical"
Label:
id: pdfpages
text: "hi"
<SideBar>:
orientation: "vertical"
Button:
id: btn_openfile
on_release: root.openfile()
text: "Open File"
Label:
text: "Hello!"
<OpenDialog>:
title: "Choose File"
BoxLayout:
#Fullscreen
size: root.size
pos: root.pos
orientation: "vertical"
FileChooserListView:
id: chsr_open
BoxLayout:
size_hint_y: None
height: 30
Button:
text: "Cancel"
on_release: root.cancelfile()
Button:
text: "Open"
on_release: root.openfile(chsr_open.path, chsr_open.selection)
将您的 openfile
方法更改为:
def openfile(self, path, selection):
#selection can contain multiple files, [0] is first or only
self.dismiss()
print("Opened File: " + os.path.join(path, selection[0]))
#open PDFView class
PDFView().newPage(PDFView, os.path.join(path, selection[0]))
PDFView
是class,PDFView()
是这个class的实例,你需要什么
编辑
标签不会改变,因为您正在创建一个新标签而不替换它。因此,如果我理解得很好,您想要的只是替换 PDFView 的文本。有很多方法可以做到这一点,但我不想编辑太多你的代码:试试这个:
...
class OpenDialog(Popup):
...
def openfile(self, path, selection):
#selection can contain multiple files, [0] is first or only
self.dismiss()
print("Opened File: " + os.path.join(path, selection[0]))
#open PDFView class
app.window.ids.pdfview.newPage(PDFView, os.path.join(path, selection[0]))
...
...
class PDFEditor(App):
...
def build(self):
#return root node
self.window = Window()
return self.window
app = PDFEditor()
if __name__ == '__main__':
app.run()
在你的 kv 中:
...
<Window>:
#this is the main (root) "window"
orientation: "horizontal"
SideBar:
size_hint: (.1, 1)
PDFView:
id: pdfview
size_hint: (.9, 1)
...
这里的问题是你设置了一个新实例的文本,它甚至不在 window 上,而不是你已经拥有的那个。
要解决此问题,您需要访问您拥有的那个。
首先,将您的 Window
设为 App
属性,以便稍后引用。
class PDFEditor(App):
title = "PDFEditor"
def build(self):
self.root = Window()
return self.root
然后在kv
中给PDFView
一个id
<Window>:
orientation: "horizontal"
SideBar:
size_hint: (.1, 1)
PDFView:
id: pdfview
size_hint: (.9, 1)
然后在你的 openfile
方法中,你可以得到你之前创建的 运行 apps root
属性,就像这样。
def openfile(self, path, selection):
self.dismiss()
print("Opened File: " + os.path.join(path, selection[0]))
app = App.get_running_app()
pdf = app.root.ids.pdfview
pdf.newPage(os.path.join(path, selection[0]))
这样您就可以访问 Window
class
的 ids
这个问题经常被问到和回答,但我仍然无法让它工作。我想访问一个作为另一个小部件的子部件的小部件。为此,我使用了一个 ObjectProperty。当我尝试访问 ObjectProperty(通过 FileChooser 弹出窗口打开任何文件)以更改标签的文本时,出现此错误:
self.pdfpages.text = "change to this" AttributeError: 'kivy.properties.ObjectProperty' object has no attribute 'text'
我需要初始化 ObjectProperty 吗?还是我的.kv结构有问题?
main.py
import kivy
kivy.require('1.10.0') # replace with your current kivy version !
# Kivy Imports
from kivy.app import App
#UI Eleemnts
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.popup import Popup
from kivy.uix.scrollview import ScrollView
from kivy.uix.scatter import Scatter
from kivy.uix.image import Image
#Core Elements
from kivy.core.image import Image as CoreImage
from kivy.properties import ObjectProperty
# Python Imports
import os
class Window(BoxLayout):
#add child widgets (in kv file)
pass
class PDFView(ScrollView):
pdfpages = ObjectProperty()
def newPage(self, filepath):
#here the error occurs
self.pdfpages.text = "change to this"
class SideBar(BoxLayout):
def openfile(self):
print("Button pressed")
OpenDialog().open()
class OpenDialog(Popup):
def cancelfile(self):
#close popup
self.dismiss()
print("No file opened")
def openfile(self, path, selection):
#selection can contain multiple files, [0] is first or only
self.dismiss()
print("Opened File: " + os.path.join(path, selection[0]))
#open PDFView class
PDFView.newPage(PDFView, os.path.join(path, selection[0]))
class PDFEditor(App):
title = "PDFEditor"
#gets called on startup
#load program
def build(self):
#return root node
return Window()
if __name__ == '__main__':
PDFEditor().run()
PDFEditor.kv
<Window>:
#this is the main (root) "window"
orientation: "horizontal"
SideBar:
size_hint: (.1, 1)
PDFView:
size_hint: (.9, 1)
<PDFView>:
#handler for ObjectProperty
pdfpages: pdfpages
Scatter:
#only zoom
BoxLayout:
#add Images in here somehow
orientation: "vertical"
Label:
id: pdfpages
text: "hi"
<SideBar>:
orientation: "vertical"
Button:
id: btn_openfile
on_release: root.openfile()
text: "Open File"
Label:
text: "Hello!"
<OpenDialog>:
title: "Choose File"
BoxLayout:
#Fullscreen
size: root.size
pos: root.pos
orientation: "vertical"
FileChooserListView:
id: chsr_open
BoxLayout:
size_hint_y: None
height: 30
Button:
text: "Cancel"
on_release: root.cancelfile()
Button:
text: "Open"
on_release: root.openfile(chsr_open.path, chsr_open.selection)
将您的 openfile
方法更改为:
def openfile(self, path, selection):
#selection can contain multiple files, [0] is first or only
self.dismiss()
print("Opened File: " + os.path.join(path, selection[0]))
#open PDFView class
PDFView().newPage(PDFView, os.path.join(path, selection[0]))
PDFView
是class,PDFView()
是这个class的实例,你需要什么
编辑
标签不会改变,因为您正在创建一个新标签而不替换它。因此,如果我理解得很好,您想要的只是替换 PDFView 的文本。有很多方法可以做到这一点,但我不想编辑太多你的代码:试试这个:
...
class OpenDialog(Popup):
...
def openfile(self, path, selection):
#selection can contain multiple files, [0] is first or only
self.dismiss()
print("Opened File: " + os.path.join(path, selection[0]))
#open PDFView class
app.window.ids.pdfview.newPage(PDFView, os.path.join(path, selection[0]))
...
...
class PDFEditor(App):
...
def build(self):
#return root node
self.window = Window()
return self.window
app = PDFEditor()
if __name__ == '__main__':
app.run()
在你的 kv 中:
...
<Window>:
#this is the main (root) "window"
orientation: "horizontal"
SideBar:
size_hint: (.1, 1)
PDFView:
id: pdfview
size_hint: (.9, 1)
...
这里的问题是你设置了一个新实例的文本,它甚至不在 window 上,而不是你已经拥有的那个。
要解决此问题,您需要访问您拥有的那个。
首先,将您的 Window
设为 App
属性,以便稍后引用。
class PDFEditor(App):
title = "PDFEditor"
def build(self):
self.root = Window()
return self.root
然后在kv
中给PDFView
一个id
<Window>:
orientation: "horizontal"
SideBar:
size_hint: (.1, 1)
PDFView:
id: pdfview
size_hint: (.9, 1)
然后在你的 openfile
方法中,你可以得到你之前创建的 运行 apps root
属性,就像这样。
def openfile(self, path, selection):
self.dismiss()
print("Opened File: " + os.path.join(path, selection[0]))
app = App.get_running_app()
pdf = app.root.ids.pdfview
pdf.newPage(os.path.join(path, selection[0]))
这样您就可以访问 Window
class
ids