【问题标题】:Kivy vertical and horizontal scrollable ScrollView Label. How to reduce/increase the horizontal Label size?Kivy 垂直和水平可滚动的 ScrollView 标签。如何减少/增加水平标签大小?
【发布时间】:2021-07-14 14:03:53
【问题描述】:

这是定义一个可以垂直和水平滚动的 Kivy ScrollView 标签的代码:

from kivy.app import App
from kivy.config import Config
from kivy.properties import ObjectProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup

class ScrollablePopup(Popup):
    contentBox = ObjectProperty()
    scrollView = ObjectProperty()


    def scrollToTop(self):
        self.scrollView.scroll_y = 1 # force scrolling to top

    def scrollToBottom(self):
        self.scrollView.scroll_y = 0 # force scrolling to bottom

    def initText(self, text):
        self.contentBox.content.text = text


class ScrollPopup(BoxLayout):
    popup = None

    def openPopup(self):
        self.popup = ScrollablePopup(title="Scrollable popup")
        text = u"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus odio nisi, pellentesque molestie adipiscing vitae, aliquam at tellus.\nFusce quis est ornare erat pulvinar elementum ut sed felis. Donec vel neque mauris. In sit amet nunc sit amet diam dapibus lacinia.\nIn sodales placerat mauris, ut euismod augue laoreet at. Integer in neque non odio fermentum volutpat nec nec nulla.\nDonec et risus non mi viverra posuere. Phasellus cursus augue purus, eget volutpat leo. Phasellus sed dui vitae ipsum mattis facilisis vehicula eu justo.\nQuisque neque dolor, egestas sed venenatis eget, porta id ipsum. Ut faucibus, massa vitae imperdiet rutrum, sem dolor rhoncus magna, non lacinia nulla risus non dui.\nNulla sit amet risus orci. Nunc libero justo, interdum eu pulvinar vel, pulvinar et lectus. Phasellus sed luctus diam. Pellentesque non feugiat dolor.\nCras at dolor velit, gravida congue velit. Aliquam erat volutpat. Nullam eu nunc dui, quis sagittis dolor. Ut nec dui eget odio pulvinar placerat.\nPellentesque mi metus, tristique et placerat ac, pulvinar vel quam. Nam blandit magna a urna imperdiet molestie. Nullam ut nisi eget enim laoreet sodales sit amet a felis.\n"

        for i in range(0, 4):
            text += "\n\n" + text

        self.popup.initText(text)
        self.popup.open()

class ScrollPopupVertHorzApp(App):
    def build(self): # implicitly looks for a kv file of name kivylistview1111.kv which is
                     # class name without App, in lowercases

        Config.set('graphics', 'width', '400')
        Config.set('graphics', 'height', '500')
        Config.write()

        return ScrollPopup()

    def on_pause(self):
        # Here you can save data if needed
        return True

    def on_resume(self):
        # Here you can check if any data needs replacing (usually nothing)
        pass

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

scrollpopupverthorz,kv

<ScrollPopup>:
    orientation: "vertical"
    popupButton: popup_button

    BoxLayout:
        size_hint_y: None
        Button:
            id: popup_button
            text: "Open scrollable popup"
            size_hint_y: None
            height: "40dp"
            on_press: root.openPopup()

<ScrollablePopup>:
    id: scr_popup
    auto_dismiss: False
    contentBox: content_box
    scrollView: scroll_view
    padding:10, 10

    BoxLayout:
        id: content_box
        orientation: "vertical"
        content: content_text

        ScrollView:
            id: scroll_view
            effect_cls: "ScrollEffect" # prevents overscrolling
            do_scroll_x: True # enabling horizontal scrolling
            Label:
                id: content_text
                size_hint_x: None # required for horizontal scrolling to work. This
                                  # comment is wrong. See the answer below !
                size_hint_y: None # required for horizontal scrolling to work
                height: self.texture_size[1] # required for vertical scrolling to work
                width: self.texture_size[0]  # Set the Label width to the text width.
                                             # Requnred for horizontal scrolling to work
                line_height: 1.5
                valign: "top"

        Button:
            text: "Scroll to top"
            size_hint_y: None
            height: "40dp"
            on_press: scr_popup.scrollToTop()

        Button:
            text: "Scroll to bottom"
            size_hint_y: None
            height: "40dp"
            on_press: scr_popup.scrollToBottom()

        Button:
            text: "Close"
            size_hint_y: None
            height: "40dp"
            on_press: root.dismiss()

