digitalmars.D.learn - GtkD - how to list 0..100K strings
- mark (44/44) Apr 26 2020 I'm trying to develop an application in GtkD.
- Mike Wey (5/22) Apr 26 2020 The code looks correct, do you have something that compiles so that we
- mark (81/81) Apr 27 2020 I've now got it to work but it is unusable!
- mark (17/17) Apr 27 2020 I renamed the class shown in my previous post from View to
- mark (18/18) Apr 27 2020 With the new code if I have 1000s of rows I get this error:
- mark (136/136) Apr 27 2020 : dub build
- Adam D. Ruppe (6/7) Apr 27 2020 The GC sends that signal to pause other threads when it is about to
- mark (4/13) Apr 27 2020 Thanks Adam, I took your advice and now have a bt.
- Kagamin (7/24) Apr 28 2020 Try this:
- drug (7/9) Apr 26 2020 Sorry for offtopic, imho both Qt and Gtk are too complex in case of
I'm trying to develop an application in GtkD. I need a widget to display a list of strings: there could be anything from 0 to 100K strings, but typically a few hundred or thousand. Using the DemoCustomList as a model I have created this code: // Note: DebNames is an AAset!string (AAset is a wrapper around a D AA, so in this case a set of strings) // namestore.d import gtk.ListStore: ListStore; class NameStore : ListStore { this(DebNames names) { import gobject.c.types: GType; import gtk.TreeIter: TreeIter; super([GType.STRING]); TreeIter iter; foreach (name; names) { append(iter); setValue(iter, 0, name); } } } // appwindow.d final class AppWindow: ApplicationWindow { TreeView debsTreeView; NameStore nameStore; // ... private void populateNames(DebNames names) { import gtk.CellRendererText: CellRendererText; import gtk.TreeViewColumn: TreeViewColumn; nameStore = new NameStore(names); auto column = new TreeViewColumn; auto renderer = new CellRendererText; column.packStart(renderer, true); column.addAttribute(renderer, "text", 0); column.setTitle("Names"); debsTreeView.appendColumn(column); } } When populateNames() is called the treeview expands horizontally but shows nothing, so I'm stuck. Can anyone help? Note that I don't have to use a tree widget if there's a better one for this use case. I did see ListBox but that seemed to be a list of widgets which would be a bit heavy for 100K strings?
Apr 26 2020
On 26-04-2020 10:06, mark wrote:I'm trying to develop an application in GtkD. I need a widget to display a list of strings: there could be anything from 0 to 100K strings, but typically a few hundred or thousand. Using the DemoCustomList as a model I have created this code: ... When populateNames() is called the treeview expands horizontally but shows nothing, so I'm stuck. Can anyone help? Note that I don't have to use a tree widget if there's a better one for this use case. I did see ListBox but that seemed to be a list of widgets which would be a bit heavy for 100K strings?The code looks correct, do you have something that compiles so that we can test where things go wrong? -- Mike Wey
Apr 26 2020
I've now got it to work but it is unusable! It can show small numbers of rows with no problem. However, if it has to show 100s of rows it expands the tree vertically way beyond the bottom of the screen and is impossible to navigate. However, if it has to show 1000s of rows it goes into an infinite loop producing endless error messages: (DebFind:6615): Gtk-WARNING **: 10:57:04.275: infinite surface size not supported I suppose I was expecting scrollbars to appear, but maybe with Gtk you have do add them separately? // Here's the view I'm now using class View : TreeView { import gtk.CellRendererText: CellRendererText; import gtk.TreeViewColumn: TreeViewColumn; import qtrac.debfind.modelutil: NameAndDescription; import qtrac.debfind.viewdata: ViewData; ViewData viewData; TreeViewColumn nameColumn; TreeViewColumn descriptionColumn; this() { super(); setActivateOnSingleClick(true); viewData = new ViewData; setModel(viewData); auto renderer = new CellRendererText; nameColumn = new TreeViewColumn("Name", renderer, "text", 0); nameColumn.setResizable(true); appendColumn(nameColumn); renderer = new CellRendererText; descriptionColumn = new TreeViewColumn("Description", renderer, "text", 1); descriptionColumn.setResizable(true); appendColumn(descriptionColumn); } void clear() { viewData.clear; } void populate(NameAndDescription[] namesAndDescriptions) { viewData.populate(namesAndDescriptions); } } // Here's the ListStore I'm using: class ViewData : ListStore { import qtrac.debfind.modelutil: NameAndDescription; this() { import gobject.c.types: GType; super([GType.STRING, GType.STRING]); } void populate(NameAndDescription[] namesAndDescriptions) { import gtk.TreeIter: TreeIter; clear; TreeIter iter; foreach (i, nameAndDescription; namesAndDescriptions) { append(iter); setValue(iter, 0, nameAndDescription.name); setValue(iter, 1, nameAndDescription.description); } } } // I have the TreeView side-by-side with a TextView: here're snippets: Paned splitter; View debsView; TextView debTextView; ... splitter = new Paned(GtkOrientation.HORIZONTAL); splitter.setWideHandle(true); debsView = new View; debsView.setHexpand(true); debsView.setVexpand(true); debTextView = new TextView; ... auto grid = new Grid; ... splitter.pack1(debsView, false, true); splitter.pack2(debTextView, true, true); grid.attach(splitter, 0, 3, 6, 1);
Apr 27 2020
I renamed the class shown in my previous post from View to InnerView, then created a new View class: class View : ScrolledWindow { import qtrac.debfind.modelutil: NameAndDescription; InnerView innerView; this() { super(); innerView = new InnerView; addWithViewport(innerView); } void clear() { innerView.viewData.clear; } void populate(NameAndDescription[] namesAndDescriptions) { innerView.viewData.populate(namesAndDescriptions); } }
Apr 27 2020
With the new code if I have 1000s of rows I get this error: (DebFind:8087): Gdk-ERROR **: 11:50:46.787: The program 'DebFind' received an X Window System error. This probably reflects a bug in the program. The error was 'BadAlloc (insufficient resources for operation)'. (Details: serial 8810 error_code 11 request_code 130 (MIT-SHM) minor_code 5) (Note to programmers: normally, X errors are reported asynchronously; that is, you will receive the error a while after causing it. To debug your program, run it with the GDK_SYNCHRONIZE environment variable to change this behavior. You can then get a meaningful backtrace from your debugger if you break on the gdk_x_error() function.) Program exited with code -5 This means the program is unusable (again) because there are often queries that result in 1000s of rows of results.
Apr 27 2020
: dub build Performing "debug" build using /home/mark/opt/ldc2-1.21.0-linux-x86_64/bin/ldc2 for x86_64. aaset 0.2.5: target for configuration "library" is up to date. gtk-d:gtkd 3.9.0: target for configuration "library" is up to date. debfind ~master: target for configuration "application" is up to date. To force a rebuild of up-to-date targets, run again with --force. : gdb DebFind GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git [snip] Reading symbols from DebFind...done. (gdb) run Starting program: /home/mark/app/d/debfind/DebFind [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". [New Thread 0x7fffeddfc700 (LWP 8186)] [New Thread 0x7fffed5fb700 (LWP 8187)] [New Thread 0x7fffe7fff700 (LWP 8188)] [New Thread 0x7ffff7fe2700 (LWP 8189)] [New Thread 0x7ffff7fdc700 (LWP 8190)] [New Thread 0x7ffff7fd6700 (LWP 8191)] [New Thread 0x7ffff7e64700 (LWP 8192)] [New Thread 0x7ffff7e5e700 (LWP 8193)] [New Thread 0x7ffff7e58700 (LWP 8194)] [New Thread 0x7ffff7e52700 (LWP 8195)] Thread 1 "DebFind" received signal SIGUSR1, User defined signal 1. 0x00007ffff50ba2ea in ?? () from /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 (gdb) bt /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 /lib/x86_64-linux-gnu/libexpat.so.1 /lib/x86_64-linux-gnu/libexpat.so.1 /lib/x86_64-linux-gnu/libexpat.so.1 /lib/x86_64-linux-gnu/libexpat.so.1 /lib/x86_64-linux-gnu/libexpat.so.1 /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 /lib/x86_64-linux-gnu/libexpat.so.1 /lib/x86_64-linux-gnu/libexpat.so.1 /lib/x86_64-linux-gnu/libexpat.so.1 /lib/x86_64-linux-gnu/libexpat.so.1 /lib/x86_64-linux-gnu/libexpat.so.1 /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 /usr/lib/x86_64-linux-gnu/libpangocairo-1.0.so.0 /usr/lib/x86_64-linux-gnu/libpangoft2-1.0.so.0 /usr/lib/x86_64-linux-gnu/libpango-1.0.so.0 warning: (Internal error: pc 0x55555584c444 in read in psymtab, but not in symtab.) warning: (Internal error: pc 0x55555584c430 in read in psymtab, but not in symtab.) warning: (Internal error: pc 0x55555584c444 in read in psymtab, but not in symtab.) /usr/lib/x86_64-linux-gnu/libpango-1.0.so.0 warning: (Internal error: pc 0x55555584c444 in read in psymtab, but not in symtab.) /usr/lib/x86_64-linux-gnu/libpango-1.0.so.0 () at /usr/lib/x86_64-linux-gnu/libpango-1.0.so.0 /usr/lib/x86_64-linux-gnu/libgtk-3.so.0 /usr/lib/x86_64-linux-gnu/libgtk-3.so.0 /usr/lib/x86_64-linux-gnu/libgtk-3.so.0 /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0 /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0 /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0 /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0 (this=0x7ffff7f98800) at Entry.d:215 qtrac.debfind.appwindow.AppWindow.makeWidgets() (this=0x7ffff7ed7a00) at appwindow.d:85 _D5qtrac7debfind9appwindow9AppWindow6__ctorMFC3gtk11ApplicationQnZCQCnQCkQCfQBy (this=0x7ffff7ed7a00, application=0x7ffff7ed0360) at appwindow.d:62 _D5qtrac7debfind3app4mainFAAyaZ__T12__dgliteral2TC3gio11Appl cationQnZQBkMFQBaZv (GioApplication=0x7ffff7ed0360) at app.d:16 _D7gobject8DClosureQj__T17d_closure_marshalTDFC3gio11ApplicationQnZvZQBtUPSQCv1c5types8GClosurePSQDr wQw6GValuekQrPvQcZv (closure=0x555555cd52c0, return_value=0x0, n_param_values=1, param_values=0x7ffff7ef39a0, invocation_hint=0x7fffffffd6e0 "\b", marshal_data=0x0) at DClosure.d:122 /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0 /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0 /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0 /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0 /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0 /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0 (this=0x7ffff7ed0360, argv=...) at Application.d:931
Apr 27 2020
On Mon, Apr 27, 2020 at 10:56:09AM +0000, mark via Digitalmars-d-learn wrote:Thread 1 "DebFind" received signal SIGUSR1, User defined signal 1.The GC sends that signal to pause other threads when it is about to collect. You can tell gdb to just ignore it. handle SIGUSR1 noprint handle SIGUSR2 noprint I added those to my .gdbinit personally.
Apr 27 2020
On Monday, 27 April 2020 at 12:26:23 UTC, Adam D. Ruppe wrote:On Mon, Apr 27, 2020 at 10:56:09AM +0000, mark via Digitalmars-d-learn wrote:Thanks Adam, I took your advice and now have a bt. I have put it in a new message thread: "GtkD crash: 'BadAlloc (insufficient resources for operation)'"Thread 1 "DebFind" received signal SIGUSR1, User defined signal 1.The GC sends that signal to pause other threads when it is about to collect. You can tell gdb to just ignore it. handle SIGUSR1 noprint handle SIGUSR2 noprint I added those to my .gdbinit personally.
Apr 27 2020
On Monday, 27 April 2020 at 10:28:04 UTC, mark wrote:I renamed the class shown in my previous post from View to InnerView, then created a new View class: class View : ScrolledWindow { import qtrac.debfind.modelutil: NameAndDescription; InnerView innerView; this() { super(); innerView = new InnerView; addWithViewport(innerView); } void clear() { innerView.viewData.clear; } void populate(NameAndDescription[] namesAndDescriptions) { innerView.viewData.populate(namesAndDescriptions); } }Try this: void populate(NameAndDescription[] namesAndDescriptions) { if(namesAndDescriptions.length>100)namesAndDescriptions=namesAndDescriptions[0..100]; innerView.viewData.populate(namesAndDescriptions); }
Apr 28 2020
On Tuesday, 28 April 2020 at 18:46:18 UTC, Kagamin wrote:Try this: void populate(NameAndDescription[] namesAndDescriptions) { if(namesAndDescriptions.length>100)namesAndDescriptions=namesAndDescriptions[0..100]; innerView.viewData.populate(namesAndDescriptions); }I tried that and it worked fine. So I then used a binary chop and discovered that 0..n where n <= 1170 works fine; n > 1170 crashes. I'm not sure where that takes me but seems suggestive that the problem is Gtk or GtkD rather than my code?
Apr 28 2020
Continuing this in the GtkD mailing list: https://forum.gtkd.org/groups/GtkD/thread/1370/
Apr 29 2020
26.04.2020 11:06, mark пишет:snippedSorry for offtopic, imho both Qt and Gtk are too complex in case of virtual list/tree view. I think the reason is they are retained mode gui. I gave up to use them for that and develop custom virtual tree view that is easy in use and currently capable to handle over 2M heterogeneous items. But it is in alpha state and for general use needs much more attention.
Apr 26 2020