[PyQt] Just for fun: QCompleter accessing a QListWidget's internal model through a proxy ?

2010-08-17 Thread fpp
Hi everyone,

After many moons of lurking I have finally subscribed to ask for
advice about my current challenge:

In this app I'm working on (my first real, non-trivial one,
admittedly), I have a number of QListWidgets in the main window,
holding plain strings, each with an associated QLineEdit for input.
They work just fine, and there really is no need for anything more
elaborate than list widgets for what they do.

Only now that it's almost finished, with everything in place and the
code working well, I just discovered the existence of QCompleters by
accident... and obviously now I want them in the line edits.

However, QCompleters are designed to work only with real models, not
convenience widgets. Of course it's very easy to use them with a plain
QStringList, but it feels somewhat clunky and inefficient to duplicate
the list widget's content to the completer's string list, refreshing
it each time that content changes... and I don't really feel like
retooling the entire UI to use QListViews just for the sake of
completers.

So I thought, perhaps naively, that it might be possible to build a
kind of proxy model, that would feed a completer with data pulled
from a list widget's hidden, internal model.

After quite some time trying to make sense of the Qt docs (which seem
to contradict themselves sometimes), I settled on the following :

- make the model a subclass of QAbstractListModel;

- reimplement the rowCount(), data() and index() methods as required,
to fetch the relevant data from the list widget (passed as a parameter
to the constructor).

Here is the entire model code :

class proxyModel(QAbstractListModel):
def __init__(self, qlwi, parent=None):
QAbstractListModel.__init__(self, parent)
self.qlwi = qlwi

def index (self, row, col = 0, parent = None):
return self.qlwi.indexFromItem(self.qlwi.item(row))

def rowCount (self, parent = None):
return self.qlwi.count()

def data (self, index, role = Qt.DisplayRole):
return self.qlwi.itemFromIndex(index).data(role)

I have verified (with good old prints) that the three methods return
the expected values and types (QModelIndex, int and QVariant),
reflecting changes made to the list widget on the fly.

Unfortunately, setting a completer's model to a proxyModel instance
does exactly nothing: everything works just as before, without
completion.

Lacking a better understanding of the Qt internals, I'm at a loss as
to which way I should dig now... I tried to Google for prior art,
and found nothing relevant, which usually means one of two things :

- the entire notion is stupid and impossible, for some fundamental
reason that eludes me;

- or else it is actually so trivial that no one has ever thought of
documenting it, and I'm just missing something really obvious.

Either way, I'd welcome suggestions and pointers to the what and why,
hopefully learning something important about (Py)Qt in the process...

Thanks in advance,
fp
___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] Just for fun: QCompleter accessing a QListWidget's internal model through a proxy ?

2010-08-17 Thread Matt Newell
On Tuesday 17 August 2010 11:23:55 fpp wrote:
 Hi everyone,
 
 After many moons of lurking I have finally subscribed to ask for
 advice about my current challenge:
 
 In this app I'm working on (my first real, non-trivial one,
 admittedly), I have a number of QListWidgets in the main window,
 holding plain strings, each with an associated QLineEdit for input.
 They work just fine, and there really is no need for anything more
 elaborate than list widgets for what they do.
 
 Only now that it's almost finished, with everything in place and the
 code working well, I just discovered the existence of QCompleters by
 accident... and obviously now I want them in the line edits.
 
 However, QCompleters are designed to work only with real models, not
 convenience widgets. Of course it's very easy to use them with a plain
 QStringList, but it feels somewhat clunky and inefficient to duplicate
 the list widget's content to the completer's string list, refreshing
 it each time that content changes... and I don't really feel like
 retooling the entire UI to use QListViews just for the sake of
 completers.
 
 So I thought, perhaps naively, that it might be possible to build a
 kind of proxy model, that would feed a completer with data pulled
 from a list widget's hidden, internal model.
 
I could be overlooking something but I don't see why you can't use the list 
widget's model directly.  The details of the implemenation may be private, but 
the QAbstractItemModel interface is still public and usable.

Should be as simple as
completer = QCompleter( listWidget.model(), parent )

Matt
___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] Just for fun: QCompleter accessing a QListWidget's internal model through a proxy ?

2010-08-17 Thread fpp
On Tue, Aug 17, 2010 at 9:25 PM, Matt Newell newe...@blur.com wrote:

 On Tuesday 17 August 2010 11:23:55 fpp wrote:
 So I thought, perhaps naively, that it might be possible to build a
 kind of proxy model, that would feed a completer with data pulled
 from a list widget's hidden, internal model.

 I could be overlooking something but I don't see why you can't use the list
 widget's model directly.  The details of the implementation may be private, 
 but
 the QAbstractItemModel interface is still public and usable.
 Should be as simple as
 completer = QCompleter( listWidget.model(), parent )

Indeed it is !... self.slaps_forehead()

Wow, that was quick... so it was actually option #2 of my self-prediction:
 or else it is so trivial that no one has ever thought of documenting it, and 
 I'm just missing something really obvious.

...which is good news. Just the usual result of my inability to parse
the Qt docs, wrap my head around object models, and generally add two
plus two.

Thanks Matt !
fp
___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt