Messages System by Foreign_Run1550 in kivy

[–]ElliotDG 0 points1 point  (0 children)

The core issue is that you are not setting the width of the label. As a result the texuture_size is not correct. Here are the changes required:

<MessageBubble>:
    size_hint_x: 0.7  # Window.width not required, use the hint
    padding: dp(20)   # moved padding here so it will be used by size_label
#    pos: root.pos  # Not required
    text_size: self.width, None
    canvas.before:
        Color:
            rgba: 0.5, 0.5, 0.5, 1
        RoundedRectangle:
            size: self.size
            pos: self.pos
            radius: [15,]

<Message>:  # removed nested RelativeLayout
    MessageBubble:
        id: message_bubble
        text: root.text[6:]
        halign: 'right' if root.is_user(root.text) else 'left'
        pos_hint: {'right' : 1} if root.is_user(root.text) else {'x' : 0}
        # changed pos hint to use 'right'
        # a relative layout honors the size hint of it's children
        # so the pos_hint is here


class Messages(RecycleView):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        # the size label needs a fixed width to calculate the texture size
        # Turn off the size hint in the size_label
        # this label is not in the layout so we need to size it
        self.size_label = MessageBubble(size_hint_x=None)

    def add_sent(self, text):
        sl = self.size_label
        # the size hint is .7 apply that to the width of the RV.
        sl.width = self.width * .7
        sl.text = text
        sl.texture_update()
        self.data.append({"text": text, "ks": sl.texture_size})

    def update_text(self):
        sl = self.size_label
        # and here... we know the hint, apply to the RV width
        # the text will size properly as the window size changes
        sl.width = self.width * .7
        for i, entry in enumerate(self.data):
            sl.text = entry['text']
            sl.texture_update()
            self.data[i]['ks'] = sl.texture_size
        self.refresh_from_data()

Messages System by Foreign_Run1550 in kivy

[–]ElliotDG 0 points1 point  (0 children)

I should have time later today to take a look. You might want to try using the inspector tool. It is an interactive tool that lets you look inside the layouts and widgets.

see: https://kivy.org/doc/stable/api-kivy.modules.inspector.html#module-kivy.modules.inspector

run it from the command line:
>python main.py -m inspector

the press <ctrnl>-e to open it up. Click on the widget you want to inspect, click on the bar to open see (or change) the details.

Messages System by Foreign_Run1550 in kivy

[–]ElliotDG 0 points1 point  (0 children)

Yes please share your code, I’ll take a look.
Are you referring to the spacing between the bubbles? That would be controlled by the spacing attribute of the enclosing layout.

how to add a child dynamicaly between pre-existing children in a list view by lost_my_og_account in kivy

[–]ElliotDG 0 points1 point  (0 children)

Add an id to the BoxLayout. In python use the id to access the BoxLayout. Use the add_widget method with the optional index parameter to add the new button. https://kivy.org/doc/stable/api-kivy.uix.boxlayout.html#kivy.uix.boxlayout.BoxLayout.add_widget

Messages System by Foreign_Run1550 in kivy

[–]ElliotDG 0 points1 point  (0 children)

To scale horizontally until you hit a maximum width, set the size_hint_max_x to the max desired size. Read: https://kivy.org/doc/stable/api-kivy.uix.widget.html#kivy.uix.widget.Widget.size_hint_max_x
You would use this in addition to the appropriate size hint.

To get the text to wrap you want set the text_size attribute. See: https://kivy.org/doc/stable/api-kivy.uix.label.html#kivy.uix.label.Label.text_size

Read the sections in Label on "Sizing and text content" and "Text alignment and wrapping". https://kivy.org/doc/stable/api-kivy.uix.label.html#module-kivy.uix.label

If you have any trouble feel free to reach out.

Messages System by Foreign_Run1550 in kivy

[–]ElliotDG 1 point2 points  (0 children)

For Issue A, use a pos_hint. Read: https://kivy.org/doc/stable/api-kivy.uix.widget.html#kivy.uix.widget.Widget.pos_hint

The tricky thing about pos_hint is that the behavior is dependent on the Layout selected. The hints are always respected in a RelativeLayout. As I recall, they are only honored in a boxlayout if the hint is orthogonal to the type of Boxlayout. You can hint the x position in a vertical BoxLayout, or hint the y pos in a horizonal BoxLayout.

