【问题标题】:Kivymd mdspinner is slowing down backendKivymd mdspinner 正在减慢后端
【发布时间】:2022-06-13 20:31:16
【问题描述】:

我正在创建一个桌面应用程序,它允许用户将文本输入到 GUI 上的文本输入中,然后将这些值写入剪切表(excel 电子表格)。我正在使用 mdspinner 给出一些指示,表明该函数正在后台运行,然后它会消失,并且会出现一个复选标记图标,表示值已写入电子表格。

问题在于 mdspinner 显着减慢了将文本输入写入电子表格的代码的执行速度。如果没有微调器,它只需不到 10 秒即可完成,但使用微调器则需要一分钟以上。

这是一个显示我如何调用函数的 sn-p:

def SingleSave(self):
    threading.Thread(target=writecutsheet.main.SingleSave, args=(self)).start()
    self.spinner_start()

def spinner_start(self):
    self.root.ids.spinid.active = True

我正在使用线程来防止 GUI 在进行回调时冻结。然后线程调用拆分文件 (writecutsheet) 中的函数 (SingleSave)。然后,我在拆分文件的函数中添加了一行来停止微调器,以防止它在线程完成之前停止。

这是微调器的 KV 和调用它的按钮:

        FloatLayout:
            TickIcon:
                id: complete
            LoadingIcon:
                id: loading
            MDSpinner:
                size_hint: None, None
                id: prog1
                size: dp(46), dp(46)
                pos_hint: {"center_y": 0.9, "center_x": 0.94}
                active: False      
        FloatLayout:
            MDNavigationRail:
                NavHomeButton:
                    on_release:
                        screen_manager.current = "Landing"
                        screen_manager.transition.direction = 'left'
                NavSaveButton:
                    on_press:
                        app.SingleSave()
                        complete.icon: ""
                NavGenerateButton:
                    on_release:
                        screen_manager.current = "Generate"
                        screen_manager.transition.direction = 'left'
                NavSettingsButton:
                    on_release:
                        screen_manager.current = "Settings"
                        screen_manager.transition.direction = 'left'

我想此时我已经尝试了所有方法,包括为 spinner 函数和 SingleSave 函数启动一个线程,只需将 prog1.active = True 添加到 KV,当按下保存按钮时触发,将其直接放入拆分文件等中,但没有任何效果。

我必须补充一点,我是线程新手,所以我觉得我在那里搞砸了。

我只提供了代码的 sn-ps,因为提供一个工作示例需要进行大量清理,但如果您需要更多工作(我怀疑您会这样做),我可以提供所有工作示例文件。

【问题讨论】:

  • 发布最小可运行示例
  • 添加到下方,谢谢!

标签: python multithreading kivy kivymd


【解决方案1】:

我创建了一个最小的运行示例并剥离了许多实际功能,并用 for 循环替换它以打印数字 1-1000。实际的单个保存函数是一个 for 循环,用于从包含文本输入 ID、Excel 工作表的 x 和 y 坐标以及工作表名称的字典中读取条目。 for 循环为字典中的每个项目调用同一拆分文件中的另一个函数(以写入剪切表)。我知道这与提供的示例不同,但在我的示例中使用简单的 for 循环仍然会降低速度。

它应该在启动应用程序时立即运行。您会注意到,当您推荐启动和停止微调器的代码时,该功能几乎立即完成。

main.py

from kivymd.app import MDApp
from kivymd.uix.label import MDLabel
from kivymd.uix.boxlayout import MDBoxLayout
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivymd.uix.navigationrail import MDNavigationRail
from kivy.core.window import Window
from kivy.factory import Factory  # NOQA: F401
from kivy.loader import Loader
from kivymd import images_path
from kivymd.uix.navigationdrawer import MDNavigationDrawer
from kivy.properties import ObjectProperty
from kivy.clock import Clock, mainthread
from kivy.core.window import Window
from kivy.metrics import dp
from kivy.uix.scrollview import ScrollView
from kivymd.uix.behaviors import HoverBehavior
from kivymd.theming import ThemableBehavior
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.image import Image
from kivy.uix.gridlayout import GridLayout
from kivymd.icon_definitions import md_icons
from kivy.properties import StringProperty
from kivy.base import ExceptionHandler, ExceptionManager
from kivy.uix.textinput import TextInput
from kivy.animation import Animation
import writecutsheets
import threading
Window.maximize()

