in reply to Tk performance and "UpdateWrapper: Failed to create container"
Providing a prosaic description of your code, rather than actual code, is an exceptionally poor choice. This greatly hampers our ability to provide improved code. Please don't do this. See "How do I post a question effectively?" and SSCCE.
"Is it possible to disable the GUI Event mechanisms, ..."
Check the documentation on a widget-by-widget basis. Interactive widgets often have a -state option, with possible values such as disabled and readonly, which may be sufficient for your needs. For greater control of events, try Tk::bind (and do follow the additional links at the end of that page).
"Is it possible to disable the binding of variables to widgets, like -textvariable for Entry widgets?"
I expect you mean something else. The obvious answer to your question is don't use a -textvariable option. If you meant "delay" rather than "disable", see Tk::options.
"I have already replaced some really slow superwidgets for leaner alternative (e.g. JBrowseEntry for BrowseEntry) but maybe there are leaner widgets still?"
Maybe there are. Without any code, how could anyone tell which widgets you consider slow?
Again, no code, no answer possible.
|Replies are listed 'Best First'.|
Re^2: Tk performance and "UpdateWrapper: Failed to create container"
by olgo (Acolyte) on Jan 17, 2022 at 11:56 UTC
Noticable in this example is that the code up till Mainloop is actually quite fast, but then it takes a couple of seconds until the whole GUI is drawn.
by Marshall (Canon) on Jan 18, 2022 at 00:41 UTC
I built one application with the TableMatrix widget in a scrolled up/down, left/right frame. 100,000 cells was no problem -> eye-blink length of time. For operations on particular cells (like delete column, or even create new view into the database requiring yet another spreadsheet), I put in mouse a right click handler.
Back in the day in which I wrote that code, the target platform was Win XP laptops with limited memory and essentially single core P5 processor. My code ran great on that Win XP platform - much, much faster than this code.
I do remember that I did one ugly thing, I broke OO encapsulation and manipulated the TableMatrix object's storage directly. The "TableMatrix" is basically a hash table
My code went EOL (End of Life) years ago. But, if you are interested, I can find an archived copy from 2008 and build a demo for you.
The main idea is to look at TableMatrix which is a single widget instead of fiddling around with many thousands of widgets. (emphasis added in an update)
UPDATE: DEMO code added:
The code below has something like 100x (or even more) than the performance of the code using grid to pack in entry objects. When Perl starts, poof... the matrix is there!
This is a hack of some code from more than a decade ago. But it does demo the speed of TableMatrix.
Many details like how to dynamically re-size the number of rows displayed in the matrix screen have answers, but at the moment, my brain is unable to remember the details (geez, its been >10 years!) and the Perl I wrote a decade+ ago is not as easy to understand as the code that I write now. (Duh!).
The code below does break OO encapsulation for direct manipulation of the TableMatrix main data table internal structure - but not for any other aspects of the object (column widths, etc). This does circumvent any unwanted display updates when a massive re-organization the matrix is desired - perhaps sort a column? From memory, for a column sort, I transformed the entire hash table Matrix representation to an array of array, used an ST to sort that, then transformed back to the hash table representation. Then called my "set_col_width()" routine which I aliased to "refresh display()".
Anyway, this idea is something to consider...
TableMatrix is a complicated critter. Plan on spending quite a few hours experimenting and fine tuning the code to get exactly what you want. Not every behavior is documented in detail (otherwise the man page would be 300 pages!).
Update to Update:
I do note some differences in the Tk display. The "slider" bar now doesn't get "smaller" based upon the number of rows to scroll. That control used to compress to such a small height (based upon total number of rows) that it was hard to "get ahold of with the mouse". That is no longer true although I notice that scrolling appears to be not as smooth with say 2,000 rows.
One thing to be wary of, is that it can be hard to be absolutely sure that you have scrolled to the "end of all rows". In my application, I always added 5 blank rows to the end any data display. If you don't see at least one blank row, then you are not at the "end of data rows". These are the details that make a difference.
by olgo (Acolyte) on Jan 20, 2022 at 15:24 UTC
I implemented a soft autosizing function that works sufficiently.
What does not work, however, is when I have finished all my grids and just want to adapt the main window to cover all the TableMatrices (I have several, but the problem goes already for a single one). My legacy solution to this is to call reqwidth and then update the main window's geometry accordingly, to a certain limit. Geometry handlers should handle the rest.
But it seems that the reqwidth reported is not the actual widths after calling ->colWidth. I guess it is some pixel/character issue.
Appended some not working code for autosizing at the end of the above example:
Strangely enough, the reqwidth is updated (637 without->827 with colWidth), but not to the value required to show the whole TableMatrix.
by cavac (Vicar) on Jan 18, 2022 at 13:59 UTC
There are two related ways that i know to speed this up dramatically. Both have to do with the fact that the main spreadsheet area doesn't actually have to use "real" widgets. In both cases, you just draw the data and any visual sugar as graphics.
The first way is the classic spreadsheet way: You have one long editable field near the top of the screen. If you select a cell (calculate from the mouse click on the graphics which cells this would be), put its value in the edit field. Every time that value changes, redraw the appropriate part of the graphics, so the user thinks they are simultaneously editing the actual value in the table.
The main advantage of doing the spreadsheet as simple graphics is speed and memory usage: All you do is print some text and paint some lines. Doesn't need to bless a gazillion instances and register a gazillion callbacks. You basically only have two callbacks: Mouseclicks (selecting cells) and scrolling.
For moving between cells with the cursor/tab keys, you would just get those from the one and only editable widget.
perl -e 'use Crypt::Digest::SHA256 qw[sha256_hex]; print substr(sha256_hex("the Answer To Life, The Universe And Everything"), 6, 2), "\n";'
by olgo (Acolyte) on Jan 19, 2022 at 15:46 UTC
I actually combined your idea with Marshall's and ended up with a blazingly fast simple Tk::TableMatrix based spreadsheet in which I replace the cell over which the mouse pointer currently hovers with an actual editable widget. I had to rewrite quite a few GUI mechanisms (binds, binds, binds...) but some 10 hours later I am pretty much back to where I started, only with a responsive GUI.
Only things I miss are autowidth of columns (my data differs quite a bit in size within the columns) and balloons. I guess you just can't have it all. Maybe I could attach a balloon to the cell I am currently hovering over but that would require me to first replace the TableMatrix cell with a (Tk::Label) widget, like I do for editable cells.