• Any PyQt developers here?

    From DFS@21:1/5 to All on Tue Oct 25 13:03:58 2022
    Having problems with removeRow() on a QTableView object.

    After calling removeRow(), the screen isn't updating. It's as if the
    model is read-only, but it's a QSqlTableModel() model, which is not
    read-only.

    The underlying SQL is straightforward (one table) and all columns are
    editable.

    None of the editStrategies are working either.

    I tried everything I can think of, including changes to the
    EditTriggers, but no luck. HELP!

    FWIW, the same removeRow() code works fine with a QTableWidget.

    -------------------------------------------------------------------
    object creation and data loading all works fine -------------------------------------------------------------------
    #open db connection
    qdb = QSqlDatabase.addDatabase("QSQLITE")
    qdb.setDatabaseName(dbname)
    qdb.open()

    #prepare query and execute to return data
    query = QSqlQuery()
    query.prepare(cSQL)
    query.exec_()

    #set model type and query
    model = QSqlTableModel()
    model.setQuery(query)

    #assign model to QTableView object
    view = frm.tblPostsView
    view.setModel(model)

    #get all data
    while(model.canFetchMore()): model.fetchMore()
    datarows = model.rowCount()



    -------------------------------------------------------------------
    iterate selected rows also works fine
    SelectionMode is Extended.
    identical code works for a QTableWidget -------------------------------------------------------------------
    selected = tbl.selectionModel().selectedRows()
    #reverse sort the selected items to delete from bottom up
    selected = sorted(selected,reverse=True)
    for i,val in enumerate(selected):
    tbl.model().removeRow(selected[i].row())

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Passin@21:1/5 to DFS on Tue Oct 25 13:45:04 2022
    On 10/25/2022 1:03 PM, DFS wrote:
    Having problems with removeRow() on a QTableView object.

    removeRow() isn't listed as being a method of a QTableView, not even an inherited method, so how are you calling removeRow() on it? (See https://doc.qt.io/qt-6/qtableview-members.html)

    After calling removeRow(), the screen isn't updating.  It's as if the
    model is read-only, but it's a QSqlTableModel() model, which is not read-only.

    The underlying SQL is straightforward (one table) and all columns are editable.

    None of the editStrategies are working either.

    I tried everything I can think of, including changes to the
    EditTriggers, but no luck.  HELP!

    FWIW, the same removeRow() code works fine with a QTableWidget.

    -------------------------------------------------------------------
    object creation and data loading all works fine -------------------------------------------------------------------
    #open db connection
    qdb = QSqlDatabase.addDatabase("QSQLITE")
    qdb.setDatabaseName(dbname)
    qdb.open()

    #prepare query and execute to return data
    query = QSqlQuery()
    query.prepare(cSQL)
    query.exec_()

    #set model type and query
    model = QSqlTableModel()
    model.setQuery(query)

    #assign model to QTableView object
    view = frm.tblPostsView
    view.setModel(model)

    #get all data
    while(model.canFetchMore()): model.fetchMore()
    datarows = model.rowCount()



    -------------------------------------------------------------------
    iterate selected rows also works fine
    SelectionMode is Extended.
    identical code works for a QTableWidget -------------------------------------------------------------------
    selected = tbl.selectionModel().selectedRows()
    #reverse sort the selected items to delete from bottom up
    selected = sorted(selected,reverse=True)
    for i,val in enumerate(selected):
        tbl.model().removeRow(selected[i].row())


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Barry Scott@21:1/5 to All on Tue Oct 25 19:03:57 2022
    There is an active PyQt mailing list that has lots of helpful and knowledgeable people on it.

    https://www.riverbankcomputing.com/mailman/listinfo/pyqt

    Barry


    On 25 Oct 2022, at 18:03, DFS <nospam@dfs.com> wrote:

    Having problems with removeRow() on a QTableView object.

    After calling removeRow(), the screen isn't updating. It's as if the model is read-only, but it's a QSqlTableModel() model, which is not read-only.

    The underlying SQL is straightforward (one table) and all columns are editable.

    None of the editStrategies are working either.

    I tried everything I can think of, including changes to the EditTriggers, but no luck. HELP!

    FWIW, the same removeRow() code works fine with a QTableWidget.

    -------------------------------------------------------------------
    object creation and data loading all works fine -------------------------------------------------------------------
    #open db connection
    qdb = QSqlDatabase.addDatabase("QSQLITE")
    qdb.setDatabaseName(dbname)
    qdb.open()

    #prepare query and execute to return data
    query = QSqlQuery()
    query.prepare(cSQL)
    query.exec_()

    #set model type and query
    model = QSqlTableModel()
    model.setQuery(query)

    #assign model to QTableView object
    view = frm.tblPostsView
    view.setModel(model)

    #get all data
    while(model.canFetchMore()): model.fetchMore()
    datarows = model.rowCount()



    -------------------------------------------------------------------
    iterate selected rows also works fine
    SelectionMode is Extended.
    identical code works for a QTableWidget -------------------------------------------------------------------
    selected = tbl.selectionModel().selectedRows()
    #reverse sort the selected items to delete from bottom up
    selected = sorted(selected,reverse=True)
    for i,val in enumerate(selected):
    tbl.model().removeRow(selected[i].row())

    --
    https://mail.python.org/mailman/listinfo/python-list


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From DFS@21:1/5 to Thomas Passin on Tue Oct 25 15:19:48 2022
    On 10/25/2022 1:45 PM, Thomas Passin wrote:
    On 10/25/2022 1:03 PM, DFS wrote:
    Having problems with removeRow() on a QTableView object.

    removeRow() isn't listed as being a method of a QTableView, not even an inherited method, so how are you calling removeRow() on it? (See https://doc.qt.io/qt-6/qtableview-members.html)


    * I thought I was calling it the same way it's called with
    QTableWidgets: tbl.removeRow()

    But looking at my code again I was using tbl.model().removeRow()


    * Plus I found several others online with similar removeRow() issues
    with QTableViews.


    * Plus the code didn't throw an error:

    selected = tbl.selectionModel().selectedRows()
    #reverse sort the selected items to delete from bottom up
    selected = sorted(selected,reverse=True)
    for i,val in enumerate(selected):
    tbl.model().removeRow(selected[i].row())


    But... as you say, when looking at the docs, removeRow() isn't even one
    of the slots for QTableViews. So duh!

    I see the QTableView.hideRow(row) method, which does exactly what I need.

    Thanks man!





    After calling removeRow(), the screen isn't updating.  It's as if the
    model is read-only, but it's a QSqlTableModel() model, which is not
    read-only.

    The underlying SQL is straightforward (one table) and all columns are
    editable.

    None of the editStrategies are working either.

    I tried everything I can think of, including changes to the
    EditTriggers, but no luck.  HELP!

    FWIW, the same removeRow() code works fine with a QTableWidget.

    -------------------------------------------------------------------
    object creation and data loading all works fine
    -------------------------------------------------------------------
    #open db connection
    qdb = QSqlDatabase.addDatabase("QSQLITE")
    qdb.setDatabaseName(dbname)
    qdb.open()

    #prepare query and execute to return data
    query = QSqlQuery()
    query.prepare(cSQL)
    query.exec_()

    #set model type and query
    model = QSqlTableModel()
    model.setQuery(query)

    #assign model to QTableView object
    view = frm.tblPostsView
    view.setModel(model)

    #get all data
    while(model.canFetchMore()): model.fetchMore()
    datarows = model.rowCount()



    -------------------------------------------------------------------
    iterate selected rows also works fine
    SelectionMode is Extended.
    identical code works for a QTableWidget
    -------------------------------------------------------------------
    selected = tbl.selectionModel().selectedRows()
    #reverse sort the selected items to delete from bottom up
    selected = sorted(selected,reverse=True)
    for i,val in enumerate(selected):
         tbl.model().removeRow(selected[i].row())



    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From DFS@21:1/5 to Barry Scott on Tue Oct 25 15:20:34 2022
    On 10/25/2022 2:03 PM, Barry Scott wrote:
    There is an active PyQt mailing list that has lots of helpful and knowledgeable people on it.

    https://www.riverbankcomputing.com/mailman/listinfo/pyqt

    Barry


    Thanks. I'll send some questions their way, I'm sure.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From DFS@21:1/5 to Thomas Passin on Thu Oct 27 11:15:58 2022
    On 10/25/2022 1:45 PM, Thomas Passin wrote:
    On 10/25/2022 1:03 PM, DFS wrote:
    Having problems with removeRow() on a QTableView object.

    removeRow() isn't listed as being a method of a QTableView, not even an inherited method, so how are you calling removeRow() on it? (See https://doc.qt.io/qt-6/qtableview-members.html)

    Since you helped me on the last one, maybe you could try to answer a
    couple more [probably simple] roadblocks I'm hitting.


    I just wanna set the font to bold/not-bold when clicking on a row in QTableView.



    With a QTableWidget I do it like this:

    font = QFont()
    font.setBold(True) or False
    QTableWidget.item(row,col).setFont(font)



    But the QTableView has data/view 'models' attached to it and that syntax doesn't work:


    Tried:
    font = QFont()
    font.setBold(True) or False
    model = QTableView.model()
    model.setFont(model.index(row,col), font)

    Throws AttributeError: 'QSqlTableModel' object has no attribute 'setFont'


    This doesn't throw an error, but doesn't show bold: model.setData(model.index(tblRow, col), font, Qt.FontRole)


    Any ideas?

    Thanks

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Passin@21:1/5 to DFS on Thu Oct 27 15:47:49 2022
    On 10/27/2022 11:15 AM, DFS wrote:
    On 10/25/2022 1:45 PM, Thomas Passin wrote:
    On 10/25/2022 1:03 PM, DFS wrote:
    Having problems with removeRow() on a QTableView object.

    removeRow() isn't listed as being a method of a QTableView, not even
    an inherited method, so how are you calling removeRow() on it? (See
    https://doc.qt.io/qt-6/qtableview-members.html)

    Since you helped me on the last one, maybe you could try to answer a
    couple more [probably simple] roadblocks I'm hitting.


    I just wanna set the font to bold/not-bold when clicking on a row in QTableView.



    With a QTableWidget I do it like this:

    font = QFont()
    font.setBold(True) or False
    QTableWidget.item(row,col).setFont(font)



    But the QTableView has data/view 'models' attached to it and that syntax doesn't work:


    Tried:
    font = QFont()
    font.setBold(True) or False
    model = QTableView.model()
    model.setFont(model.index(row,col), font)

    Throws AttributeError: 'QSqlTableModel' object has no attribute 'setFont'


    This doesn't throw an error, but doesn't show bold: model.setData(model.index(tblRow, col), font, Qt.FontRole)


    Any ideas?

    You definitely need to be setting the font in an item. I'm not sure but
    I think that your QFont() doesn't have any properties, so it doesn't do anything. I found this bit in a page - it's in C++ instead of Python
    but that doesn't really make a difference except for the exact syntax to
    use -


    https://forum.qt.io/topic/70016/qlistview-item-font-stylesheet-not-working/4

    QVariant v = ModelBaseClass::data(index,role);
    if( condition && role == Qt::FontRole )
    {
    QFont font = v.value<QFont>();
    font.setBold( true );
    v = QVariant::fromValue<QFont>( font );
    }

    IOW, you have to get the font from the item, then set it to bold, which
    you would do with setFont(). Then you set that new font on the item. Of
    course you would have to unset bold on it later. See

    https://doc.qt.io/qt-6/qtablewidgetitem.html#font

    Instead of "item", you might need to operate on "row". I didn't look
    into that. Since a row probably doesn't have just one font (since it
    can have more than one item), you'd still have to get the font from some
    item in the row.

    You might also be able to make the item bold using CSS, but I'm not sure.

    Thanks

    Internet searches are your friend for questions like this. I've never
    worked with a QTableView, so I had to start with some knowledge about
    some other parts of QT. I found the first page searching for "qt set qtableview row font", and the second searching for "qtablewidgetitem".

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Passin@21:1/5 to Thomas Passin on Fri Oct 28 01:01:13 2022
    This looks like a useful tutorial -

    https://doc.qt.io/qt-6/modelview.html

    On 10/27/2022 3:47 PM, Thomas Passin wrote:
    On 10/27/2022 11:15 AM, DFS wrote:
    On 10/25/2022 1:45 PM, Thomas Passin wrote:
    On 10/25/2022 1:03 PM, DFS wrote:
    Having problems with removeRow() on a QTableView object.

    removeRow() isn't listed as being a method of a QTableView, not even
    an inherited method, so how are you calling removeRow() on it? (See
    https://doc.qt.io/qt-6/qtableview-members.html)

    Since you helped me on the last one, maybe you could try to answer a
    couple more [probably simple] roadblocks I'm hitting.


    I just wanna set the font to bold/not-bold when clicking on a row in
    QTableView.



    With a QTableWidget I do it like this:

    font = QFont()
    font.setBold(True) or False
    QTableWidget.item(row,col).setFont(font)



    But the QTableView has data/view 'models' attached to it and that
    syntax doesn't work:


    Tried:
    font = QFont()
    font.setBold(True) or False
    model = QTableView.model()
    model.setFont(model.index(row,col), font)

    Throws AttributeError: 'QSqlTableModel' object has no attribute 'setFont'


    This doesn't throw an error, but doesn't show bold:
    model.setData(model.index(tblRow, col), font, Qt.FontRole)


    Any ideas?

    You definitely need to be setting the font in an item.  I'm not sure but
    I think that your QFont() doesn't have any properties, so it doesn't do anything.  I found this bit in a page - it's in C++ instead of Python
    but that doesn't really make a difference except for the exact syntax to
    use -


    https://forum.qt.io/topic/70016/qlistview-item-font-stylesheet-not-working/4

          QVariant v = ModelBaseClass::data(index,role);
          if( condition && role == Qt::FontRole )
          {
                   QFont font = v.value<QFont>();
                        font.setBold( true );
                   v = QVariant::fromValue<QFont>( font );
          }

    IOW, you have to get the font from the item, then set it to bold, which
    you would do with setFont().  Then you set that new font on the item. Of course you would have to unset bold on it later. See

    https://doc.qt.io/qt-6/qtablewidgetitem.html#font

    Instead of "item", you might need to operate on "row".  I didn't look
    into that.  Since a row probably doesn't have just one font (since it
    can have more than one item), you'd still have to get the font from some
    item in the row.

    You might also be able to make the item bold using CSS, but I'm not sure.

    Thanks

    Internet searches are your friend for questions like this.  I've never worked with a QTableView, so I had to start with some knowledge about
    some other parts of QT.  I found the first page searching for "qt set qtableview row font", and the second searching for "qtablewidgetitem".


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From DFS@21:1/5 to Thomas Passin on Fri Oct 28 23:31:48 2022
    On 10/27/2022 3:47 PM, Thomas Passin wrote:
    On 10/27/2022 11:15 AM, DFS wrote:
    On 10/25/2022 1:45 PM, Thomas Passin wrote:
    On 10/25/2022 1:03 PM, DFS wrote:
    Having problems with removeRow() on a QTableView object.

    removeRow() isn't listed as being a method of a QTableView, not even
    an inherited method, so how are you calling removeRow() on it? (See
    https://doc.qt.io/qt-6/qtableview-members.html)

    Since you helped me on the last one, maybe you could try to answer a
    couple more [probably simple] roadblocks I'm hitting.


    I just wanna set the font to bold/not-bold when clicking on a row in
    QTableView.



    With a QTableWidget I do it like this:

    font = QFont()
    font.setBold(True) or False
    QTableWidget.item(row,col).setFont(font)



    But the QTableView has data/view 'models' attached to it and that
    syntax doesn't work:


    Tried:
    font = QFont()
    font.setBold(True) or False
    model = QTableView.model()
    model.setFont(model.index(row,col), font)

    Throws AttributeError: 'QSqlTableModel' object has no attribute 'setFont'


    This doesn't throw an error, but doesn't show bold:
    model.setData(model.index(tblRow, col), font, Qt.FontRole)


    Any ideas?

    You definitely need to be setting the font in an item.  I'm not sure but
    I think that your QFont() doesn't have any properties, so it doesn't do anything.  I found this bit in a page - it's in C++ instead of Python
    but that doesn't really make a difference except for the exact syntax to
    use -


    https://forum.qt.io/topic/70016/qlistview-item-font-stylesheet-not-working/4


          QVariant v = ModelBaseClass::data(index,role);
          if( condition && role == Qt::FontRole )
          {
                   QFont font = v.value<QFont>();
                        font.setBold( true );
                   v = QVariant::fromValue<QFont>( font );
          }

    IOW, you have to get the font from the item, then set it to bold, which
    you would do with setFont().  Then you set that new font on the item. Of course you would have to unset bold on it later. See

    https://doc.qt.io/qt-6/qtablewidgetitem.html#font

    Instead of "item", you might need to operate on "row".  I didn't look
    into that.  Since a row probably doesn't have just one font (since it
    can have more than one item), you'd still have to get the font from some
    item in the row.

    You might also be able to make the item bold using CSS, but I'm not sure.

    Thanks

    Internet searches are your friend for questions like this.

    Before I posted I spent a couple hours looking online, reading the docs,
    and trying different ways.

    I found one person that said they did it but their syntax didn't work.
    But it doesn't throw an error either.

    model.setData(model.index(tblRow, col), font, Qt.FontRole)

    When I'm done with my app (nearly 2K LOC) I'm going to put a summary out
    there somewhere with a bunch of examples of easy ways to do things. For
    one thing I wrote zero classes. Not one.



    I've never
    worked with a QTableView, so I had to start with some knowledge about
    some other parts of QT.  I found the first page searching for "qt set qtableview row font", and the second searching for "qtablewidgetitem".


    I used TableWidgets in 2 apps and no problems. In this app there's more
    data and more sorting, and one of the TableWidgets took a while to load
    35K rows (7 items per row). So I tried a TableView. Incredibly fast -
    4x the speed - but it doesn't have the bolding in place yet. That could
    slow it down.

    As you know, a TableView is tied to the underlying datasource (in my
    case via a QSqlTableModel), but it's much faster to show data than a TableWidget, because with the widget you have populate each cell with setItem().

    The Widget is slower but easier to work with. So it's a tradeoff.


    And I think I found some bugs in the TableViews. The Views have editStrategies() that control how data is updated (if the model supports editing), but they don't work the way the docs say they do.

    In my app, when I click on a row a flag field is changed from N to Y
    onscreen (well, it's hidden but it's in the row).

    model.setData(model.index(row,7), 'Y')


    OnFieldChange : all changes to the model will be applied immediately to
    the database.
    model.setEditStrategy(QSqlTableModel.OnFieldChange)

    Doesn't work right. The screen is updated the first row you click on,
    but the db isn't updated until you reload the view.


    OnRowChange : changes to a row will be applied when the user selects
    a different row.
    model.setEditStrategy(QSqlTableModel.OnRowChange)

    Doesn't work right. The screen is updated the first row you click on,
    but the db isn't updated until you reload the view.


    OnManualSubmit : all changes will be cached in the model until either submitAll() or revertAll() is called. model.setEditStrategy(QSqlTableModel.OnManualSubmit)

    This works the best: the screen changes on each row I click, but the db
    isn't updated even if I do submitAll() right after setData(). Have to
    reload the view for the changes to propagate to the db.

    Since none work as they say, the issue is probably on my end. Don't know.

    I just ended up issuing a quick SQL UPDATE statement for the row.


    If you really want speed use the read-only QSqlQueryModel(). Loads 35K
    rows to screen in 1/2 a second (but no bolding applied - I really have
    to figure that out, as it's a central feature of the GUI)


    Thanks for your help.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Passin@21:1/5 to Thomas Passin on Fri Oct 28 22:56:10 2022
    On 10/28/2022 1:01 AM, Thomas Passin wrote:
    {snip]
    You might also be able to make the item bold using CSS, but I'm not sure.


    Apparently so:

    QTreeView::item:selected {
    background-color: #1d3dec;
    color: white;
    }

    See https://joekuan.wordpress.com/2015/10/02/styling-qt-qtreeview-with-css/.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Michael Torrie@21:1/5 to DFS on Sat Oct 29 09:03:28 2022
    On 10/28/22 21:31, DFS wrote:
    I found one person that said they did it but their syntax didn't work.
    But it doesn't throw an error either.

    model.setData(model.index(tblRow, col), font, Qt.FontRole)

    I wouldn't expect that to work but it's understandable why it didn't
    throw an error. setData() is used to edit the contents of the model at
    the provided index. Remember a model can store anything. All this does
    is replace whatever was at that index with a Font object instance. I'm
    puzzled why you keep trying to mess with the model when it's the view
    that does the actual font setting. Remember that a single model can be
    used with more than one view at the same time, each view implementing
    its own style. Thus a model has no information like fonts in it, nor
    should it, other than perhaps HTML text markup that the view will render.

    Did you consult the folk on the PyQt mailing list? Or even the main Qt
    lists? This isn't language-specific stuff you're asking about.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)