class MainApp(MDApp):
    def build(self):
            self.theme_cls.primary_palette = "DeepPurple"
            self.theme_cls.theme_style = "Dark"
            return Builder.load_file('myapp.kv')

    def SingleSave(self, screenid, spinid, tickid):
        reset = "self.root.ids." + tickid + ".icon = \"\""
        exec(reset)
        threading.Thread(target=writecutsheets.main.SingleSave, args=(self, screenid, spinid, tickid, )).start()
        spinner_string = "self.root.ids." + spinid + ".active = True"
        exec(spinner_string)
        
if __name__ == '__main__':
    MainApp().run()

writecutsheets.py:

class main:  
    def SingleSave(self, screenid, spinid, tickid):
        for i in range(1, 1000):
            print(i)
        spinner_string = "self.root.ids." + spinid + ".active = False"
        exec(spinner_string)
        complete_string = "self.root.ids." + tickid + ".icon = \"check\""
        exec(complete_string)

myapp.kv:

#:import get_color_from_hex kivy.utils.get_color_from_hex
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
#:import toast kivymd.toast.toast
#:import StiffScrollEffect kivymd.effects.stiffscroll.StiffScrollEffect
#:import Snackbar kivymd.uix.snackbar.Snackbar
#:import ScrollEffect kivy.effects.scroll.ScrollEffect
#:import Clock kivy.clock.Clock
#:import threading threading

<NavSaveButton@MDNavigationRailItem>
    icon: "content-save-outline"
<NavGenerateButton@MDNavigationRailItem>
    icon: "check-circle-outline"
<NavSettingsButton@MDNavigationRailItem>
    icon: "cog-outline"
<NavHomeButton@MDNavigationRailItem>
    icon: "home"

##### Navigation Drawer Buttons #####
<DrawerClickableItem@MDNavigationDrawerItem>
    text_color: text_color
    icon_color: text_color

##### Button for Dropdown menus #####
<DropDownButton@MDFillRoundFlatIconButton>
    size_hint_x: .2
    icon: "menu-down"
    text: "Select an option"

##### Title text for each screen #####
<TitleLabel@MDLabel>
    halign: "center"
    font_style: "H3"
    pos_hint: {"center_y": 0.85}

##### Text Input #####
<Textbox@MDTextField>
    size_hint_x: .2
    write_tab: False

<TickIcon@MDIconButton>
    icon: ""
    icon_size: "40sp"
    theme_icon_color: "Custom"
    icon_color: "#00ff00"
    pos_hint: {"center_y": 0.9, "center_x": 0.94}


##### Icon for help text #####
<HelpIcon@MDIconButton+MDTooltip>
    icon: "help-circle-outline"
    icon_size: "16sp"

##### Icon for writing values on given page #####
<SaveButton@MDIconButton>
    icon: "content-save-outline"
    pos_hint: {"center_y": 0.98, "center_x": 0.94}

##### Icon to navigate to the generate CLI screen #####
<CompleteButton@MDIconButton>
    icon: "check-circle-outline"
    pos_hint: {"center_y": 0.98, "center_x": 0.96}
    theme_icon_color: "Custom"
    icon_color: "#00ff00"

##### Checkbox #####
<Check@MDCheckbox>
    size_hint: None, None
    size: "38dp", "38dp"

##### Grid Layout #####
<Grid@MDGridLayout>
    col: 1
    rows: 1
    orientation: "lr-tb"
    pos_hint: {"center_y": 0.85}

##### Icon button for going back #####
<BackButton@MDIconButton+MDTooltip>
    icon: "arrow-left"
    tooltip_text: "Back"
    pos_hint: {"center_y": 0.08, "center_x": 0.1}

##### Icon button for moving forward #####
<ForwardButton@MDIconButton+MDTooltip>
    tooltip_text: "Next"
    icon: "arrow-right"
    pos_hint: {"center_y": 0.08, "center_x": 0.94}