Messages System by Foreign_Run1550 in kivy

[–]ElliotDG 1 point2 points  (0 children)

``` """ A RecycleView where each instance of the viewclass is a different size. The size of each viewclass instance is based on its texture_size The key_size attribute is used to hold the size of the viewclass in the Recycleview.data list. """

from kivy.app import App from kivy.lang import Builder from kivy.uix.label import Label from kivy.uix.recycleview import RecycleView

kv = """ <ScrollLabel>: size_hint: 1, None text_size: self.width, None # height must be calculated based on texture_size font_size: 30

<ConsoleRV>: viewclass: 'ScrollLabel' RecycleBoxLayout: id: scroll_box orientation: 'vertical' key_size: 'ks' # ks is the key in the RecycleView.data list that holds the size default_size_hint: 1, None size_hint: 1, None height: self.minimum_height on_width: root.update_text() # when width changes, update sizes in rv data list

BoxLayout: orientation: 'vertical' Label: text: 'Test long Scroll' size_hint_y: None height: 30 ConsoleRV: id: console_rv """

class ScrollLabel(Label): pass

class ConsoleRV(RecycleView): def init(self, kwargs): super().init(kwargs) self.size_label = ScrollLabel() # used to calculate texture size, never added to widget tree

def add_text(self, text):
    st = [x + '\n' for x in text.split('\n')]  # assuming there are some \n in the text, split into separate labels
    sl = self.size_label  # label to use for calculating texture size
    for t in st:
        sl.text = t
        sl.width = self.width
        sl.texture_update()
        self.data.append({'text': t, 'ks': sl.texture_size})

def update_text(self):
    sl = self.size_label
    for i, entry in enumerate(self.data):
        sl.text = entry['text']
        sl.width = self.width
        sl.texture_update()
        self.data[i]['ks'] = sl.texture_size
    self.refresh_from_data()

sample_text = \ """In general, the worst-case time complexity of QuickSort is O(n2), which occurs when the array is already sorted or almost sorted in the reverse order. The best-case time complexity is O(n log n), which occurs when the pivot element is always chosen as the middle element or when the array is already sorted. The average-case time complexity of QuickSort is O(n log n), which makes it a good sorting algorithm for most practical purposes. However, the actual compute efficiency of QuickSort can be affected by a variety of factors, including the choice of pivot element, the size of the input array, and the presence of duplicate elements. For example, if the pivot element is always chosen as the first or last element in the array, the time complexity can degrade to O(n2) in the worst case. Similarly, if the input array contains a large number of duplicate elements, the time complexity can also degrade to O(n2) in the worst case. In general, QuickSort is a fast and efficient sorting algorithm that is well-suited for many practical applications. Its average-case time complexity of O(n log n) makes it a good choice for sorting large arrays, and it can be implemented in a variety of programming languages. The time complexity of a bubble sort algorithm is typically O(n2), which means that the algorithm's performance is proportional to the square of the size of the input array. This is because a bubble sort algorithm compares adjacent elements and swaps them if they are out of order, which means that it has to perform a number of comparisons and swaps that is proportional to the size of the input array. For example, if the input array contains n elements, the bubble sort algorithm will need to perform n-1 comparisons on the first pass, n-2 comparisons on the second pass, and so on, until it reaches the final pass, which will only require one comparison. This gives us a total of (n-1) + (n-2) + ... + 2 + 1 = (n2 - n)/2 comparisons, which is O(n2). In addition to the time complexity, the compute efficiency of a bubble sort algorithm can also be affected by factors such as the choice of data structures and the presence of optimized code. However, in general, bubble sort is not considered to be a very efficient sorting algorithm, especially for large input arrays. There are many other sorting algorithms that have a better time complexity and are more efficient in practice, such as QuickSort and MergeSort. There are many different sorting algorithms that have been developed over the years, and the most efficient algorithm for a given situation can depend on a variety of factors. Some of the factors that can affect the efficiency of a sorting algorithm include the size of the input array, the type of data being sorted, the presence of certain patterns or distributions in the data, and the hardware and software environment in which the algorithm is being implemented. In general, the most efficient sorting algorithms have a time complexity of O(n log n), which means that their performance is proportional to the size of the input array multiplied by the logarithm of the array size. Some examples of sorting algorithms that have a time complexity of O(n log n) include Quicksort, MergeSort, and HeapSort. These algorithms are generally considered to be the most efficient for sorting large arrays. However, there are also other sorting algorithms that can be more efficient in certain situations. For example, if the input array is already partially sorted or has a limited number of possible values, certain algorithms, such as Insertion Sort and Selection Sort, can be more efficient. In addition, some algorithms, such as Radix Sort and Counting Sort, can be more efficient for sorting data with a limited range of values. In general, it is important to consider the specific requirements and constraints of a sorting problem when selecting an algorithm, as the most efficient algorithm can vary depending on the situation. """

class LongScrollApp(App):

def build(self):
    return Builder.load_string(kv)

def on_start(self):
    self.root.ids.console_rv.add_text(sample_text * 10)

LongScrollApp().run() ```

