我对Python和Kivy还是很陌生,想创建一个简单的代码编辑器。我尝试使用Kivy(.kv)文件制作一个好的原型:
<Label>:
font_name:'Fura Code Retina Nerd Font Complete.otf'
font_size:'18sp'
<GridLayout>:
cols:3
rows:1
Label:
text:"Bars"
size_hint_x: None
width: 50
Label:
canvas.before:
Color:
rgb:0.085,0.095,0.085
Rectangle:
pos: self.pos
size: self.size
text:"Bars-result"
size_hint_x: None
width: 170
ScrollView:
TextInput:
font_size: '18sp'
cursor_color: [255,255,255,1]
background_color: (.17, .18, .17, 1)
foreground_color:[255,255,255,1]
font_name: 'Fura Code Retina Nerd Font Complete.otf'
selection_color: (1,1,1,0.125)
您可能已经发现,如果垂直超出框,则可以向后滚动(但是没有实际的滚动条)。但是,在水平方向执行此操作不会发生相同的情况,实际上,我们转到下一行。我想使其在x和y轴上均可滚动,并同时具有滚动条。
感谢您的任何帮助,如果可能的话,文档帮助也会有所帮助(但是,我很快就与Kivy的文档大声混为一谈)
答案 0 :(得分:0)
您需要根据TextInput
中文本行的长度来调整其宽度。不幸的是,没有简单的方法可以动态调整TextInput
小部件的宽度。这是我认为可以解决的问题。请注意,这使用了TextInput
的内部结构,因此如果TextInput
代码在将来的版本中进行更改,则可能会中断:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.gridlayout import GridLayout
Builder.load_string('''
<Label>:
font_name:'Fura Code Retina Nerd Font Complete.otf'
font_size:'18sp'
<GridLayout>:
cols:3
rows:1
Label:
text:"Bars"
size_hint_x: None
width: 50
Label:
canvas.before:
Color:
rgb:0.085,0.095,0.085
Rectangle:
pos: self.pos
size: self.size
text:"Bars-result"
size_hint_x: None
width: 170
ScrollView:
id:scroller
TextInput:
id: ti
size_hint: (None, None)
width: scroller.width
height: max(self.minimum_height, scroller.height)
font_size: '18sp'
cursor_color: [255,255,255,1]
background_color: (.17, .18, .17, 1)
foreground_color:[255,255,255,1]
font_name: 'Fura Code Retina Nerd Font Complete.otf'
selection_color: (1,1,1,0.125)
on_text: app.text_changed()
''')
class ScrollBothApp(App):
def build(self):
self.grid = GridLayout()
return self.grid
def text_changed(self, *args):
width_calc = self.grid.ids.scroller.width
for line_label in self.grid.ids.ti._lines_labels:
width_calc = max(width_calc, line_label.width + 20) # add 20 to avoid automatically creating a new line
self.grid.ids.ti.width = width_calc
ScrollBothApp().run()
答案 1 :(得分:0)
这是一个简化且略有改进的工作解决方案。关键区别是
<TextInputScrolling>:
textInput: txt_input
textOutput: txt_output
scroller: scroll_view
orientation: 'vertical'
BoxLayout:
orientation: 'vertical'
canvas.before:
Rectangle:
pos: self.pos
size: self.size
BoxLayout:
orientation: 'vertical'
size_hint_y: None
height: "56dp"
canvas.before:
Color:
rgb: [0,0,0]
Rectangle:
pos: self.pos
size: self.size
TextInput:
id: txt_input
focus: True
multiline: False
on_text_validate: root.submitRequest() # ENTER triggers root.submitRequest()
GridLayout:
cols: 2
ScrollView:
id: scroll_view
do_scroll_y: False # limiting to horizontal scrolling
effect_cls: "ScrollEffect" # prevents overscrolling
size_hint_x: 3
TextInput:
id: txt_output
size_hint: (None, None) # warning: if not there, scrolling not working !
width: scroll_view.width
cursor_color: [255,255,255,1]
background_color: (.17, .18, .17, 1)
foreground_color:[255,255,255,1]
selection_color: (1,1,1,0.125)
multiline: False
read_only: True
on_text: root.text_changed()
Button:
id: clear_output_Button
text: 'Clear'
size_hint_x: 1
width: 130
on_press: root.clearAll()
from kivy.app import App
from kivy.config import Config
from kivy.properties import ObjectProperty
from kivy.uix.boxlayout import BoxLayout
class TextInputScrolling(BoxLayout):
textInput = ObjectProperty()
scroller = ObjectProperty()
textOutput = ObjectProperty()
def submitRequest(self):
self.textOutput.text = self.textInput.text
def text_changed(self, *args):
width_calc = self.scroller.width
for line_label in self.textOutput._lines_labels:
width_calc = max(width_calc, line_label.width + 20) # add 20 to avoid automatically creating a new line
self.textOutput.width = width_calc
def clearAll(self):
self.textInput.text = ''
self.textOutput.text = ''
class TextInputScrollingApp(App):
def build(self):
Config.set('graphics', 'width', '200')
Config.set('graphics', 'height', '60')
Config.write()
self.gui = TextInputScrolling()
return self.gui
TextInputScrollingApp().run()