##### Scrollview Template ######
<Scroll@ScrollView>
    scroll_y: 1
    pos_hint: {"center_y": 0.3}
    do_scroll_x: False

##### Toolbar Template #####
<Toolbar@MDToolbar>
    title: "Perimeta Config Generator"
    elevation: 10
    pos_hint: {"top": 1}


MDNavigationLayout:
    id: nav_layout
    Toolbar:
        left_action_items: [['menu', lambda x: nav_drawer.set_state("toggle")]]
    ScreenManager:
        id: screen_manager
        Screen:
            name: "screen1"
            Grid:
                TitleLabel:
                    text: "My screen"
            Scroll:
                FloatLayout:
                    MDLabel:
                        text: "Network Name"
                        pos_hint: {"center_y": 0.95, "center_x": 0.8}
                    HelpIcon:
                        tooltip_text: "Enter the name of yournetwork"
                        pos_hint: {"center_y": 0.95, "center_x": 0.29}
                    DropDownButton:
                        pos_hint: {"center_y": 0.95, "center_x": 0.6}
                        id: servnetname
                        on_release:
                            app.servdropdown(servnetname)
                    MDLabel:
                        text: "Source Description"
                        pos_hint: {"center_y": 0.9, "center_x": 0.8}
                    HelpIcon:
                        tooltip_text: "Enter the description of thesource"
                        pos_hint: {"center_y": 0.9, "center_x": 0.29}
                    Textbox:
                        pos_hint: {"center_y": 0.91, "center_x": 0.6}
                        id: tsdesc
                    MDLabel:
                        text: "IP Version"
                        pos_hint: {"center_y": 0.85, "center_x": 0.8}
                    HelpIcon:
                        tooltip_text: "Enter the IP Version"
                        pos_hint: {"center_y": 0.85, "center_x": 0.29}
                    DropDownButton:
                        pos_hint: {"center_y": 0.85, "center_x": 0.6}
                        id: ipversts
                        on_release:
                            app.ipdropdown(ipversts)
                    MDLabel:
                        text: "Start IP"
                        pos_hint: {"center_y": 0.8, "center_x": 0.8}
                    HelpIcon:
                        tooltip_text: ""
                        pos_hint: {"center_y": 0.8, "center_x": 0.29}
                    Textbox:
                        pos_hint: {"center_y": 0.81, "center_x": 0.6}
                        id: trustip
                    MDLabel:
                        text: "End IP"
                        pos_hint: {"center_y": 0.75, "center_x": 0.8}
                    HelpIcon:
                        tooltip_text: ""
                        pos_hint: {"center_y": 0.75, "center_x": 0.29}
                    Textbox:
                        pos_hint: {"center_y": 0.76, "center_x": 0.6}
                        id: rangeendts
            FloatLayout:
                TickIcon:
                    id: complete3
                MDSpinner:
                    size_hint: None, None
                    id: prog3
                    size: dp(46), dp(46)
                    pos_hint: {"center_y": 0.9, "center_x": 0.94}
                    active: False
            FloatLayout:
                size_hint_y: 0.936
                MDNavigationRail:
                    NavSaveButton:
                        on_press:
                            app.SingleSave(3, "prog3", "complete3")
                    NavGenerateButton:
                        on_release:
                            screen_manager.current = "Generate"
                            screen_manager.transition.direction = 'left'
                    NavSettingsButton:
                        on_release:
                            screen_manager.current = "Settings"
                            screen_manager.transition.direction = 'left'

    MDNavigationDrawer:
        id: nav_drawer
        MDNavigationDrawerMenu:   
            MDNavigationDrawerLabel:
                text: "Basic Configuration"
                title_color: text_color
                title_color: text_color 
            DrawerClickableItem:
                icon: ""                
                text: "Start"
                on_press:
                    nav_drawer.set_state("close") 

  

【讨论】:

    猜你喜欢
    • 2018-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-27
    • 1970-01-01
    • 1970-01-01
    • 2012-06-30
    • 2020-11-19
    相关资源
    最近更新 更多