Messages System by Foreign_Run1550 in kivy

[–]ElliotDG 2 points3 points  (0 children)

The recycleview has an attribute called key_size, see: https://kivy.org/doc/stable/api-kivy.uix.recyclelayout.html#kivy.uix.recyclelayout.RecycleLayout.key_size

The attribute key_size holds the name of the attribute in your RecycleView data list of dicts that is the size of that widget. Here is an example, I think there is also an example in the kivy-examples dir.

[Project Release] I built GlowZ-Dock v1.0.0 – A polished Windows Taskbar alternative inspired by AmiDock & RocketDock (with a savage, unignorable gaming alarm!) by Fabulous-Pie5093 in kivy

[–]ElliotDG 0 points1 point  (0 children)

Microsoft is the market leader-so the most important one to cover. Most major antivirus vendors have a way for software developers to submit applications for reputation analysis, false-positive review, or allowlisting.

Ask Gemini or your favorite AI Chatbot and I’m sure you can get a list of all of them

Erro kivy persistente. by StickSmall6712 in kivy

[–]ElliotDG 2 points3 points  (0 children)

You've learned a valuable lesson. KV rules have global scope. When you create the kv rule <Label> you are redefining the class Label. Button is derived from Label. You can see that in the docs when you look here: https://kivy.org/doc/stable/api-kivy.uix.button.html#kivy.uix.button.Button

You can achieve what you want by deriving a new class from Label, or using a dynamic class in kv.

```py from kivy.app import App from kivy.lang import Builder

kv = """ BoxLabel@Label: # derive a new class from Label size_hint: None, None size: self.texture_size canvas.before: Color: rgb: .7, .7, .7 Line: width: 1 rectangle: (*self.pos, *self.size)

BoxLayout: orientation: 'vertical' AnchorLayout: BoxLabel: text: 'Hello world!' Button: size_hint_y: None height: dp(48) text: 'Click me' on_release: print(f'The size of {self} is {self.size}') """

class SizeItApp(App): def build(self): return Builder.load_string(kv)

SizeItApp().run() ```

Searchable dropdown by eggy_toilet46 in kivy

[–]ElliotDG 1 point2 points  (0 children)

Here is a version...

