首页 > 解决方案 > 如何防止小部件重叠?

问题描述

如何解决 kivy 框架中的小部件重叠问题,我在循环中添加小部件,所以我有多个小部件,但它们都在一个地方,我该如何防止这种情况?

我的python代码:

from kivy.app import App
from kivymd.app import MDApp
from kivy.uix.label import Label
from kivy.clock import Clock
from kivy.graphics import Color
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivymd.uix.card import MDCard
from kivy.properties import StringProperty
from kivy.lang import Builder
import requests, time, collections

class request_sender():
    return 'DATA'

class CustomLabel(Label):
    pass
class CustomBox(BoxLayout):
    pass

class AuctionCard(Widget):
    auc_timer = ''
    auc_img = ''
    auc_name = ''
    def __init__(self, **kwargs):
        super(AuctionCard, self).__init__(**kwargs)
        with self.canvas.before: Color(1, 0, .4, mode='rgb')
        Clock.schedule_once(self.load_info)

    def load_info(self, dt):
        print(self.auc_name)
        self.size_hint = None, None
        box = BoxLayout(orientation='vertical', size = (800, 600))
        box.size_hint_x = 50;
        box.height = 100
        AuctionName = CustomLabel(text=self.auc_name, pos_hint={'top': 300.9})
        AuctionImage = CustomLabel(text=self.auc_img)
        AuctionTimer = CustomLabel(text=self.auc_name)
        box.add_widget(AuctionName)
        box.add_widget(AuctionTimer)
        box.add_widget(AuctionImage)
        self.add_widget(box)

class MyWidget(Widget):
    prop = StringProperty('')
    array_of_labels = []
    prop1 = StringProperty('Second card')
    n = 0
    all_cards = collections.defaultdict()
    def __init__(self, **kwargs):
        super(MyWidget, self).__init__(**kwargs)
        self.screen_load()
    def timer_le(self, dt):
        returned_data = request_sender().sender_update('ajax.php')
        for key in self.all_cards:
            for data in returned_data:
                if data['pid'] == key:
                    self.all_cards[key][0].text = str(data['remaining_time'])

    def screen_load(self):
        returned_data = request_sender().sender_update('ajax.php')
        box = GridLayout(cols=2)
        self.size_hint = None, None
        for data in returned_data:
            AucCard = AuctionCard()
            AucCard.auc_name = str(data['auc_name'])+'\n\n'
            AucCard.auc_timer = str(data['remaining_time'])+'\n\n'
            AucCard.auc_img = str(data['auc_img'])+'\n\n'
            box.add_widget(AucCard)
            print('Widget added')
        self.add_widget(box)
            #self.all_cards[str(data['pid'])] = [AucCard]
        #Clock.schedule_interval(self.timer_le, 1/30)

class TestApp(App):
    def build(self):
        box = GridLayout(cols=2)
        return MyWidget()

TestApp().run()

我的kv代码:

<CustomLabel>:
    size_hint_y: None
    text_size: self.width, None
    height: self.texture_size[1]

结果:

在此处输入图像描述

我想要创建的结果类型:

在此处输入图像描述

标签: pythonkivykivy-language

解决方案


其实我找到了解决这个问题的简单方法。问题出在我的 AuctionCard 和 MyWidget 类的父类中,我将父类设置为 Widget,但对于 AuctionCard,它应该是 BoxLayout 和 MyWidget GridLayout。所以从那里我设法将cols = 2和size设置为window.size。从这里它完全按照它应该如何工作。

from kivy.lang import Builder
from kivy.app import App
from kivy.core.window import Window
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.clock import Clock
from kivy.uix.gridlayout import GridLayout


class AuctionCard(BoxLayout):
    auc_timer = ''
    auc_img = ''
    auc_name = ''
    def __init__(self, **kwargs):
        super(AuctionCard, self).__init__(**kwargs)
        Clock.schedule_once(self.load_info)
    def load_info(self, dt):
        self.orientation = 'vertical'
        AuctionName = Label(text=self.auc_name)
        AuctionImage = Label(text=self.auc_img)
        AuctionTimer = Label(text=self.auc_timer)
        self.add_widget(AuctionName)
        self.add_widget(AuctionTimer)
        self.add_widget(AuctionImage)

class MyWidget(GridLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.cols = 2
        self.size = (Window.size[0], self.size[1])
        self.load_app()
        print('MyWidget size: '+str(self.size))
    def load_app(self):
        self.size_hint = None, None
        returned_data = [{'auc_name':'name 1', 'remaining_time':'100', 'auc_img':'https://img.src'},
                         {'auc_name':'name 2', 'remaining_time':'200', 'auc_img':'https://img.src'},
                         {'auc_name':'name 3', 'remaining_time':'300', 'auc_img':'https://img.src'}]
        for data in returned_data:
            AucCard = AuctionCard()
            AucCard.auc_name = str(data['auc_name'])+'\n\n'
            AucCard.auc_timer = str(data['remaining_time'])+'\n\n'
            AucCard.auc_img = str(data['auc_img'])+'\n\n'
            self.add_widget(AucCard)
            print('Widget added')


class MyTestApp(App):
    def __init__(self, **kwargs):
        self.title = "My Material Application"
        super().__init__(**kwargs)

    def build(self):
        return MyWidget()


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

结果: 结果


推荐阅读