首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python继承/多态性

Python继承/多态性
EN

Stack Overflow用户
提问于 2020-04-07 08:26:22
回答 1查看 87关注 0票数 0

我在玩Python库:

读文档

PopUpDialog

有一个名为PopUpDialog的对象,基类为框架类型。

can_scroll=True.是框架对象的字段之一。

我希望这个字段False,当我实例化时,这样就会有,没有scoll吧

我试图创建一个名为so的新类

代码语言:javascript
复制
class PopUpDialogNoScroll(PopUpDialog):
    super(PopUpdDialogNoScroll, self).__init__(screen,...

代码语言:javascript
复制
class PopUpDialogNoScroll(Frame):
    super(PopUpdDialogNoScroll, self).__init__(screen,...

然而,我所有的尝试都导致了一个错误,比如“给出了7个参数2是预期的”。

有人能指出如何派生类并设置父级和/或祖父母类的字段吗?

谢谢,祝你身体健康

编辑多亏了获奖99,但是滚动条仍然是可见的。这里我有一些演示代码。

代码语言:javascript
复制
from asciimatics.widgets import Frame, ListBox, Layout, Divider, Text, TextBox, Widget, Button, Label, DropdownList, PopUpDialog, CheckBox, RadioButtons, PopupMenu
from asciimatics.scene import Scene
from asciimatics.screen import Screen
from asciimatics.exceptions import ResizeScreenError, NextScene, StopApplication, InvalidFields


class PopUpDialogNoScroll(PopUpDialog):
    def __init__(self, *args, **kwargs):
        super(PopUpDialogNoScroll, self).__init__(*args, **kwargs)
        self.can_scroll = False
        self.has_border = False


class DemoView(Frame):
    def __init__(self, screen):
        super(DemoView, self).__init__(screen,
                                          11,
                                          48,
                                          data=None,
                                          on_load=None,
                                          has_border=True,
                                          hover_focus=True,
                                          name=None,
                                          title="Welcome",
                                          x=None,
                                          y=None,
                                          has_shadow=False,
                                          reduce_cpu=False,
                                          is_modal=False,
                                          can_scroll=False)


        body = Layout([1], fill_frame=True)
        self.add_layout(body)
        button = Button("Click me", self.clicked, label=None)
        body.add_widget(button, 0)


    def clicked(self):
      self._scene.add_effect(
          PopUpDialogNoScroll(self.screen, "1..\n2..\n3..\n4..\n5..  ", ["OK"], on_close=self.done, has_shadow=False, theme='info'))

    def done(self):
        pass


last_scene = None

def demo(screen, scene):
  scenes = [
    Scene([DemoView(screen)], duration=-1, clear=True, name="demo"),
  ]

  screen.play(scenes, stop_on_resize=False, unhandled_input=None, start_scene=scene, repeat=True, allow_int=True)

Screen.wrapper(demo, catch_interrupt=True, arguments=[last_scene])
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-07 08:38:33

首先,对超级程序的任何调用都应该在类自己的__init__函数的第一行中进行。因此,您的类应该有自己的__init__函数。然后,要将所有想要的参数传递给原始类,可以提供两个参数来合并继承的类所包含的所有参数:*args**kwargs。然后,可以在can_scroll函数中显式地将__init__字段设置为False,如下所示:

代码语言:javascript
复制
class PopUpDialogNoScroll(PopUpDialog):
    def __init__(self, *args, **kwargs):
        super(PopUpDialogNoScroll, self).__init__(*args, **kwargs)
        self.can_scroll = False

通过拥有*args**kwargs,您可以传入原始PopUpDialog类所期望的任何参数,而不必显式重写它们,并且可以将它们提供给super类。

编辑:当您将代码迁移到Python3时,可以将super调用更改为以下内容,这是Python3:super().__init(*args, **kwargs)中的新语法。注意,唯一的区别是不必显式地指定类名和self引用

编辑2:查看源代码提供的这里,我可以通过复制用于PopUpDialog类的任何代码来创建PopUpDialogNoScroll类,然后从源代码中更改这一行:

super(PopUpDialog, self).__init__(screen, height, width, self._data, has_shadow=has_shadow, is_modal=True)

至:

super(PopUpDialogNoScroll, self).__init__(screen, height, width, self._data, has_shadow=has_shadow, is_modal=True, can_scroll=False)

不是最优雅的解决方案,但它有效。

代码语言:javascript
复制
from asciimatics.widgets import Frame, ListBox, Layout, Divider, Text, TextBox, Widget, Button, Label, DropdownList, PopUpDialog, CheckBox, RadioButtons, PopupMenu
from asciimatics.scene import Scene
from asciimatics.screen import Screen
from asciimatics.exceptions import ResizeScreenError, NextScene, StopApplication, InvalidFields
from wcwidth import wcswidth
from functools import partial

def _enforce_width(text, width, unicode_aware=True):
    """
    Enforce a displayed piece of text to be a certain number of cells wide.  This takes into
    account double-width characters used in CJK languages.
    :param text: The text to be truncated
    :param width: The screen cell width to enforce
    :return: The resulting truncated text
    """
    # Double-width strings cannot be more than twice the string length, so no need to try
    # expensive truncation if this upper bound isn't an issue.
    if (2 * len(text) < width) or (len(text) < width and not unicode_aware):
        return text

    # Can still optimize performance if we are not handling unicode characters.
    if unicode_aware:
        size = 0
        for i, c in enumerate(str(text)):
            w = wcwidth(c) if ord(c) >= 256 else 1
            if size + w > width:
                return text[0:i]
            size += w
    elif len(text) + 1 > width:
        return text[0:width]
    return text

def _split_text(text, width, height, unicode_aware=True):
    """
    Split text to required dimensions.
    This will first try to split the text into multiple lines, then put a "..." on the last
    3 characters of the last line if this still doesn't fit.
    :param text: The text to split.
    :param width: The maximum width for any line.
    :param height: The maximum height for the resulting text.
    :return: A list of strings of the broken up text.
    """
    # At a high level, just try to split on whitespace for the best results.
    tokens = text.split(" ")
    result = []
    current_line = ""
    string_len = wcswidth if unicode_aware else len
    for token in tokens:
        for i, line_token in enumerate(token.split("\n")):
            if string_len(current_line + line_token) > width or i > 0:
                # Don't bother inserting completely blank lines - which should only happen on the very first
                # line (as the rest will inject whitespace/newlines)
                if len(current_line) > 0:
                    result.append(current_line.rstrip())
                current_line = line_token + " "
            else:
                current_line += line_token + " "

    # At this point we've either split nicely or have a hugely long unbroken string (e.g. because the
    # language doesn't use whitespace.  Either way, break this last line up as best we can.
    current_line = current_line.rstrip()
    while string_len(current_line) > 0:
        new_line = _enforce_width(current_line, width, unicode_aware)
        result.append(new_line)
        current_line = current_line[len(new_line):]

    # Check for a height overrun and truncate.
    if len(result) > height:
        result = result[:height]
        result[height - 1] = result[height - 1][:width - 3] + "..."

    # Very small columns could be shorter than individual words - truncate
    # each line if necessary.
    for i, line in enumerate(result):
        if len(line) > width:
            result[i] = line[:width - 3] + "..."
    return result

class PopUpDialogNoScroll(Frame):
    """
    A fixed implementation Frame that provides a standard message box dialog.
    """

    def __init__(self, screen, text, buttons, on_close=None, has_shadow=False, theme="warning"):
        """
        :param screen: The Screen that owns this dialog.
        :param text: The message text to display.
        :param buttons: A list of button names to display. This may be an empty list.
        :param on_close: Optional function to invoke on exit.
        :param has_shadow: optional flag to specify if dialog should have a shadow when drawn.
        :param theme: optional colour theme for this pop-up.  Defaults to the warning colours.
        The `on_close` method (if specified) will be called with one integer parameter that
        corresponds to the index of the button passed in the array of available `buttons`.
        Note that `on_close` must be a static method to work across screen resizing.  Either it
        is static (and so the dialog will be cloned) or it is not (and the dialog will disappear
        when the screen is resized).
        """
        # Remember parameters for cloning.
        self._text = text
        self._buttons = buttons
        self._on_close = on_close

        # Decide on optimum width of the dialog.  Limit to 2/3 the screen width.
        string_len = wcswidth if screen.unicode_aware else len
        width = max([string_len(x) for x in text.split("\n")])
        width = max(width + 2,
                    sum([string_len(x) + 4 for x in buttons]) + len(buttons) + 5)
        width = min(width, screen.width * 2 // 3)

        # Figure out the necessary message and allow for buttons and borders
        # when deciding on height.
        dh = 4 if len(buttons) > 0 else 2
        self._message = _split_text(text, width - 2, screen.height - dh, screen.unicode_aware)
        height = len(self._message) + dh

        # Construct the Frame
        self._data = {"message": self._message}
        super(PopUpDialogNoScroll, self).__init__(
            screen, height, width, self._data, has_shadow=has_shadow, is_modal=True, can_scroll=False)

        # Build up the message box
        layout = Layout([width - 2], fill_frame=True)
        self.add_layout(layout)
        text_box = TextBox(len(self._message), name="message")
        text_box.disabled = True
        layout.add_widget(text_box)
        layout2 = Layout([1 for _ in buttons])
        self.add_layout(layout2)
        for i, button in enumerate(buttons):
            func = partial(self._destroy, i)
            layout2.add_widget(Button(button, func), i)
        self.fix()

        # Ensure that we have the right palette in place
        self.set_theme(theme)

    def _destroy(self, selected):
        self._scene.remove_effect(self)
        if self._on_close:
            self._on_close(selected)

    def clone(self, screen, scene):
        """
        Create a clone of this Dialog into a new Screen.
        :param screen: The new Screen object to clone into.
        :param scene: The new Scene object to clone into.
        """
        # Only clone the object if the function is safe to do so.
        if self._on_close is None or isfunction(self._on_close):
            scene.add_effect(PopUpDialog(screen, self._text, self._buttons, self._on_close))

class DemoView(Frame):
    def __init__(self, screen):
        super(DemoView, self).__init__(screen,
                                          11,
                                          48,
                                          data=None,
                                          on_load=None,
                                          has_border=True,
                                          hover_focus=True,
                                          name=None,
                                          title="Welcome",
                                          x=None,
                                          y=None,
                                          has_shadow=False,
                                          reduce_cpu=False,
                                          is_modal=False,
                                          can_scroll=False)


        body = Layout([1], fill_frame=True)
        self.add_layout(body)
        button = Button("Click me", self.clicked, label=None)
        body.add_widget(button, 0)


    def clicked(self):
      self._scene.add_effect(
          PopUpDialogNoScroll(self.screen, "1..\n2..\n3..\n4..\n5..  ", ["OK"], on_close=self.done, has_shadow=False, theme='info'))

    def done(self):
        pass


last_scene = None

def demo(screen, scene):
  scenes = [
    Scene([DemoView(screen)], duration=-1, clear=True, name="demo"),
  ]

  screen.play(scenes, stop_on_resize=False, unhandled_input=None, start_scene=scene, repeat=True, allow_int=True)

Screen.wrapper(demo, catch_interrupt=True, arguments=[last_scene])
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61075773

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档