Jump to page: 1 2
Thread overview
GtkD - how to list 0..100K strings
Apr 26, 2020
mark
Apr 26, 2020
Mike Wey
Apr 27, 2020
mark
Re: GtkD - how to list 0..100K strings [solved]
Apr 27, 2020
mark
Re: GtkD - how to list 0..100K strings: new problem
Apr 27, 2020
mark
It won't run in gdb...
Apr 27, 2020
mark
Apr 27, 2020
Adam D. Ruppe
Apr 27, 2020
mark
Apr 28, 2020
Kagamin
Re: GtkD - how to list 0..100K strings
Apr 28, 2020
mark
Apr 29, 2020
mark
Apr 26, 2020
drug
April 26, 2020
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?
April 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
April 26, 2020
26.04.2020 11:06, mark пишет:
> snipped
> 

Sorry 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.

April 27, 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);


April 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);
    }
}


April 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.
April 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
#0  0x00007ffff50ba2ea in  () at /usr/lib/x86_64-linux-gnu/libfontconfig.so.1
#1  0x00007ffff50bbae5 in  () at /usr/lib/x86_64-linux-gnu/libfontconfig.so.1
#2  0x00007ffff1af0e28 in  () at /lib/x86_64-linux-gnu/libexpat.so.1
#3  0x00007ffff1af1bfc in  () at /lib/x86_64-linux-gnu/libexpat.so.1
#4  0x00007ffff1aef823 in  () at /lib/x86_64-linux-gnu/libexpat.so.1
#5  0x00007ffff1af050b in  () at /lib/x86_64-linux-gnu/libexpat.so.1
#6  0x00007ffff1af40ed in XML_ParseBuffer () at /lib/x86_64-linux-gnu/libexpat.so.1
#7  0x00007ffff50bab43 in  () at /usr/lib/x86_64-linux-gnu/libfontconfig.so.1
#8  0x00007ffff50baf76 in FcConfigParseAndLoad () at /usr/lib/x86_64-linux-gnu/libfontconfig.so.1
#9  0x00007ffff50bafe8 in FcConfigParseAndLoad () at /usr/lib/x86_64-linux-gnu/libfontconfig.so.1
#10 0x00007ffff50bb15e in  () at /usr/lib/x86_64-linux-gnu/libfontconfig.so.1
#11 0x00007ffff1af0e28 in  () at /lib/x86_64-linux-gnu/libexpat.so.1
#12 0x00007ffff1af1bfc in  () at /lib/x86_64-linux-gnu/libexpat.so.1
#13 0x00007ffff1aef823 in  () at /lib/x86_64-linux-gnu/libexpat.so.1
#14 0x00007ffff1af050b in  () at /lib/x86_64-linux-gnu/libexpat.so.1
#15 0x00007ffff1af40ed in XML_ParseBuffer () at /lib/x86_64-linux-gnu/libexpat.so.1
#16 0x00007ffff50bab43 in  () at /usr/lib/x86_64-linux-gnu/libfontconfig.so.1
#17 0x00007ffff50baf76 in FcConfigParseAndLoad () at /usr/lib/x86_64-linux-gnu/libfontconfig.so.1
#18 0x00007ffff50add24 in  () at /usr/lib/x86_64-linux-gnu/libfontconfig.so.1
#19 0x00007ffff50adf76 in  () at /usr/lib/x86_64-linux-gnu/libfontconfig.so.1
#20 0x00007ffff50a1a27 in  () at /usr/lib/x86_64-linux-gnu/libfontconfig.so.1
#21 0x00007ffff50a3ab5 in FcConfigSubstituteWithPat () at /usr/lib/x86_64-linux-gnu/libfontconfig.so.1
#22 0x00007ffff5cfe718 in  () at /usr/lib/x86_64-linux-gnu/libpangocairo-1.0.so.0
#23 0x00007ffff2c97552 in  () at /usr/lib/x86_64-linux-gnu/libpangoft2-1.0.so.0
#24 0x00007ffff5abfa67 in  () at /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.)

#25 0x00007ffff5ac10c0 in pango_itemize_with_base_dir () at /usr/lib/x86_64-linux-gnu/libpango-1.0.so.0
warning: (Internal error: pc 0x55555584c444 in read in psymtab, but not in symtab.)

#26 0x00007ffff5ac974d in  () at /usr/lib/x86_64-linux-gnu/libpango-1.0.so.0
#27 0x00007ffff5acab32 in pango_layout_get_unknown_glyphs_count () at /usr/lib/x86_64-linux-gnu/libpango-1.0.so.0
#28 0x00007fffef522f8a in  () at /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#29 0x00007fffef522ff8 in  () at /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#30 0x00007fffef523168 in  () at /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#31 0x00007ffff69bd9c5 in g_type_create_instance () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#32 0x00007ffff699e748 in  () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#33 0x00007ffff699fee5 in g_object_new_with_properties () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#34 0x00007ffff69a0961 in g_object_new () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#35 0x000055555584c445 in _D3gtk5EntryQg6__ctorMFZCQxQvQx (this=0x7ffff7f98800) at Entry.d:215
#36 0x0000555555749c80 in qtrac.debfind.appwindow.AppWindow.makeWidgets() (this=0x7ffff7ed7a00) at appwindow.d:85
#37 0x0000555555749919 in _D5qtrac7debfind9appwindow9AppWindow6__ctorMFC3gtk11ApplicationQnZCQCnQCkQCfQBy (this=0x7ffff7ed7a00, application=0x7ffff7ed0360) at appwindow.d:62
#38 0x0000555555784449 in _D5qtrac7debfind3app4mainFAAyaZ__T12__dgliteral2TC3gio11ApplicationQnZQBkMFQBaZv (GioApplication=0x7ffff7ed0360) at app.d:16
#39 0x000055555596d234 in _D7gobject8DClosureQj__T17d_closure_marshalTDFC3gio11ApplicationQnZvZQBtUPSQCv1c5types8GClosurePSQDrQwQw6GValuekQrPvQcZv (closure=0x555555cd52c0, return_value=0x0, n_param_values=1, param_values=0x7ffff7ef39a0, invocation_hint=0x7fffffffd6e0 "\b", marshal_data=0x0) at DClosure.d:122
#40 0x00007ffff699910d in g_closure_invoke () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#41 0x00007ffff69ac05e in  () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#42 0x00007ffff69b4715 in g_signal_emit_valist () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#43 0x00007ffff69b512f in g_signal_emit () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#44 0x00007ffff537ec55 in  () at /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0
#45 0x00007ffff537ee66 in g_application_run () at /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0
#46 0x000055555579a2e5 in _D3gio11ApplicationQn3runMFAAyaZi (this=0x7ffff7ed0360, argv=...) at Application.d:931
#47 0x0000555555784390 in D main (args=...) at app.d:18

April 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.
April 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:
>> 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.

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)'"
April 28, 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);
    }
« First   ‹ Prev
1 2