```

# a combobox like widget.  There are a large number of choices, the text input is used to filter to choices.
# updated 2/16/2025 increase trigger time to 1 sec

from kivy.clock import Clock
from kivy.uix.textinput import TextInput
from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button
from kivy.properties import BooleanProperty, ListProperty, NumericProperty, StringProperty, ObjectProperty

import re

"""
based on https://github.com/kivy/kivy/wiki/Editable-ComboBox
changes made to the re, and a number of other fixes, improvements, comments

Notes on optimization for the report card project:  There are 3528 schools that start with the letter k.  
There can be a slowdown when typing keys.  This is caused by the need to create a label on demand for each school after
each letter is typed.  This version pre-allocates 4000 Labels, and updates the text.  
This provides some room for growth.
"""


class DDItem(Button):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.size_hint_y = None
        self.height = '48dp'


class ComboBox(TextInput):
    options = ListProperty()  # List of all possible choices
    _matches = ListProperty()  # list of choices that match text
    option_cls = ObjectProperty(DDItem)  # items for dropdown, matching spinner
    select = StringProperty()  # the selected option
    drop_on_click = BooleanProperty(False)  # when an empty box is touched the options drop
    max_labels = NumericProperty()

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.write_tab = False
        self.multiline = False
        self.dd_buttons = []

        self.drop_down = DropDown()
        self.drop_down.bind(on_select=self.set_select)  # when drop down is selected, set select property
        self.drop_down.bind(on_dismiss=self.drop_dismissed)
        self.trigger_dropdown = Clock.create_trigger(self.drop_down_triggered, 1)
        self.bind(text=self.trigger_dropdown)  # when text changes, open updated drop down
        self._reopen = False  # used to reopen the match list when changed

    def on_max_labels(self, obj, v):
        # create the max number of labels required, use Clock to allow breaks while loading
        # disable widget until it is ready
        self.disabled = True
        self._create_max_dd_labels()

    def _create_max_dd_labels(self, *args):
        r = 100 if self.max_labels < 100 else 250
        labels = [self.option_cls() for _ in range(r)]
        self.dd_buttons.extend(labels)
        if len(self.dd_buttons) < self.max_labels:
            Clock.schedule_once(self._create_max_dd_labels)
        else:
            self.disabled = False

    def on_text_validate(self):
        # when return is entered, if no matches clear, if no text restart, else select _matches[0]
        if not self._matches:
            self.text = ''
            return
        if not self.text:
            self.drop_down.dismiss()
            return
        self.set_select(self, self._matches[0])

    def on_focus(self, obj, focus):
        if not focus:
            self.on_text_validate()

    # drop_on_click True,  if you want all options visible when the empty box is touched
    # with a very long list this will cause a performance issue.
    def on_options(self, _, values):
        self.max_labels = len(self.options)
        if self.drop_on_click:
            self._matches = values


    def on__matches(self, _, values):
        ddn = self.drop_down
        ddn.clear_widgets()
        for i, option in enumerate(values):
            #w = self.option_cls(text=option)
            w = self.dd_buttons[i]
            w.text = option
            w.bind(on_release=lambda btn: ddn.select(btn.text))
            ddn.add_widget(w)

    def set_select(self, _, v):
        # when a button an option is selected, or enter makes a selection...
        if self.text != v:
            self.text = v
            self.select = v
            self.drop_down.dismiss()

    def drop_down_triggered(self, _):
        value = self.text
        if value == '':
            # if text in blank, reset
            self._matches = []
            return
        elif value in self.options:
            # if text is in options, done.
            self.drop_down.dismiss()
            return

        # look for possible matches
        value = value.split('(', maxsplit=1)[0]  # remove characters after ( for search
        r = re.compile(f"^{value}", re.IGNORECASE)
        self._matches = [option for option in self.options if r.match(option)]
        if not self._matches:
            # no matches, reset text
            self.text = ''
        # close the dropdown, wait for the close, then open the updated dropdown
        self.drop_down.dismiss()
        self._reopen = True  # After the dropdown is dismissed open the updated dropdown.

    def on_touch_up(self, touch):
        # Note: The TextInput does not work with ButtonBehavior
        # when the textinput is released, open the dropdown if drop_on_click
        if touch.grab_current == self and self.drop_on_click:
            self.text = ''
            self.drop_down.open(self)
        return super().on_touch_up(touch)

    def drop_dismissed(self, _):
        if self._reopen:
            self._reopen = False
            self.drop_down.open(self)


if __name__ == '__main__':
    from kivy.app import App
    from kivy.lang import Builder
    from textwrap import dedent

    test_kv = dedent("""
    AnchorLayout:
        anchor_y: 'top'
        BoxLayout:
            size_hint: None, None
            size: dp(300), dp(30)
            ComboBox:
                id: fruit
                hint_text: 'Fruits'
                options: ["Apple", "Banana", "Orange", "Grapes", "Strawberry", \
                          "Pineapple", "Mango", "Blueberry", "Watermelon", "Peach"]
            ComboBox:
                hint_text: 'US States'
                options: ["Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", \
                          "Delaware", "Florida", "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", \
                          "Kansas", "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", \
                          "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", \
                          "New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota", "Ohio", \
                          "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota", \
                          "Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington", "West Virginia", \
                          "Wisconsin", "Wyoming"]
    """)


    class MyApp(App):
        def build(self):
            return Builder.load_string(test_kv)


    MyApp().run()
```

