Cant display speedometer on MainWindow (kivy)

亡梦爱人 提交于 2021-02-11 13:35:51

问题


I am trying to display the speedometer in my MainWindow screen. Right now when i run the code, the speedometer works but it is not displayed on the MainWindow screen which i want rather it is just appearing on a normal screen. It is possible to combine class Gauge(Widget): and class MainWindow(Screen): together so that the speedometer will actually be displayed on the MainWindow?

.py file

import kivy
kivy.require('1.6.0')
from kivy.app import App
from kivy.clock import Clock
from kivy.properties import NumericProperty
from kivy.properties import StringProperty
from kivy.properties import BoundedNumericProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.widget import Widget
from kivy.uix.scatter import Scatter
from kivy.uix.image import Image
from kivy.uix.label import Label
from kivy.uix.progressbar import ProgressBar
from os.path import join, dirname, abspath
from kivy.uix.screenmanager import Screen, ScreenManager

class WindowManager(ScreenManager):
    pass

class MainWindow(Screen):
    pass

class Gauge(Widget):

    unit = NumericProperty(1.8)
    value = BoundedNumericProperty(0, min=0, max=100, errorvalue=0)
    path = dirname(abspath(__file__))
    file_gauge = StringProperty(join(path, "cadran.png"))
    file_needle = StringProperty(join(path, "needle.png"))
    size_gauge = BoundedNumericProperty(128, min=128, max=256, errorvalue=128)
    size_text = NumericProperty(10)

    def __init__(self, **kwargs):
        super(Gauge, self).__init__(**kwargs)

        self._gauge = Scatter(
            size=(1350,600),
            do_rotation=False,
            do_scale=False,
            do_translation=False
        )

        _img_gauge = Image(
            source=self.file_gauge,
            size=(1350,600)

        )

        self._needle = Scatter(
            size=(self.size_gauge, self.size_gauge),
            do_rotation=False,
            do_scale=False,
            do_translation=False
        )

        _img_needle = Image(
            source=self.file_needle,
            size=(self.size_gauge, self.size_gauge)
        )

        self._glab = Label(font_size=self.size_text, markup=True)
        self._progress = ProgressBar(max=100, height=20, value=self.value , size=(500,400))

        self._gauge.add_widget(_img_gauge)
        self._needle.add_widget(_img_needle)

        self.add_widget(self._gauge)
        self.add_widget(self._needle)
        self.add_widget(self._glab)
        self.add_widget(self._progress)

        self.bind(pos=self._update)
        self.bind(size=self._update)
        self.bind(value=self._turn)

    def _update(self, *args):
        '''
        Update gauge and needle positions after sizing or positioning.
        '''
        self._gauge.pos = self.pos
        self._needle.pos = (self.x, self.y)
        self._needle.center = self._gauge.center
        self._glab.center_x = self._gauge.center_x
        self._glab.center_y = self._gauge.center_y + (self.size_gauge / 4)
        self._progress.x = self._gauge.x + (self.size_gauge/0.468 )
        self._progress.y = self._gauge.y + (self.size_gauge/4 )
        self._progress.width = self.size_gauge

    def _turn(self, *args):
        '''
        Turn needle, 1 degree = 1 unit, 0 degree point start on 50 value.
        '''
        self._needle.center_x = self._gauge.center_x
        self._needle.center_y = self._gauge.center_y
        self._needle.rotation = (50 * self.unit) - (self.value * self.unit)
        self._glab.text = "[b]{0:.0f}[/b]".format(self.value)
        self._progress.value = self.value


class GaugeApp(App):
    increasing = NumericProperty(1)
    begin = NumericProperty(50)
    step = NumericProperty(1)

    def build(self):
        box = BoxLayout(orientation='horizontal', padding=5)
        self.gauge = Gauge(value=50, size_gauge=256, size_text=25)

        box.add_widget(self.gauge)
        Clock.schedule_interval(lambda *t: self.gauge_increment(), 0.05)
        return box

    def gauge_increment(self):
        begin = self.begin
        begin += self.step * self.increasing
        if begin > 0 and begin < 100:
            self.gauge.value = begin
        else:
            self.increasing *= -1
        self.begin = begin


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

回答1:


You need to create an instance of ScreenManager and an instance of Screen. Next you add_widget the Screen to ScreenManager and to the Screen you add box

sm = ScreenManager()
s1 = Screen()
s1.add_widget(box)
sm.add_widget(s1)

This is the complete code which uses your new classes

from kivy.app import App
from kivy.clock import Clock
from kivy.properties import NumericProperty
from kivy.properties import StringProperty
from kivy.properties import BoundedNumericProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.widget import Widget
from kivy.uix.scatter import Scatter
from kivy.uix.image import Image
from kivy.uix.label import Label
from kivy.uix.progressbar import ProgressBar
from os.path import join, dirname, abspath
from kivy.uix.screenmanager import Screen, ScreenManager

class WindowManager(ScreenManager):
    pass

class MainWindow(Screen):
    pass

class Gauge(Widget):

    unit = NumericProperty(1.8)
    value = BoundedNumericProperty(0, min=0, max=100, errorvalue=0)
    path = dirname(abspath(__file__))
    file_gauge = StringProperty(join(path, "cadran.png"))
    file_needle = StringProperty(join(path, "needle.png"))
    size_gauge = BoundedNumericProperty(128, min=128, max=256, errorvalue=128)
    size_text = NumericProperty(10)

    def __init__(self, **kwargs):
        super(Gauge, self).__init__(**kwargs)

        self._gauge = Scatter(
            size=(1350,600),
            do_rotation=False,
            do_scale=False,
            do_translation=False
        )

        _img_gauge = Image(
            source=self.file_gauge,
            size=(1350,600)

        )

        self._needle = Scatter(
            size=(self.size_gauge, self.size_gauge),
            do_rotation=False,
            do_scale=False,
            do_translation=False
        )

        _img_needle = Image(
            source=self.file_needle,
            size=(self.size_gauge, self.size_gauge)
        )

        self._glab = Label(font_size=self.size_text, markup=True)
        self._progress = ProgressBar(max=100, height=20, value=self.value , size=(500,400))

        self._gauge.add_widget(_img_gauge)
        self._needle.add_widget(_img_needle)

        self.add_widget(self._gauge)
        self.add_widget(self._needle)
        self.add_widget(self._glab)
        self.add_widget(self._progress)

        self.bind(pos=self._update)
        self.bind(size=self._update)
        self.bind(value=self._turn)

    def _update(self, *args):
        '''
        Update gauge and needle positions after sizing or positioning.
        '''
        self._gauge.pos = self.pos
        self._needle.pos = (self.x, self.y)
        self._needle.center = self._gauge.center
        self._glab.center_x = self._gauge.center_x
        self._glab.center_y = self._gauge.center_y + (self.size_gauge / 4)
        self._progress.x = self._gauge.x + (self.size_gauge/0.468 )
        self._progress.y = self._gauge.y + (self.size_gauge/4 )
        self._progress.width = self.size_gauge

    def _turn(self, *args):
        '''
        Turn needle, 1 degree = 1 unit, 0 degree point start on 50 value.
        '''
        self._needle.center_x = self._gauge.center_x
        self._needle.center_y = self._gauge.center_y
        self._needle.rotation = (50 * self.unit) - (self.value * self.unit)
        self._glab.text = "[b]{0:.0f}[/b]".format(self.value)
        self._progress.value = self.value


class GaugeApp(App):
    increasing = NumericProperty(1)
    begin = NumericProperty(50)
    step = NumericProperty(1)

    def build(self):
        box = BoxLayout(orientation='horizontal', padding=5)
        self.gauge = Gauge(value=50, size_gauge=256, size_text=25)

        box.add_widget(self.gauge)
        Clock.schedule_interval(lambda *t: self.gauge_increment(), 0.05)

        sm = WindowManager()
        s1 = MainWindow()
        s1.add_widget(box)
        sm.add_widget(s1)

        return sm

    def gauge_increment(self):
        begin = self.begin
        begin += self.step * self.increasing
        if begin > 0 and begin < 100:
            self.gauge.value = begin
        else:
            self.increasing *= -1
        self.begin = begin


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


来源:https://stackoverflow.com/questions/59067674/cant-display-speedometer-on-mainwindow-kivy

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