Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

tablelist problem with <Configure> callback

75 views
Skip to first unread message

Busirane

unread,
Apr 26, 2018, 8:49:28 AM4/26/18
to
Hello:

I'm trying to use Csaba Nemethi's wonderful tablelist widget as a virtualized tree display, meaning that it contains only the rows that should be visible and is updated in response to scroll and resize events. The full dataset could be millions of rows and is kept in a SQLite database. I'm running into a problem (not necessarily a bug, but a discrepancy) between how "insertlist" and "insertchildlist" are handled in a <Configure> callback. The problem occurs in tablelist 5.7 and 5.16, which are the two versions available to me due to constraints on the tclkits I can use (KBS 0.4.4 and 0.4.9). This minimal code demonstrates the main problem and a second, possibly related, problem:

proc fill {t} {
set data [list [list [winfo geometry $t]] {"row 2"} {"etc..."}]
$t delete 0 end
$t insertlist end $data
$t insertchildlist root end $data ;# problem 1
}

puts [package require tablelist]
tablelist::tablelist .t -columns {0 data}
pack .t -fill both -expand 1
fill .t
bind .t <Configure> {+ fill .t} ;# problem 2
console show

Problem 1 is that you can't resize the window. It *starts* to resize, but then it snaps back, which knocks it out from under the mouse and ends the drag operation. If you comment out the problem 1 line, then window resizing works as expected but a second problem occurs.

Problem 2 is these two errors on startup:

Error: bad text index ""
Error: can't read "data(rowsToDisplay)": no such element in array

These errors are harmless in that things work if you click past them. Tablelist 5.7 reports both errors, but 5.16 reports only the second error. You can eliminate these errors by binding the <Configure> callback to [.t bodypath] instead of .t directly, but that is nonintuitive.

Q1: Is there a way to use the "insertchild*" commands from within a <Configure> callback without the undesired snap back behavior? I checked and there aren't any other bindings on .t or .t.body.

Q2: Is there a way to query the current height in rows, without computing it from the widget, label, body, and font heights? Perhaps "data(rowsToDisplay)"?

Harald Oehlmann

unread,
Apr 26, 2018, 8:54:37 AM4/26/18
to
Has you tried to bind like that ?
bind [.t bodypath] ...
or
bind [.t bodytag]
?
Just an idea...

Harald

Busirane

unread,
Apr 26, 2018, 10:12:59 AM4/26/18
to
On Thursday, April 26, 2018 at 8:54:37 AM UTC-4, Harald Oehlmann wrote:
> Has you tried to bind like that ?
> bind [.t bodypath] ...

Harald:

Yes, I tried that. It eliminates the Problem 2 errors, but doesn't affect the Problem 1 resize behavior.

martyn....@gmail.com

unread,
Apr 27, 2018, 5:12:44 AM4/27/18
to
Le jeudi 26 avril 2018 14:49:28 UTC+2, Busirane a écrit :
> Hello:
>
> I'm trying to use Csaba Nemethi's wonderful tablelist widget as a virtualized tree display, meaning that it contains only the rows that should be visible and is updated in response to scroll and resize events. The full dataset could be millions of rows and is kept in a SQLite database. I'm running into a problem (not necessarily a bug, but a discrepancy) between how "insertlist" and "insertchildlist" are handled in a <Configure> callback.

Hello,

I too have been working on this same problem, using TableList, without the tree part as I deemed it too complicated for me. We have a filtering mechanism to reduce the view to more manageable sizes. I have a prototype working, and can confirm the edge cases of scrolling and resizing were problematic, but I did not have your problems.

I have very little spare time to work on the problem, but could share the code and any ideas I had, its a bit rough at the moment as it was mostly to test out mechanisms and ideas, maybe working together would accelerate the work.

I'm sure Harald remembers the presentation at Munich.
I will probably go to the European conference at Munich again this year.

Martyn

Busirane