我的问题是:如何在不分别剪切部分文本行或在每个文本行左侧添加空格的情况下将标签宽度设置为更小或更大的值?

【问题讨论】:

    标签: python-3.x kivy scrollview


    【解决方案1】:

    size_hint 实际上不需要是None 才能滚动工作,您只需要最终的高度或宽度大于ScrollView 的高度或宽度。因此,您可以将size_hint_x 设置为大于1 的任何值,您仍然会获得水平滚动:

            Label:
                id: content_text
                size_hint_x: 1.5 # must be greater than 1 for horizontal scrolling
                size_hint_y: None # requnred for vertical scrolling to work
                height: self.texture_size[1] # required for vertical scrolling to work
                text_size: self.width, None
                line_height: 1.5
                valign: "top"
    

    关键是设置text_size,让文字横向约束。

    请注意,您可以使用size_hint_x: None 并将width 设置为某个特定值。如果width 大于ScrollView width,那么您将获得水平滚动。

    【讨论】:

      【解决方案2】:

      使用可滚动的 TextInput 而不是可滚动的 Label 并不能解决问题。

      这是代码。

      Python 文件:

      import os
      import pandas as pd
      
      from kivy.app import App
      from kivy.config import Config
      from kivy.properties import ObjectProperty
      from kivy.uix.boxlayout import BoxLayout
      
      OWNER = 'OWNER'
      CAPITAL_USD = 'CAPITAL USD'
      YIELD_USD = 'YIELD USD'
      CAPITAL_CHF = 'CAPITAL CHF'
      YIELD_CHF = 'YIELD CHF'
      CAPITAL_EUR = 'CAPITAL EUR'
      YIELD_EUR = 'YIELD EUR'
      CAPITAL_DM = 'CAPITAL DM'
      YIELD_DM = 'YIELD DM'
      
      class PandasTextInputScrolling(BoxLayout):
          textOutput = ObjectProperty()
      
          def initTextOutput(self):
              self.textOutput.text = ''
              self.textOutput.text = self.createDataframe()
      
          def clearAll(self):
              self.textOutput.text = ''
      
      
          def createDataframe(self):
              df = pd.DataFrame({OWNER: ['John', 'John', 'John', 'John', 'John', 'John', 'Rob', 'Rob', 'Rob', 'Rob', 'Rob',
                                         'Rob', 'Rob', 'Rob', 'Tom', 'Tom', 'Tom', 'Tom', 'Tom', 'Tom', 'Bob', 'Bob', 'Bob',
                                         'Bob', 'Bob'] * 3,
                                 CAPITAL_USD: [10000, 5000, 20000, 4000, 3000] * 15,
                                 YIELD_USD: [1000, 500, 2000, 400, 300] * 15,
                                 CAPITAL_CHF: [10000, 5000, 20000, 4000, 3000] * 15,
                                 YIELD_CHF: [1000, 500, 2000, 400, 300] * 15,
                                 CAPITAL_EUR: [10000, 5000, 20000, 4000, 3000] * 15,
                                 YIELD_EUR: [1000, 500, 2000, 400, 300] * 15,
                                 CAPITAL_DM: [10000, 5000, 20000, 4000, 3000] * 15,
                                 YIELD_DM: [1000, 500, 2000, 400, 300] * 15})
      
              # adding OWNER total rows
      
              dfGroupOwnerTotal = df.groupby([OWNER]).agg({CAPITAL_USD: 'sum',
                                                           YIELD_USD: 'sum',
                                                           CAPITAL_CHF: 'sum',
                                                           YIELD_CHF: 'sum',
                                                           CAPITAL_EUR: 'sum',
                                                           YIELD_EUR: 'sum',
                                                           CAPITAL_DM: 'sum',
                                                           YIELD_DM: 'sum'})
              totalDf = pd.DataFrame(columns=[OWNER,
                                              CAPITAL_USD,
                                              YIELD_USD,
                                              CAPITAL_CHF,
                                              YIELD_CHF,
                                              CAPITAL_EUR,
                                              YIELD_EUR,
                                              CAPITAL_DM,
                                              YIELD_DM])
              currentOwner = df.loc[1, OWNER]
              totalDfIndex = 0
      
              # deactivating SettingWithCopyWarning caueed by totalRow[OWNER] += ' total'
              pd.set_option('mode.chained_assignment', None)
      
              for index, row in df.iterrows():
                  if currentOwner == row[OWNER]:
                      totalDf = totalDf.append({OWNER: row[OWNER],
                                                CAPITAL_USD: row[CAPITAL_USD],
                                                YIELD_USD: row[YIELD_USD],
                                                CAPITAL_CHF: row[CAPITAL_CHF],
                                                YIELD_CHF: row[YIELD_CHF],
                                                CAPITAL_EUR: row[CAPITAL_EUR],
                                                YIELD_EUR: row[YIELD_EUR],
                                                CAPITAL_DM: row[CAPITAL_DM],
                                                YIELD_DM: row[YIELD_DM]}, ignore_index=True)
                  else:
                      totalRow = dfGroupOwnerTotal.loc[currentOwner]
                      totalDf = totalDf.append(totalRow, ignore_index=True)
                      totalDf.iloc[totalDfIndex][OWNER] = currentOwner + ' total'
                      totalDfIndex += 1
                      totalDf = totalDf.append({OWNER: row[OWNER],
                                                CAPITAL_USD: row[CAPITAL_USD],
                                                YIELD_USD: row[YIELD_USD],
                                                CAPITAL_CHF: row[CAPITAL_CHF],
                                                YIELD_CHF: row[YIELD_CHF],
                                                CAPITAL_EUR: row[CAPITAL_EUR],
                                                YIELD_EUR: row[YIELD_EUR],
                                                CAPITAL_DM: row[CAPITAL_DM],
                                                YIELD_DM: row[YIELD_DM]}, ignore_index=True)
                      currentOwner = row[OWNER]
                  totalDfIndex += 1
      
              totalRow = dfGroupOwnerTotal.loc[currentOwner]
              totalDf = totalDf.append(totalRow, ignore_index=True)
              totalDf.iloc[totalDfIndex][OWNER] = currentOwner + ' total'
      
              return totalDf.to_string()
      
      
      class PandasTextInputScrollingApp(App):
          def build(self):
              if os.name != 'posix':
                  # running app om Windows
                  Config.set('graphics', 'width', '400')
                  Config.set('graphics', 'height', '300')
                  Config.write()
      
              self.gui = PandasTextInputScrolling()
              self.gui.initTextOutput()
      
              return self.gui
      
      PandasTextInputScrollingApp().run()
      

      KV 文件:

      <PandasTextInputScrolling>:
          textOutput: txt_output
      
          orientation: 'vertical'
          BoxLayout:
              orientation: 'vertical'
              BoxLayout:
                  orientation: 'vertical'
                  size_hint_y: 0.9
      
                  ScrollView:
                      id: scrlv
                      size_hint_y: 0.9
                      effect_cls: "ScrollEffect" # prevents overscrolling
                      TextInput:
                          id: txt_output
                          readonly: True
                          size_hint_x: 1.5  # any value greater than 1 can be set to enable
                                            # scrolling, with the risk of cutting part of the
                                            # text width !
                          size_hint_y: None # required for horizontal scrolling to work
                          height: self.texture_size[1] # required for vertical scrolling to work
                          line_height: 1.5
                          height: max( (len(self._lines)+1) * self.line_height, scrlv.height)
                  Button:
                      id: clear_output_Button
                      text: 'Clear'
                      size_hint_y: 0.1
                      on_press: root.clearAll()
                  Button:
                      id: fill_output_Button
                      text: 'Show Pandas data frame'
                      size_hint_y: 0.1
                      on_press: root.initTextOutput()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-09-23
        • 1970-01-01
        • 1970-01-01
        • 2017-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-08
        相关资源
        最近更新 更多