nucleic / enaml

Declarative User Interfaces for Python
http://enaml.readthedocs.io/en/latest/
Other
1.53k stars 130 forks source link

'Include' hides re-appended objects even though destroy_old = False #370

Open K3nn3th2 opened 5 years ago

K3nn3th2 commented 5 years ago

as stated, i have an include object with the 'destroy_old' attribute set to false. i can append and remove an object to/from the objects attribute and it gets shown/removed respectively.

when re-appending an object i previously had appended, it does not get shown. interestingly, upon appending more objects, i can see the re-appended one taking up some space in the list, yet without showing any of the widgets.

so the include object is hiding the re-appended object even though destroy_old = False

is this a bug? ill try and make a minimal working example reproducing the error.

sccolbert commented 5 years ago

Please make a minimal example that reproduces the error. The behavior you describe does not sound correct.

On Mon, Sep 9, 2019, 7:01 PM K3nn3th2 notifications@github.com wrote:

as stated, i have an include object with the 'destroy_old' attribute set to false. i can append and remove an object to/from the objects attribute and it gets shown/removed respectively.

when re-appending an object i previously had appended, it does not get shown. interestingly, upon appending more objects, i can see the re-appended one taking up some space in the list, yet without showing any of the widgets.

so the include object is hiding the re-appended object even though destroy_old = False

is this a bug? ill try and make a minimal working example reproducing the error.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/nucleic/enaml/issues/370?email_source=notifications&email_token=AABBQSNEJ66SY37SNMO7CXLQI3PT7A5CNFSM4IVBKVVKYY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4HKJ4KDA, or mute the thread https://github.com/notifications/unsubscribe-auth/AABBQSK3B4GR2YSIQFA36ULQI3PT7ANCNFSM4IVBKVVA .

MatthieuDartiailh commented 5 years ago

From the top of my head, even if the Include does not destroy the widget it hides it. Show the widget when you add it back and you should be fine.

MatthieuDartiailh commented 5 years ago

I also have a memory that this is related to qt behavior when a widget is unparented and not directly something enforced by enaml.

K3nn3th2 commented 5 years ago

Thank you @MatthieuDartiailh ! calling .show() after adding did the trick.

it is rather strange though, i'm using a further Include in my code (also with destroy_old = False) which works perfectly fine when fiddling with its objects attribute, no need to display anything after adding.

anyway, i attached a 'minimal' example.

please excuse the somewhat unusual structure, i tried to keep the example close to my use case in order to see if maybe the structure is causing the strange behaviour.

here is the content of the enaml file (sorry for the strange formatting, the "code" markup doesnt seem to work for enaml code ) :

` from enaml.widgets.api import ( Window, FlowItem, FlowArea, Form, CheckBox, PushButton, ScrollArea, GroupBox, Label, MultilineField, Container, ) from enaml.layout.api import vbox, hbox from enaml.core.api import Include

class Release(object): name = '' def init(self, name): super(Release, self).init() self.name = name

enamldef DownloadListItem(Form): attr release Container: Label: name: text << release.name

enamldef ReleaseItem(FlowItem): attr release attr downloadList attr downloadListItem = DownloadListItem(release = release) preferred_size << (180,250) Container: constraints = [ height >= 200, gBox.width == width, gBox.height == height, ] GroupBox: gBox: constraints = [ info.height == .5 * self.height, info.width == self.width, contents_bottom == toDownload.bottom, contents_left == toDownload.left, ] MultilineField: info: read_only = True

border =

            resist_width = 'weak'
            resist_height = 'weak'
            text << release.name
        CheckBox: toDownload:
            checked << False if downloadListItem not in downloadList else True
            toggled :: 
                if checked:
                    downloadList.append(downloadListItem)
                    print('appended downloadListitem. contents: ' + str(downloadList))
                else:
                    downloadList.remove(downloadListItem)

enamldef Downloader(GroupBox): title = 'Download' alias downloads : downloads

ScrollArea:
    Container:
        Include: downloads:
            destroy_old = False
PushButton:
    text = 'print include objects "destroy_old" value'
    clicked :: print('includes destroy old: ' + str(downloads.destroy_old))

enamldef Main(Window):

func getItems():
    return [ReleaseItem(release=Release(name='Release ' + str(x)), downloadList = dl.downloads.objects) for x in range(5)]

Container:
    constraints=[
        vbox(flow, dl),
        dl.height == 0.5 * height,
        ]
    FlowArea: flow:
        Include: inc:
            destroy_old = False
            objects = getItems()
    Downloader: dl:
        pass

`