Kivy在布局的不同侧面添加小部件

2024-10-17 08:25:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个聊天应用程序,它使用一个小部件打印信息。我想把这些打印在不同的侧面,所以用户输入在右边,答案在左边。此外,我希望聊天框滚动到新的消息。这是我的代码,我试图使用StackLayout,但却发现它不起作用:

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.lang import Builder

class Message(Widget):
    pass

class KatApp(App):
    def post(self):
        msg = self.root.ids.usrinp.text
        if len(msg) > 0:
            self.root.ids.chatbox.orientation = 'tb-rl'
            msgbox = Message()
            msgbox.ids.mlab.text = msg
            self.root.ids.chatbox.add_widget(msgbox)
            self.root.ids.scrlv.scroll_to(msgbox)
            self.root.ids.usrinp.text = ''
    def resp(self,msg):
        if len(msg) > 0:
            ansr = msg
            self.root.ids.chatbox.orientation = 'tb-lr'
            ansrbox = Message()
            ansrbox.ids.mlab.text = str(ansr)
            self.root.ids.chatbox.add_widget(ansrbox)
            self.root.ids.scrlv.scroll_to(ansrbox)
            self.root.ids.usrinp.text = ''

    def build(self):
        return Builder.load_string('''
<Message@Widget>:
    size_hint: None, None
    height: mlab.height
    width: mlab.width
    canvas:
        Color:
            rgba: 0, 1, 0, 0.7
        Rectangle:
            pos: self.pos
            size: self.size
    Label:
        id: mlab
        center: root.center
        padding: 10, 10
        markup: True
        text_size: (None, None)
        text: ''
        haligh: 'left'
        valign: 'top'
        size_hint: (1, None)
        size: self.texture_size
        color: 0, 0, 0

ScreenManager:
    Screen:

        BoxLayout:
            orientation: 'vertical'

            ScrollView:

                canvas.before:
                    Color:
                        rgb: 1, 1, 1
                    Rectangle:
                        pos: self.pos
                        size: self.size

                StackLayout:
                    id: chatbox
                    padding: 10, 10
                    orientation: 'tb-rl'

            BoxLayout:
                orientation: 'horizontal'
                padding: 10, 10, 10, 10
                size_hint: 1, None
                height: 50

                BoxLayout:
                    id: inpbox
                    height: max(40, scrlv.height)
                    size_hint: 0.9, None

                    ScrollView:
                        id: scrlv
                        width: inpbox.width - 15
                        x: inpbox.x + 10
                        y: inpbox.y
                        height: 
                            (len(usrinp._lines)+1) * usrinp.line_height - 5 \
                            if (len(usrinp._lines)+1 <= 5) \
                            else 5 * usrinp.line_height - 5

                        TextInput:
                            id: usrinp
                            valign: 'middle'
                            halign: 'left'
                            font_size: 16
                            multiline: True
                            size_hint: scrlv.size_hint_x, None
                            padding: 10, 0, 10, 0


                Button:
                    id: post
                    border: 0, 0, 0, 0
                    size: 40, 40
                    size_hint: None, None
                    on_press:
                        root.inp = usrinp.text
                        app.post()
                    on_release:
                        app.resp(root.inp)
''')

if __name__ == "__main__":
    KatApp().run()

在本例中,右下角的按钮在按下时发送用户输入,在释放时使用相同的输入进行应答。你知道吗

另外,是否可以为消息小部件设置一个最大宽度,比如,如果它到达页面的中间,它应该在下一行?你知道吗

还有一件事我很难弄清楚,那就是文本输入。似乎,使用multiline选项,当一个单词足够长,可以放在下一行时,我试图删除它,但仍保留了一些空间,使框无法调整大小。要复制这个,只需键入“aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa。你知道吗


Tags: textselfnoneididssizemsgroot
1条回答
网友
1楼 · 发布于 2024-10-17 08:25:33

每一面的书写都可以使用BoxLayout来完成。你知道吗

def post(self):
    msg = self.root.ids.usrinp.text
    if len(msg) > 0:
        msgbox = Message()
        msgbox.ids.mlab.text = msg
        msgbox.pos_hint = {'right': 1}
        self.root.ids.chatbox.add_widget(msgbox)
        self.root.ids.scrlv.scroll_to(msgbox)
        self.root.ids.usrinp.text = ''

def resp(self, msg):
    if len(msg) > 0:
        ansr = msg
        ansrbox = Message()
        ansrbox.ids.mlab.text = str(ansr)
        ansrbox.pos_hint = {'x': 0}
        self.root.ids.chatbox.add_widget(ansrbox)
        self.root.ids.scrlv.scroll_to(ansrbox)
        self.root.ids.usrinp.text = ''

在构建器中:

        ScrollView:

            canvas.before:
                Color:
                    rgb: 1, 1, 1
                Rectangle:
                    pos: self.pos
                    size: self.size

            BoxLayout:
                orientation: 'vertical'
                id: chatbox
                padding: 10, 10
                spacing: 5

pos_hint: {'right': 1}添加到输入小部件后,文本现在位于右侧,如下所示:

现在的问题仍然是小部件的宽度:

我试着将小部件的宽度设置为max(root.width, mlab.width),但是没有用。而且,现在,向上滚动不起作用。你知道吗

相关问题 更多 >