Re: is there any particular reason why Leo wouldn't use native QTreeWidget

2018-03-02 Thread Edward K. Ream
On Fri, Mar 2, 2018 at 8:02 AM, vitalije  wrote:

Also speaking about "rendering" tree and how it is expensive has always
> seemed a bit strange to me, because I was expecting that rendering tree
> items should do QTreeWidget by itself. I've always thought that this
> vocabulary (rendering tree items) was caused by some ancient way the things
> used to work perhaps in the Tkinter time or even before.
>

​A very interesting question. Perhaps you have put your finger on a big
blind spot on my part. As you say, the mind set may have come from Tkinter
or Borland C++.

I was surprised to see that Leo actually clears all items from the
> QTreeWidget and then recreates those which are visible. It looked strange
> to me
>

​Now that you mention it, perhaps I've just be very stupid :-)
​


> and I thought perhaps QTreeWidget can't handle very well large number of
> items, so I made an experiment.
>
​[snip]​

> It fills the tree widget with total of 10313 nodes (LeoPyRef.leo my
> version) and tree seems very responsive. There is no sign of performance
> issues. Expanding and collapsing nodes is smooth.
>
> This left me wandering. Why Leo doesn't use this widget as it is, and just
> dump all the vnodes to it? Is there something I am not aware of?
>

​A superb question.  I don't know the answer.  As Terry says, there may
minor issues with icons or hoisting, but that's probably a nit.

Performance gains are always very welcome, provided that somehow Leo works
exactly as it did before.  Without looking at your demo code, I infer that
you believe this is possible.

Without remember anything about dawn of Leo's Qt tree, I suspect that I was
lead astray by history.  A more native implementation is worth serious
consideration.

> The only thing that I don't understand is why are we deleting all the
items on every redraw and then creating new ones. instead. That seems to me
wrong and most probably is the cause for the delay in tree actions.

I have no idea why I did things this way. Perhaps I just wanted to simplify
some code that is, in fact, not needed at all.  In essence, this is an
important lifetime question.  Perhaps I thought that killing everything on
every redraw was somehow simpler than figuring out what tree items are
still valid.  Or something like that.

I do know that the code to maintain references is fairly complicated,
requiring several dicts.  Perhaps in your proposed scheme those
complications can go away.

There is one more thing to consider, just for completeness.  Mouse action
on the tree must generate the expected events so that Leo changes nodes
correctly.  But I suspect you know that :-)

Edward

-- 
You received this message because you are subscribed to the Google Groups 
"leo-editor" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to leo-editor+unsubscr...@googlegroups.com.
To post to this group, send email to leo-editor@googlegroups.com.
Visit this group at https://groups.google.com/group/leo-editor.
For more options, visit https://groups.google.com/d/optout.


Re: is there any particular reason why Leo wouldn't use native QTreeWidget

2018-03-02 Thread vitalije
I agree that QTreeView would be better choice. Especially hoisting feature 
is asking for a QTreeView/Model pair. After all hoisting is just another 
view into the same model.

In current version computed icons are handled by QTreeWidgetItem, so there 
should be no difference between how it is handled now. 

The only thing that I don't understand is why are we deleting all the items 
on every redraw and then creating new ones. instead. That seems to me wrong 
and most probably is the cause for the delay in tree actions.

If any node is changed in any way, it is straight forward to change 
corresponding treeWidgetItem and not deleting all the items and recreating 
all of them again just to create different one for the node that has been 
changed. QTreeWidgetItem instances have methods setText, setIcon that can 
be used to alter them as needed.

Vitalije

-- 
You received this message because you are subscribed to the Google Groups 
"leo-editor" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to leo-editor+unsubscr...@googlegroups.com.
To post to this group, send email to leo-editor@googlegroups.com.
Visit this group at https://groups.google.com/group/leo-editor.
For more options, visit https://groups.google.com/d/optout.


Re: is there any particular reason why Leo wouldn't use native QTreeWidget

2018-03-02 Thread Terry Brown
On Fri, 2 Mar 2018 09:37:22 -0600
Terry Brown  wrote:

> Not separate from the "let the widget do the rendering" part, don't
> forget the dynamic icon generation part

Or hoisting, that needs to be supported too.

-- 
You received this message because you are subscribed to the Google Groups 
"leo-editor" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to leo-editor+unsubscr...@googlegroups.com.
To post to this group, send email to leo-editor@googlegroups.com.
Visit this group at https://groups.google.com/group/leo-editor.
For more options, visit https://groups.google.com/d/optout.


Re: is there any particular reason why Leo wouldn't use native QTreeWidget

2018-03-02 Thread Terry Brown
On Fri, 2 Mar 2018 06:04:50 -0800 (PST)
vitalije  wrote:

> Just to be clear. I know that Leo uses QTreeWidget for rendering the
> tree, but my question is why we don't let it to mange rendering
> process all by itself.

