Re: [PyQt] QAbstractItemModel's "dataChanged" signal not working?

2010-03-03 Thread Claudio Felix
2010/3/2 Mark Summerfield :
> On 2010-02-27, Claudio Felix wrote:
>> Hi everyone,
>>
>> I'm using a QSqlRelationalTableModel for a simple dialog where I can
>> add/delete periods related to a particular customer, which is chosen
>> by a QComboBox. The periods table is filtered by customer (whose ID is
>> a foreign key) and shown through a QTableView. There's an "Add" button
>> which basically inserts a new row in the Periods table and sets the
>> view to edit mode, so the period data can be entered:
>>
>>     def addRecord(self):
>>         row = self.model.rowCount()
>>         customerid = self._getRecordID(self.customerComboBox,
>> self.customersModel, "CUSTOMER_ID")
>>         self.enableControls(False)
>>         self.model.insertRow(row)
>>         index = self.model.index(row, CUSTOMER_ID)
>>         self.model.setData(index, QVariant(customerid))
>>         index = self.model.index(row, PERIOD_YEAR)
>>         self.periodsTableView.setCurrentIndex(index)
>>         self.periodsTableView.edit(index)
>>
>> I noticed that, while the view is in edit mode (with the asterisk '*'
>> appearing in the leftmost field), if the user clicks on the add button
>> again, an empty row appears in the view and the asterisk appears in
>> the next row, with this message on the console:
>>
>> edit: index was invalid
>> edit: editing failed
>>
>> The same problem happens in the "assetmanager.pyw" example from the
>> (great!) book "Rapid GUI Programming with Python and QT", which is my
>> main guide. That way, in my limited experience with PyQT, I tried to
>> work around the undesirable behavior creating the method
>> "enableControls" for the dialog, which is called in the addRecord
>> method so it makes it impossible for the user to click on "add" again
>> while the view is in edit mode. The idea then was to re-enable the
>> controls when the data was finally committed by the view. That's when
>> the main problem comes up. I tried to use the model's "dataChanged"
>> signal for calling my "enableControls" method, but it looks like it
>> never gets emitted, although the record does get written to the
>> database table. Does anybody can confirm that or help me avoiding the
>> problem at all? I used the following signature for the signal, exactly
>> the same shown on QAbstractItemModel's documentation:
>>
>> self.connect(self.model, SIGNAL("dataChanged(const QModelIndex&,const
>> QModelIndex&)"), self.enableControls)
>>
>> That line is declared in my dialog's __init__, along with all the
>> other (working) signals. self.model referes to the
>> QSqlRelationalTableModel.
>>
>> Thanks for any help!
>
> Hi Claudio,
>
> I must admit that I've grown very frustrated with Qt's database support,
> particularly with SQLite. I've found that the book's database examples
> (which all use SQLite since that is supplied with Qt) exhibit varying
> differences in behavior depending on the Qt version.
>
> Regarding your specific problem, I can't see anything obviously wrong
> with your connection. Personally, I would have written it as
>
>    self.connect(self.model, SIGNAL("dataChanged(QModelIndex,QModelIndex)"),
>                 self.enableControls)
>
> but that should make no difference.
>
> Is your model a QSqlRelationalTableModel or a subclass? If it is a
> subclass and you have reimplemented setData() then you must emit the
> dataChanged() signal in your reimplemented setData() method. But if
> you're using QSqlRelationalTableModel directly then it isn't obvious to
> me what you're doing wrong. However, dataChanged() might be the wrong
> signal for reenabling the Add button since it is emitted for every
> change to every field, whereas I'd have thought you wanted to enable the
> Add button only when the record was inserted? So maybe you could try
> connecting to the QAbstractItemModel::rowsInserted() signal?
>
> I had a quick go at changing assetmanager.pyw to do this but without
> success (using PyQt 4.6 and Qt 4.5.2); maybe things have improved with
> Qt 4.6.
>
> --
> Mark Summerfield, Qtrac Ltd, www.qtrac.eu
>    C++, Python, Qt, PyQt - training and consultancy
>        "C++ GUI Programming with Qt 4" - ISBN 0132354160
>

Hello Mark,

Thanks for your help, and specially for the great book you've written.
It's been a really helpful source, very nice to read. It has saved me
from quite a lot of endless trial

[PyQt] How to get a simple QTabBar in QT Designer (don't want a QTabWidget)

2010-02-27 Thread Claudio Felix
Hi all,

I have an app where I want to use a QTabBar but in QT Designer there
is only a QTabWidget. Since I don't want to select pages of widgets by
the tabs, but just need the index of the chosen tab, is there any way
to get a QTabBar in QT Designer?

Cheers,

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


[PyQt] QAbstractItemModel's "dataChanged" signal not working?

2010-02-27 Thread Claudio Felix
Hi everyone,

I'm using a QSqlRelationalTableModel for a simple dialog where I can
add/delete periods related to a particular customer, which is chosen
by a QComboBox. The periods table is filtered by customer (whose ID is
a foreign key) and shown through a QTableView. There's an "Add" button
which basically inserts a new row in the Periods table and sets the
view to edit mode, so the period data can be entered:

def addRecord(self):
row = self.model.rowCount()
customerid = self._getRecordID(self.customerComboBox,
self.customersModel, "CUSTOMER_ID")
self.enableControls(False)
self.model.insertRow(row)
index = self.model.index(row, CUSTOMER_ID)
self.model.setData(index, QVariant(customerid))
index = self.model.index(row, PERIOD_YEAR)
self.periodsTableView.setCurrentIndex(index)
self.periodsTableView.edit(index)

I noticed that, while the view is in edit mode (with the asterisk '*'
appearing in the leftmost field), if the user clicks on the add button
again, an empty row appears in the view and the asterisk appears in
the next row, with this message on the console:

edit: index was invalid
edit: editing failed

The same problem happens in the "assetmanager.pyw" example from the
(great!) book "Rapid GUI Programming with Python and QT", which is my
main guide. That way, in my limited experience with PyQT, I tried to
work around the undesirable behavior creating the method
"enableControls" for the dialog, which is called in the addRecord
method so it makes it impossible for the user to click on "add" again
while the view is in edit mode. The idea then was to re-enable the
controls when the data was finally committed by the view. That's when
the main problem comes up. I tried to use the model's "dataChanged"
signal for calling my "enableControls" method, but it looks like it
never gets emitted, although the record does get written to the
database table. Does anybody can confirm that or help me avoiding the
problem at all? I used the following signature for the signal, exactly
the same shown on QAbstractItemModel's documentation:

self.connect(self.model, SIGNAL("dataChanged(const QModelIndex&,const
QModelIndex&)"), self.enableControls)

That line is declared in my dialog's __init__, along with all the
other (working) signals. self.model referes to the
QSqlRelationalTableModel.

Thanks for any help!

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


Re: [PyQt] Trouble reading a model index from an "untouched" combo box

2010-01-30 Thread Claudio Felix
>
> Looking at the source code in Qt, I think the reason for this is because
> there's no connection between the currentIndex() in the itemview and the
> one in its selectionModel. In particular the currentChanged() slot in
> the itemview doesn't update its internal currentIndex. I think thats a
> bug in Qt.
>
> So you'll have to ignore the view here and work with the row from the
> combobox to generate a model index. This should work:
>
> def getItemID(self:
>    self.comboBox.setCurrentIndex(0)
>    idx = self.model.index( self.comboBox.currentIndex(), 
> self.model.fieldIndex("ITEM_ID"), QModelIndex() )
>    return self.model.data(idx).toInt()[0]
>
> Andreas
>

Thanks Andreas,

It worked fine that way. Since these DB records won't change anyway, I
think indexing the ITEM_ID field by the combo box item index will do
the job in the long run for this particular project. About this
potential bug of the lack of connection between the currentIndex in
the itemview and the one in the selectionModel, should we report this
to Phil or maybe open a bug report for QT? I'm not familiar with QT's
source code, but if that is really a bug (and it looks like it is) it
would be nice to get it fixed, huh?

Thank you for your help!

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


Re: [PyQt] Trouble reading a model index from an "untouched" combo box

2010-01-27 Thread Claudio Felix
> Well, the combobox has initially no selected/current entry - AFAIK. Only
> once you select one it'll be set. Hence the invalid index.
>
> However a setCurrentIndex with a value != 0 on the combobox should
> change that already I think.
>
> Another thing in your case is that box.view().currentIndex() will not be
> an index that contains the ITEM_ID value, because the current index will
> be pointing to the name-cell. Each index indvidually refers to a single
> cell and you've used the ITEM_NAME column for the combobox, so its view
> will only give you indexes from that column.
>
> Andreas
>

Andreas,

One of Demetrius' previous suggestions was doing that indeed (setting
currentIndex), and I tried it both for zero and non-zero indexes, but
to no avail. The combo box starts showing the right item but the model
index still comes invalid. If I just click, voila, I get a valid
index. Really strange.

For this part about getting ITEM_ID, that's the purpose of the
"getItemID" function:

  def getItemID(self):
   index = self.comboBox.view().currentIndex()
   if not index.isValid():
   raise ValueError, "invalid index" # Here I always get the
error if I don't click on the combo box before
   row = index.row()
   column = self.model.fieldIndex("ITEM_ID")
   return self.model.data(self.model.index(row, column)).toInt()[0]

It retrieves the index corresponding to the ITEM_NAME column in the
combo box, but then I query the table model for the same row but
specifying the ITEM_ID index, so I really get the right one from the
table, not tem combo box.

I really think there might be a better way though... the whole purpose
of this dialog is to set restrictions on a SQL Query based on the
foreign keys found in the main table (each combo box should show a
text field associated to a foreign key value), so maybe I can replace
the QSqlQuery  by a QSqlRelationalTableModel altogether with each
combo box showing the named field set through an QSqlRelation. I know
that works fine, but if I change a combo box item I suspect it will
modify the key value on the main table, and this is not what I want.

In fact I just want to filter the results and sum them up in SQL,
something like this (consider this table):

Volume (float)Cost (float)  Supplier_ID (int)  Period_ID (int)

The query would sum up all the volume and cost records of some product
if no Combo box were enabled, but if supplier was enabled it would sum
up just the volume and cost for products from a given supplier or if
period combo box were enabled also, just the given periods for that
given supplier would be considered. Something like "select
sum(Volume), sum(Cost) from table where SUPPLIER_ID = x and PERIOD_ID
= y" (the where clause depends on the combos being enabled or not).

Thank all you guys for your help!

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


Re: [PyQt] Trouble reading a model index from an "untouched" combo box

2010-01-27 Thread Claudio Felix
2010/1/27 Andreas Pakulat :
> On 26.01.10 17:41:40, Demetrius Cassidy wrote:
>> I don't think you need to use the view pointer at all - it's
>> returning QAbstractItemView *, which I would assume it would need to
>> be casted to the proper class in C++. If that's so, by design the
>> Abstract class will return an invalid index.
>
> I don't think so ;) The function currentIndex on the view is not
> virtual, so its implemented in the abstract class already properly.
>
> And to get a model index to index into the model its easier to ask the
> view for it, rather than constructing it yourself with model->index(
> combobox->currentIndex(), , QModelIndex())
>
> Andreas
>

Andreas,

That was the way I was thinking when I tried the code in the beggining
of this thread.. but I'm still stuck retrieving an invalid index if I
don't at least click on the combo box (if I do click on it I get a
valid index just fine).

If you take a look at the code, my intent was to get the ITEM_ID
field, which is the table's primary key which corresponds to the item
selected on the combo box. Since I have the model for the table
already, I found natural to use it for displaying the ITEM_NAME field
on the combo box, so I would get the selected item model index from
its view to get the ITEM_ID from the table model and use it to
optionally filter data on a subsequent SQL Query. I'm intrigued by
this QComboBox behavior, for the model was given a "select()" before
being associated to it, so I think it should return a valid index.


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


Re: [PyQt] Trouble reading a model index from an "untouched" combo box

2010-01-26 Thread Claudio Felix
2010/1/26 Demetrius Cassidy :
> How about selecting index 0 once the combobox is initialized with the
> database data? It sounds to me that it has no valid index when first
> initialized, and if you try to programmatically select the first index, it's
> returning an invalid one. You don't need to generate a signal, just use
> something like .setCurrentIndex(0).
>


Thanks for the answer Demetrius. Unfortunately, it didn't change it.
Maybe I do have to use a QDataWidgetMapper on the combo box? I thought
just getting the model associated with it should do it.. it shows all
the models' values indeed...

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


[PyQt] Trouble reading a model index from an "untouched" combo box

2010-01-26 Thread Claudio Felix
Hi everyone,

I'm developing an app which loads data from a database table into a
QSqlTableModel. At some point I associate this model to a Combo Box
(using QComboBox.setModel). The strange thing is, when I try to read
the current model index from the combo box view, for getting the
selected item's data from another database field on the same model
record, I get a invalid index, but If I just click on the combo box (I
don't even have to change the item) before trying to read its index,
it returns a valid model index. So, it is really necessary to do
something before, like generating a "currentIndexChanged" signal? What
I did was like this:


  def __init__(self):
   self.model = QSqlTableModel()
   self.model.setTable("dbtable")
   self.model.select()
   self.comboBox = QComboBox()
   self.comboBox.setModel(self.model)
   self.comboBox.setModelColumn("ITEM_NAME")


  def getItemID(self):
   index = self.comboBox.view().currentIndex()
   if not index.isValid():
   raise ValueError, "invalid index"   # Here
I always get the error if I don't click on the combo box before
   row = index.row()
   column = self.model.fieldIndex("ITEM_ID")
   return self.model.data(self.model.index(row, column)).toInt()[0]

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


[PyQt] Trouble reading a model index from an "untouched" combo box

2010-01-26 Thread Claudio Felix
Hi everyone,

I'm developing an app which loads data from a database table into a
QSqlTableModel. At some point I associate this model to a Combo Box
(using QComboBox.setModel). The strange thing is, when I try to read
the current model index from the combo box view, for getting the
selected item's data from another database field on the same model
record, I get a invalid index, but If I just click on the combo box (I
don't even have to change the item) before trying to read its index,
it returns a valid model index. So, it is really necessary to do
something before, like generating a "currentIndexChanged" signal? What
I did was like this:


   def __init__(self):
self.model = QSqlTableModel()
self.model.setTable("dbtable")
self.model.select()
self.comboBox = QComboBox()
self.comboBox.setModel(self.model)
self.comboBox.setModelColumn("ITEM_NAME")


   def getItemID(self):
index = self.comboBox.view().currentIndex()
if not index.isValid():
raise ValueError, "invalid index"   # Here
I always get the error if I don't click on the combo box before
row = index.row()
column = self.model.fieldIndex("ITEM_ID")
return self.model.data(self.model.index(row, column)).toInt()[0]

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


Re: [PyQt] Problem freezing a Sqlite based PyQT app

2010-01-11 Thread Claudio Felix
2010/1/11 Anil 

>  Have you included "sqldrivers" folder in to your package?
>
>
> On 12/01/2010 11:55 AM, Claudio Felix wrote:
>
> Hello everyone,
>
> I've been developing a PyQT database app which uses a SQlite3
> database. It is working just fine on my development environment, which
> is Linux based. My problem is the end users want it running on
> Windows, and it does run fine on it, until I try freezing it (they
> wouldn't have a clue as how to install python, PyQT and all by
> themselves). I'm using cx_Freeze to get it done and on Linux even the
> frozen version runs just fine, but on Windows I get this error:
>
> Database Error: Driver not loaded
>
> Have you guys hit anything like this before? I'm using the same
> version of cx_Freeze on Linux and Windows (4.1.2) and the software
> doesn't have any different imports for one or the other, so I guess
> the same modules should be included in the freezing process.. is there
> anything obvious I'm missing? The cx_Freeze command line used was like
> this (also tried from eric4 packager plugin, with same result):
>
> cxfreeze --target-dir=c:\test --target-name=app.exe
> --base-name=Win32GUI mainwindow.py
>
> If this helps, python version is 2.6.2, QT is 4.5.2 and PyQT is 4.4.4.
>
> Thanks and congratulations for the great work in PyQT!
>
> Claudio
> ___
> PyQt mailing list
> p...@riverbankcomputing.comhttp://www.riverbankcomputing.com/mailman/listinfo/pyqt
>
>
> --
>

Thanks Anil, it worked just fine! Just complementing for those who face the
same problem in the future, I had to copy the C:\Python26\Lib\site-packages\
PyQt4\plugins\sqldrivers dir to my frozen app target-dir. The only file
needed in my case was qsqlite4.dll (which refers to QSqlite), but it has to
be in a folder named ''sqldrivers'' into the target-dir for the app to work.

Cheers,

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

[PyQt] Problem freezing a Sqlite based PyQT app

2010-01-11 Thread Claudio Felix
Hello everyone,

I've been developing a PyQT database app which uses a SQlite3
database. It is working just fine on my development environment, which
is Linux based. My problem is the end users want it running on
Windows, and it does run fine on it, until I try freezing it (they
wouldn't have a clue as how to install python, PyQT and all by
themselves). I'm using cx_Freeze to get it done and on Linux even the
frozen version runs just fine, but on Windows I get this error:

Database Error: Driver not loaded

Have you guys hit anything like this before? I'm using the same
version of cx_Freeze on Linux and Windows (4.1.2) and the software
doesn't have any different imports for one or the other, so I guess
the same modules should be included in the freezing process.. is there
anything obvious I'm missing? The cx_Freeze command line used was like
this (also tried from eric4 packager plugin, with same result):

cxfreeze --target-dir=c:\test --target-name=app.exe
--base-name=Win32GUI mainwindow.py

If this helps, python version is 2.6.2, QT is 4.5.2 and PyQT is 4.4.4.

Thanks and congratulations for the great work in PyQT!

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