Label keeps running off edge of ScrollView screen x axis Kivy

我怕爱的太早我们不能终老 提交于 2021-02-11 13:50:10

问题


I'm creating a chat screen, adding a Label to my GridLayout everytime the send button is pressed. However, my Labels run off the side of the screen when the text becomes too long, I would like them to wrap round and the text to go onto a new line but this isn't happening and I'm not sure why.

<ChatPage>:
    name: "chat_page"
    layout_content: layout_content

    NavigationLayout:
        id: nav_layout
        MDNavigationDrawer:
            NavigationDrawerIconButton:
                text: "Test"
                on_release: app.root.current = "login"

        FloatLayout:
            MDToolbar:
                pos_hint: {'top': 1}
                md_bg_color: 0.2, 0.6, 1, 1
                left_action_items: [['menu', lambda x: root.ids.nav_layout.toggle_nav_drawer()]]

            ScrollView:
                size_hint: 0.95, 0.6
                pos_hint: {"x": 0.025, "top" : 0.8, "bottom" : 0.5}
                do_scroll_x: False
                GridLayout:
                    id: layout_content
                    cols: 2
                    size_hint_y: None
                    spacing: 10
                    height: self.minimum_height
                    canvas:
                        Color:
                            rgba: (1, 1, 1, 1)
                        Rectangle:
                            size: self.size
                            pos: self.pos

            BoxLayout:
                TextInput:
                    id: msg
                    hint_text: "Type your message here"
                    pos_hint: {"x": 0, "top": 0.15}
                    size_hint: 0.75, 0.15
                Button:
                    text: "Send"
                    background_normal: ""
                    background_color: 0, 0.6, 0, 1
                    pos_hint: {"x": 0.75, "top": 0.15}
                    size_hint: 0.25, 0.15
                    on_release: root.btn_press()

<SmoothLabel>:
    size_hint: None, None
    size: self.texture_size
    padding: 10, 10
    multiline: True
    background_color: 0,0,0,0
    background_normal: ""
    back_color: 1,0,1,1
    border_radius: [6]
    canvas.before:
        Color:
            rgba: 0.2,0.6,1,1 #This changes the label colour
        RoundedRectangle:
            size: self.size
            pos: self.pos
            radius: self.border_radius

py file

import kivy
from kivy.app import App
from kivy.properties import ObjectProperty, StringProperty, NumericProperty, ListProperty
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.core.window import Window
from kivymd.theming import ThemeManager
import mysql.connector
from kivymd.uix.picker import MDDatePicker
from kivy.uix.scrollview import ScrollView

Window.clearcolor = (1,1,1,1)


class SmoothLabel(Label):
    pass


class ChatPage(Screen):
    layout_content = ObjectProperty(None)
    def btn_press(self):
        if self.ids.msg.text:
            lab1 = Label()
            self.layout_content.add_widget(SmoothLabel(text=self.ids.msg.text))
            self.layout_content.add_widget(lab1)
            self.ids.msg.text = ""
        else:
            pass


class WindowManager(ScreenManager):
    pass


class MyApp(App):
    theme_cls = ThemeManager()

    def build(self):
        kv = Builder.load_file("kivy.kv")
        sm = WindowManager()

        screens = [ChatPage(name="chat_page")]
        for screen in screens:
            sm.add_widget(screen)

        sm.current = "chat_page"
        return sm


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


回答1:


In your btn_press method, change:

self.layout_content.add_widget(SmoothLabel(text=self.ids.msg.text))

to:

self.layout_content.add_widget(SmoothLabel(text=self.ids.msg.text, text_size=(self.layout_content.width, None)))

Adding the text_size allows the Label to wrap at the specified width.




回答2:


I should insist that you submit your new question as a separate post. But here is another answer that handles both your questions:

Using the concept of the text_size along with calculating the SmoothLabel size with kivy.core.text.Label, a size adjusted SmoothLabel can be created.

Adding a static method to SmoothLabel:

class SmoothLabel(Label):
    @staticmethod
    def create_sized_label(**kwargs):
        max_width = kwargs.pop('max_width', 0)
        if max_width <= 0:
            # just create a SmoothLabel without a text_size
            return SmoothLabel(**kwargs)

        # calculate what the SmoothLabel size will be
        core_label = CoreLabel(padding=[10,10], **kwargs)  # use same padding as SmoothLabel
        core_label.refresh()

        if core_label.width > max_width:
            # width is too big, use text_size to force wrapping
            return SmoothLabel(text_size=(max_width,None), **kwargs)
        else:
            # width is OK, no need for text_size
            return SmoothLabel(**kwargs)

Then use that method in the ChatPage:

class ChatPage(Screen):
    layout_content = ObjectProperty(None)
    def btn_press(self):
        if self.ids.msg.text:
            lab1 = Label()

            # calculate max allowable width in the GridLayout
            max_width = self.layout_content.width - self.layout_content.spacing[0] - self.layout_content.padding[0] - self.layout_content.padding[2]

            # specify font and font_size (so that the CoreLabel uses the same)
            self.layout_content.add_widget(SmoothLabel.create_sized_label(text=self.ids.msg.text, max_width=max_width, font_name='Roboto', font_size=15))

            self.layout_content.add_widget(lab1)
            self.ids.msg.text = ""
        else:
            pass


来源:https://stackoverflow.com/questions/59696424/label-keeps-running-off-edge-of-scrollview-screen-x-axis-kivy

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!