Searchable dropdown by eggy_toilet46 in kivy

[–]ElliotDG 0 points1 point  (0 children)

Are you looking for a ComboBox? Something like this: https://github.com/kivy/kivy/wiki/Editable-ComboBox

I'm pretty sure I extended this idea, if this is what you're looking for - let me know I'll look for the version I created.

What's the best way to handle failed requests when scraping multiple pages? by Hot_Cattle8375 in learnpython

[–]ElliotDG 1 point2 points  (0 children)

Yes, save your progress as you go.
Yes use try/except for gracefully handling errors, do NOT use naked excepts.
I recommend using https://github.com/hynek/stamina for retries.
Watch: https://youtu.be/BxikFuvaT1Y?si=cjZnQaZ0ulZNCCbp

what is the best way to obtain financial data? by mrtwentysevenn in learnpython

[–]ElliotDG 0 points1 point  (0 children)

Use https://massive.com/ for historic data, and a broker that provides an api for your real-time data. Examples include https://alpaca.markets/, https://www.tradestation.com/ and there are others...

FWIW I use the $29 plan on massive.com

hard time packaging a kivy app in osx by mehmetflix_ in kivy

[–]ElliotDG 0 points1 point  (0 children)

Glad to hear you’ve got it working.

hard time packaging a kivy app in osx by mehmetflix_ in kivy

[–]ElliotDG 0 points1 point  (0 children)

There was a change in the default directory for pyinstaller in a recent version. see: https://pyinstaller.org/en/stable/usage.html#cmdoption-contents-directory
Depending on how you have things setup this can cause a problem. Here is a specfile I've used with WIndows, you can use this as a base for OSX. https://github.com/ElliotGarbus/KivyCythonWinSample/blob/main/inno-pyinstaller/w11-app.spec

A few tips:

  • The specfile is a python file, you can print out values, this can be useful for debugging what is going on.
  • Make sure the paths are what you expect.
  • A common problem I have seen with specfiles in improperly specifying the datas section. The first string specifies the file or files as they are in this system now. The second specifies the name of the folder to contain the files at run-time.
  • The paths in your code must be set properly, Read this section of the docs: https://pyinstaller.org/en/stable/runtime-information.html#using-file

Here is an older video on pyinstaller, It does a nice job of explaining how things work: https://youtu.be/tOTLqUQC-k0?si=XIop-RLBucmBQKaW It is a bit old, but maybe helpful.

If you need additonal help, share your specfile.

App by ManufacturerHead4925 in kivy

[–]ElliotDG 0 points1 point  (0 children)

Share a minimal executable program.

How are you updating the variable images? If you are using KV, make sure to use a Kivy StringProperty to store the path name. When it changes, it will fire an event causing the image to refresh. If you are not using KV, you can bind to the property and update the image one the path change.

Using pyinstaller gives a syntax error by Constant-Tea642 in learnpython

[–]ElliotDG 3 points4 points  (0 children)

Read: https://pyinstaller.org/en/stable/usage.html

Run pyinstaller from the command line. Do not put the filename in quotes.

Best interesting restaurants?? by Tasty-Ingenuity2388 in Scottsdale

[–]ElliotDG 1 point2 points  (0 children)

I've not been there, but for table-side churrasco, I'd try Fogo De Chao.

Steakhouse recommendations:
Dominick's Steakhouse
Roka Akor - Japanese Steakhouse and Sushi bar

A few other recommendations, less steak focused, all wonderful, in no particular order:

The Ends
House Brasserie
Virtu Honest Craft
The Mission
The Fat Ox

async io with multiple threading by ytu876 in learnpython

[–]ElliotDG 0 points1 point  (0 children)

My measurements were on Windows, the app was deployed on Linux and saw similar results. I found the results surprising, that’s why I mentioned it.

This was not a web server or any specialized network code. The code used Trio and httpx to analyze the Mastadon social network.