Separate from the "let the widget do the rendering" part, should we be
using QTreeWidget or QTreeView?  The former handles nodes for you, the
latter expects you to do it?  I'm not 100% sure about that, but it
would seem we'd want the latter for that reason.

Not separate from the "let the widget do the rendering" part, don't
forget the dynamic icon generation part, which obviously is working in
the current scheme - -I guess it could be covered by the 'role'
approach used in the framework.

Cheers -Terry

-- 
You received this message because you are subscribed to the Google Groups 
"leo-editor" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to leo-editor+unsubscr...@googlegroups.com.
To post to this group, send email to leo-editor@googlegroups.com.
Visit this group at https://groups.google.com/group/leo-editor.
For more options, visit https://groups.google.com/d/optout.


Re: is there any particular reason why Leo wouldn't use native QTreeWidget

2018-03-02 Thread vitalije
Just to be clear. I know that Leo uses QTreeWidget for rendering the tree, 
but my question is why we don't let it to mange rendering process all by 
itself.

-- 
You received this message because you are subscribed to the Google Groups 
"leo-editor" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to leo-editor+unsubscr...@googlegroups.com.
To post to this group, send email to leo-editor@googlegroups.com.
Visit this group at https://groups.google.com/group/leo-editor.
For more options, visit https://groups.google.com/d/optout.


is there any particular reason why Leo wouldn't use native QTreeWidget

2018-03-02 Thread vitalije
In another thread 
 Edward 
wrote:

4. Leo's tree drawing code would likely choke on showing more than a few 
> thousand nodes. 


It wasn't the first time that I read about it. Also speaking about 
"rendering" tree and how it is expensive has always seemed a bit strange to 
me, because I was expecting that rendering tree items should do QTreeWidget 
by itself. I've always thought that this vocabulary (rendering tree items) 
was caused by some ancient way the things used to work perhaps in the 
Tkinter time or even before. 

Today I have looked more closely to the implementation of this tree 
rendering methods. I was surprised to see that Leo actually clears all 
items from the QTreeWidget and then recreates those which are visible. It 
looked strange to me and I thought perhaps QTreeWidget can't handle very 
well large number of items, so I made an experiment.

Here is the script:
from leo.core.leoQt import QtWidgets, QtCore
from collections import defaultdict
def demoW():
DWH = 'demo-window-instance'
w = c.user_dict.get(DWH)
if not w:
w = createDemoWindow()
c.user_dict[DWH] = w
return w

def createDemoWindow():

d = QtWidgets.QDialog()

def closeEvent(event, d=d):
event.ignore()
d.hide()

d.closeEvent = closeEvent
w = QtWidgets.QTreeWidget(d)
w.setObjectName('tree')
layout = QtWidgets.QVBoxLayout(d)
layout.addWidget(w)
d.setLayout(layout)
d.setModal(False)
d.setWindowFlags(d.windowFlags().__or__(0x4))
return d

def showW():
d = demoW()
if d.isVisible():
# The order is important, and tricky.
d.focusWidget()
d.show()
d.raise_()
d.activateWindow()
else:
d.show()
return d

def treeW():
d = demoW()
return d.findChild(QtWidgets.QTreeWidget, 'tree')

g.app.gui.replaceClipboardWith(g.getScript(c, p, useSentinels=False))
d = showW()
tw = treeW()
titems = defaultdict(lambda: list((None,)))
def addnode(tw, par, txt):
pitem = par or tw
item = QtWidgets.QTreeWidgetItem(pitem)
item.setFlags(item.flags() | QtCore.Qt.ItemIsEditable)
item.setText(0, txt)
return item
tw.clear()
i = 0
def pgn(p):
pp = p.parent()
gnx = pp.gnx if pp else 'root'
return titems[gnx][-1]
i = 0
for p in c.allNodes_iter():
par = pgn(p)
item = addnode(tw, par, p.h)
titems[p.gnx].append(item)
i += 1
for k, v in titems.items():
if k is 'root': continue
if len(c.fileCommands.gnxDict[k].children):
for item in v[1:]:
tw.expandItem(item)
g.es('total %d nodes'%i)


It fills the tree widget with total of 10313 nodes (LeoPyRef.leo my 
version) and tree seems very responsive. There is no sign of performance 
issues. Expanding and collapsing nodes is smooth. 

This left me wandering. Why Leo doesn't use this widget as it is, and just 
dump all the vnodes to it? Is there something I am not aware of?

Vitalije

PS: Initializing code for QDialog I borrowed from the Leo :-)

 

-- 
You received this message because you are subscribed to the Google Groups 
"leo-editor" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to leo-editor+unsubscr...@googlegroups.com.
To post to this group, send email to leo-editor@googlegroups.com.
Visit this group at https://groups.google.com/group/leo-editor.
For more options, visit https://groups.google.com/d/optout.