unread,
Apr 27, 2018, 9:10:44 AM4/27/18
to
On Friday, April 27, 2018 at 5:12:44 AM UTC-4, martyn....@gmail.com wrote:
> I too have been working on this same problem [...] I have a prototype working, and can confirm the edge cases of scrolling and resizing were problematic, but I did not have your problems.
>
> I have very little spare time to work on the problem, but could share the code and any ideas I had, its a bit rough at the moment as it was mostly to test out mechanisms and ideas, maybe working together would accelerate the work.

Martyn:

If you don't mind, I would like to see your code so I can see how you handled these problems. It's clear that the "insertchild*" commands do *something* that the "insert*" commands don't, but I haven't put my finger on it yet. I've tried many things without success, and I'm starting to think there's a window manager interaction too. I should have mentioned this is on Windows 10. The snap back behavior seems to only occur while the mouse is still down for the resize drag operation. If resize the window from the console and call [fill], the snap back behavior doesn't occur.

nemethi

unread,
Apr 27, 2018, 1:54:16 PM4/27/18
to
Am 26.04.2018 um 14:49 schrieb Busirane:
Modify your test script to become:

proc fill {t} {
if {$::gotConfigureEvent} {
set ::gotConfigureEvent 0
after 1000 [list fill $t]
return
}

set data [list [list [winfo geometry $t]] {"row 2"} {"etc..."}]
$t delete 0 end
$t insertlist end $data
$t insertchildlist root end $data ;# problem 1
}

puts [package require tablelist]
tablelist::tablelist .t -columns {0 data}
pack .t -fill both -expand 1
set gotConfigureEvent 0
fill .t
bind .t <Configure> {+ set gotConfigureEvent 1; fill .t} ;# problem 2

This will solve problem 2, which is present on all platforms and is
related to the fact that the insertlist invocation interferes badly with
some internal tablelist actions triggered by the <Configure> event.

Problem 1 is Windows-specific, it doesn't occur in other environments
(at least not on X11). It is caused by unexpected <Configure> events,
generated when embedded windows within a text widget are destroyed. I
have not yet found a solution to this strange Windows behavior. The
above changes in your code at least alleviate the problem to some
extent, making it possible for the user to resize the window if he or
she releases the mouse button within a few seconds.

Answer to Q1: I hope there is a way, but I haven't found it yet. :-(

Answer to Q2: data(rowsToDisplay) is definitely not the current height
in rows. Instead, you can retrieve it as foolows:

set topRow [$t index top]
set btmRow [$t index bottom]
set heightInRows [$t viewablerowcount $topRow $btmRow]

Note that the viewablerowcount subcommand was introduced in Tablelist 5.10.

--
Csaba Nemethi http://www.nemethi.de mailto:csaba....@t-online.de

nemethi

unread,
Apr 28, 2018, 7:53:25 AM4/28/18
to
Here is a significantly improved version of your test script:

proc fill {t} {
if {[info exists ::afterId]} {
after cancel ::afterId
unset ::afterId
}

set data [list [list [winfo geometry $t]] {"row 2"} {"etc..."}]
$t delete 0 end
$t insertlist end $data
$t insertchildlist root end $data ;# problem 1
}

proc onConfigureEvent {t height} {
if {$height != $::height} {
set ::height $height
if {![info exists ::afterId]} {
set ::afterId [after 1000 [list fill $t]]
}
}
}

puts [package require tablelist]
tablelist::tablelist .t -columns {0 data}
pack .t -fill both -expand 1
set height 0
fill .t
bind .t <Configure> {+ onConfigureEvent %W %h} ;# problem 2

This version behaves much smoother than the one that I posted yesterday.
In addition, it takes into account that filling the tablelist is only
needed if the widget's height has changed.

Busirane

unread,
May 3, 2018, 10:38:54 AM5/3/18
to
On Saturday, April 28, 2018 at 7:53:25 AM UTC-4, nemethi wrote:
> This version behaves much smoother than the one that I posted yesterday.
> In addition, it takes into account that filling the tablelist is only
> needed if the widget's height has changed.

Thank you, Csaba. Holding off the update until the resize drag is over, or nearly over, seems to be the only viable solution until you can solve the underlying mystery.
0 new messages