【问题标题】:How to display the contents of a dictionary in a morph in smalltalk?如何在smalltalk中以变形显示字典的内容?
【发布时间】:2015-12-26 21:09:21
【问题描述】:

因为我似乎无法找到一些可以显示Dictionary 内容的预定义Morph,所以我决定最好停止寻找并想创建自己的Morph。我找到了nice description 如何从一些不错的示例代码开始让我开始,但很快我就遇到了我似乎无法在画布上绘制文本或类似内容的问题。

我创建了一个类

Morph subclass: #DictionaryView
    instanceVariableNames: 'dictionary'
    classVariableNames: ''
    poolDictionaries: ''
    category: 'StatisticsTool'

我想覆盖drawOn,如下所示:

drawOn: aCanvas

    | x y |
    x := 0.
    y := 0.
    dictionary associationsDo: [ :assoc |
        aCanvas drawString: assoc key at: x@y.
        aCanvas drawString: assoc value at: x+10@y.
        y := y + 10. ].

我知道这并不是最好的一段代码(我还不知道我应该如何考虑最长的字符串等,但我已经到了这个地步,我什至不想再考虑这个了),但我只是想显示一些东西。不幸的是,当我尝试时这似乎不起作用

d := Dictionary new.
d at: 'test1' put: 5.
d at: 'test2' put: 23.
d at: 'test3' put: 514.

view := DictionaryView new.
view dictionary: d.
view openInWorld.

我收到一个错误:Instances of SmallInteger are not indexable

我不知道该怎么办了。我实际上没有时间写这些长长的问题,也没有时间花一整周的时间来寻找这样的东西。这一切都让我非常紧张和不耐烦,因此我想原谅自己直接问:

如何在 Smalltalk 中显示字典以便在 GUI 中使用它?

PS:也欢迎任何应对压力的技巧;)

【问题讨论】:

  • 使用d inspectd explore 怎么样,它们都在字典上打开视图(检查器)。它们甚至允许您编辑对象。
  • 谢谢,但我希望能够在我的问题中提到的 GUI 中显示它...我的问题是否不清楚?
  • 看看Debugger的实现。它正是这样做的。它将上述检查器变形嵌入到自己的 UI 中。你也可以这样做。
  • 我应该在哪里找到它?这可能是一个解决方案,但我希望最终产品看起来像一张简单的桌子……最终的东西应该是一张漂亮、简单的桌子,但恐怕我不得不放弃那个计划……

标签: user-interface smalltalk squeak


【解决方案1】:

你的错误来源在这里

    aCanvas drawString: **assoc key** at: x@y.
    aCanvas drawString: **assoc value** at: x+10@y.

无法保证它们中的任何一个都是字符串(在您的情况下,值是数字),因此您必须手动转换它们

    aCanvas drawString: assoc key printString at: x@y. "or asString"
    aCanvas drawString: assoc value printString at: x+10@y.

您应该能够很容易地调试此类问题。

关于字符串的宽度,可以向字体询问字符串的长度。

Preferences standardDefaultTextFont heightOfString: 'hello'

更新:

您也可以简单地将所有值转换为StringMorphs 并将它们组合在一起。

DictionaryView>>dictionary: aDictionary
    | container keys values |
    (container := Morph new)
        layoutPolicy: TableLayout new;
        listDirection: #leftToRight.
    (keys := Morph new) layoutPolicy: TableLayout new.
    (values := Morph new) layoutPolicy: TableLayout new.
    aDictionary
        associationsDo:
            [ :assoc | 
            keys addMorph: assoc key printString asMorph.
            values addMorph: assoc value printString asMorph ].
    container
        addMorph: keys;
        addMorph: values.
    self addMorph: container

(当然删除 #drawOn: 方法,因为它不再需要)

显然还有很大的改进空间,但这超出了本问答的范围。

您也可以使用MulticolumnLazyListMorph 小部件。

【讨论】:

  • 我必须承认,我的问题很糟糕。我需要它以变形显示以在界面中使用它......对不起。
  • @MrTsjolder 我已经更新了答案;如果你想要别的东西,那么你需要更好地指定你的问题
  • 可以通过哪些方式改进?这对我来说似乎是一个很好的解决方案(可能是因为我整整一周都没有展示任何东西)。还有如何使用那些LazyListMorphs?我一直在研究代码,但我没有找到如何在我的字典中附加数据。无论如何都非常感谢!
  • 通过改进,我想到了它的外观和感觉(我觉得它很难看)。至于(Multicolumn)LazyListMorph我不知道---我使用Pharo和Spec,很少使用Morphic小部件,并且没有这个小部件的示例。最好将其作为单独的问题发布(或在 Squeak 邮件列表中提问)
【解决方案2】:

使用 Canvas 及其绘图 API 主要是为了实现 你自己的基础变形。如果你想构建一个 GUI,你可以尝试使用 现有的 Morphs 作为构建块。

就像调试器/检查器不实现自己的列表变形一样,您 可以使用现有的类。 PluggableListMorphs 使用 LazyListMorphs。您可以插入一个模型 为列表选择行为提供列表和一些选择器。

|list listMorph|
list := Smalltalk allClasses.
listMorph := PluggableListMorph on:list list:#yourself selected:nil changeSelected:nil.
listMorph openInHand

这是一个简单的例子。在现实世界的应用程序中,您将实现一个提供列表的模型类(请参阅 Inspector 或其他工具)。

如果要列出字典内容,可以为两个“子列表”(键、值)构建多列 listMorph, 另一个多列示例:

|listOfLists listMorph|
listOfLists := { (1 to:100) asArray . (1 to:100) collect:[:x | x * x]}.
listMorph := PluggableMultiColumnListMorph on:listOfLists list:#yourself     selected:nil changeSelected:nil.
listMorph openInHand

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-08
    • 1970-01-01
    • 1970-01-01
    • 2019-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多