Skip to content
  • 0 Votes
    4 Posts
    1k Views
    Venkatesh VV

    @Kushan
    Or you can use resizeColumnsToContents() method for the same.

  • 0 Votes
    4 Posts
    4k Views
    VRoninV

    You can use either QTreeWidget, QTableWidget, QTreeView+QStandardItemModel, QTableView+QStandardItemModel, QTreeView+QAbstactTableModel subclass, QTableView+QAbstactTableModel subclass for what you are trying to do.

    I would go with a QT*View+QStandardItemModel (tree or table doesn't matter).

    The functionalities you describe are:

    only some columns will be editable

    use QStandardItem::setFlag

    Entering a value in the cents column (a logarithmic measure of frequency) will change the value in the hertz column, and vice versa

    connect a slot to QStandardItemModel::dataChanged signal

    There will be a button next to the table to add an additional note to the scale

    connect a slot that calls QStandardItemModel::insertRows to the QPushButton::clicked signal

  • 0 Votes
    11 Posts
    6k Views
    JonBJ

    @MrBolton
    Sorry, I really don't understand your comment. Precisely the point is that with "bigger data sets" you would have to fetch all the data, which is incredibly slow and may well exceed available memory. (OTOH, if the dataset is "small" the overhead of re-query compared to holding all the previous rows locally is also "small".) As a rule of thumb, one always wants as much work to be done at the server side as possible, not client side.

    Let's say the table has a million rows and the query I want to pose is:

    SELECT * FROM table ORDER BY column LIMIT 100

    Very approximately, pushing the ORDER BY to the server instead of into a QSortFilterProxyModel will run 10 thousand times faster and use one ten-thousandth of the client memory. That's why I would be very careful before advising people to use QSortFilterProxyModel without understanding the ramifications!

  • 0 Votes
    5 Posts
    9k Views
    O

    Thanks everyone for answer.
    I am end up with write my own models, the load time reduce to 3s for 30k row and 150 col each.

  • 0 Votes
    3 Posts
    2k Views
    VRoninV

    Put a QSortFilterProxy model in-between. then save from the proxy instead of the main model.

    P.S.
    connect(currentTableHeader, SIGNAL(sectionClicked(int)), this, SLOT(on_sectionClicked(int))); and void mainWidget::on_sectionClicked(int index) are useless. this is the default behaviour of QTableView, you don't have to implement it manually

  • 0 Votes
    4 Posts
    2k Views
    SGaistS

    Did you already checked the bug report system to see if there was something related ?

    If not, please consider opening a new report providing a minimal compilable example showing the behaviour.

  • 0 Votes
    1 Posts
    742 Views
    No one has replied
  • 0 Votes
    11 Posts
    13k Views
    R

    You might get error is the following statement, since ui is not included
    ui->MWtextEdit->setText(text)

    which can be got ridden by adding following syntax in in mainwindow.h
    #include "ui_mainwindow.h"

  • 0 Votes
    3 Posts
    1k Views
    VRoninV

    In 90% of the cases you can use QStandardItemModel instead of going through the minefield that is subclassing an abstract model.

    My advice is just to use that "universal model" instead of a custom one. If you really, really want to customise it as performance of QStandardItemModel is a problem then make sure you run your model through the Model Test (needs just a couple of trivial fixes to work on Qt5) that will tell you if you did everything as you were supposed to or you fell in the countless pitfalls of model subclassing

  • 0 Votes
    2 Posts
    899 Views
    SGaistS

    Hi and welcome to devnet,

    You can use a proxy model that adds the columns you want/need.

    You can keep updating the DB content and trigger the GUI update at some known interval or when a certains amount of changed happened to the database.

  • 0 Votes
    6 Posts
    4k Views
    VRoninV

    @blastdoman You are correct, let's try this:

    #include <QStyledItemDelegate> class DataChangeDelegate : public QStyledItemDelegate{ Q_OBJECT Q_DISABLE_COPY(DataChangeDelegate) public: enum{IsDirtyRole=Qt::UserRole + 44}; explicit DataChangeDelegate(QObject* parent=Q_NULLPTR) :QStyledItemDelegate(parent) {} virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const Q_DECL_OVERRIDE{ const QVariant oldData = index.data(Qt::EditRole); QStyledItemDelegate::setModelData(editor,model,index); if(index.data(Qt::EditRole)!=oldData) model->setData(index,true,IsDirtyRole); } }; DataChangeDelegate* signalingDelegate=new DataChangeDelegate(this); connect(tableView->selectionModel(),&QItemSelectionModel::currentChanged,this,[this](const QModelIndex& idx)->void{ const int newRow= idx.isValid() ? idx.row():-1; if(newRow==currentRow) return; if(currentRow>=0){ const int maxCols =idx.model()->columnCount(idx.parent()); for(int i=0;i<maxCols ;++i){ if(idx.model()->index(currentRow,i,idx.parent()).data(DataChangeDelegate::IsDirtyRole).toBool()){ validateRow(currentRow); /* inside validateRow call something like: for(int i=0;i<model->columnCount();++i) model->setData(model->index(currentRow,i),QVariant(),DataChangeDelegate::IsDirtyRole); */ break; } } } currentRow=newRow; }); tableView->setItemDelegate(signalingDelegate);
  • 0 Votes
    9 Posts
    4k Views
    VRoninV

    this should return the list of the row indexes as sorted in the view. Hidden rows will be placed at the beginning

    QList<int> viewIndexes(const QHeaderView* const view){ if(!view) return QList<int>(); const int numSections= view->count(); QMap<int,int> sorter; for(int i=0;i<numSections;++i) sorter.insert(view->sectionPosition(i),i); return sorter.values(); }

    or alternatively:

    QVector<int> viewIndexes(const QHeaderView* const view){ if(!view) return QVector<int>(); const int numSections=view->count(); QVector<int> result(numSections); for(int i=0;i<numSections;++i) result[i]=i; // Use stable_sort if you want the hidden sections still placed at the beginning but in the same order as the original model std::sort(result.begin(),result.end(),[view](int a,int b)->bool{return view->sectionPosition(a)<view->sectionPosition(b);}); return result; }

    You'll have to benchmark them to tell which is more efficient

  • 0 Votes
    17 Posts
    10k Views
    jwernernyJ

    I've uncovered the same issue with QSqlQueryModel using the Windows QODBC database engine connected to MS SQL Server, and have been do some digging. Hopefully this will help others experiencing this issue.

    There are a couple of different things happening here.

    First, QSqlQueryModel does not support forward only queries. If you try to use a forward only query, QSqlQueryModel::lastError() will return "Forward-only queries cannot be used in a data model".

    That seems clear, but does not explain the situation when the forward only is left in its default false state or explicitly set in code. During my exploration of the issue, I would notice that even though I called QSqlQuery::setForwardOnly(false), a call to QSqlQuery::isForwardOnly() made after the query was executed would show forward only set to true, something I did not understand.

    Then I read the Qt documentation for setForwardOnly:

    Setting forward only to false is a suggestion to the database engine, which has the final say on whether a result set is forward only or scrollable. isForwardOnly() will always return the correct status of the result set.

    The database engine has the final say whether or not forward only is used!

    Why was the database engine setting forward only? Qt's SQL Database Drivers documentation gives part of the answer if you know what you are looking at.

    ODBC Stored Procedure Support

    With Microsoft SQL Server the result set returned by a stored procedure that uses the return statement, or returns multiple result sets, will be accessible only if you set the query's forward only mode to forward using QSqlQuery::setForwardOnly().

    By observation, the QODBC database engine (in Qt 5.8) recognizes when more than one return set has resulted from the query, so it is automatically setting forward only to true.

    How are multiple result sets generated? I've uncovered a few ways.

    A query that has multiple select statements (e.g. select * from table1; select * from table2). Stored Procedures In particular, MS SQL Server documentation has this to say:

    SQL Server stored procedures have four mechanisms used to return data:

    Each SELECT statement in the procedure generates a result set. The procedure can return data through output parameters. A cursor output parameter can pass back a Transact-SQL server cursor. The procedure can have an integer return code.

    The first item in Microsoft's list was the key for me. When NOCOUNT is OFF, Even a simple internal variable assignment using a select (e.g. select @user = 'fred') generated a return set. Setting NOCOUNT to ON stops this behavior. From Microsoft's documentation on NOCOUNT

    SET NOCOUNT ON prevents the sending of DONE_IN_PROC messages to the client for each statement in a stored procedure. For stored procedures that contain several statements that do not return much actual data, or for procedures that contain Transact-SQL loops, setting SET NOCOUNT to ON can provide a significant performance boost, because network traffic is greatly reduced.

    The Solution for me turned out to be two things:

    Add SET NOCOUNT ON to the top of my stored procedure so that only the select statement I cared about was returned Instead of using QSqlQueryModel, manually extract the results from the query and build my own QStandardItemModel.
  • 0 Votes
    10 Posts
    26k Views
    S

    @VRonin hey it works. I created a separate qt project and it's working there. I will see if I am doing something wrong in my project.

    Actually the row to which I am trying to set a background color also has some color set to it in table widget stylesheet. Also tablewidget items also have a background color. I will check there. Thanks again.

  • 0 Votes
    4 Posts
    2k Views
    SGaistS

    Glad you found a solution !

    Can you share a small sample code that triggers this behaviour ?

  • 0 Votes
    9 Posts
    9k Views
    VRoninV

    @IMAN4K said in change QSortFilterProxyModel behaviour for multiple column filtering:

    Answer from stackfverflow : http://stackoverflow.com/questions/39488901/change-qsortfilterproxymodel-behaviour-for-multiple-column-filtering

    This answer is the typical example that lead people to say

    subclassing QSortFilterProxyModel, which would likely have a very limited reusability

    It's bad. the proxy model implementation should not depend on the structure of the underlying data in sourceModel

  • 0 Votes
    4 Posts
    4k Views
    J

    @raven-worx: while I'm not sure it is the right solution for what @tokafr wants to do, he can take ownership of the vertical scrollbar and have some influence this way. I have done it before that way.

    @tokafr: Instead of trying to influence the hidden layout of the QTableView, you could mask the space between the header view and the vertical scrollbar to make it look like it being part of the header view. Stylesheets are probably the best place to try.

  • 0 Votes
    2 Posts
    797 Views
    mrjjM

    Hi
    Did you have a look at
    http://doc.qt.io/qt-4.8/qitemeditorfactory.html#details

    Seems to be such editor cache, like you have/want.

  • Qtableview aligment

    Solved General and Desktop
    5
    0 Votes
    5 Posts
    4k Views
    PabloArgP

    Hi again Vronin;

    I improve little bit your idea. Perphaps is usefull for somebody.
    As I comment before, my tableview will have diferent types of Aligment. Some columns goes to right, other left, other center.
    But, I will use the same subclass created for QSqlQueryModel I will call this subclass many times in diferent part of my application.
    I created something more variable, so at the moment that you call the subclass you must define by QStringList define in my subclass, for each column what kind of aligment you like.

    Thanks Vronin for your help. And I share the code with you

    ================== MyQSqlQueryModel.h ======================
    #ifndef MYQSQLQUERYMODEL_H
    #define MYQSQLQUERYMODEL_H
    #include <QSqlQueryModel>

    #include <QObject>

    class MyQSqlQueryModel : public QSqlQueryModel
    {
    public:
    MyQSqlQueryModel();
    QVariant data(const QModelIndex &item, int role) const;
    QStringList AligmentDefinition; // HERE I DEFINE THE ALIGMENT BY COLUMNS
    };

    #endif // MYQSQLQUERYMODEL_H

    ================== MyQSqlQueryModel.cpp ======================
    #include "myqsqlquerymodel.h"

    MyQSqlQueryModel::MyQSqlQueryModel()
    {

    }

    QVariant MyQSqlQueryModel::data(const QModelIndex &item, int role) const
    {
    if(role==Qt::TextAlignmentRole)
    {
    if(AligmentDefinition.size()==0)
    {// There are any definition
    return 0;
    }
    if(item.column() > AligmentDefinition.size())
    {// There are no definition for that Column
    return 0;
    }
    int i = item.column();
    QString Value = AligmentDefinition.value(i);
    if(Value =="1")
    return int(Qt::AlignRight | Qt::AlignVCenter);
    if(Value=="2")
    return int(Qt::AlignCenter | Qt::AlignVCenter);
    if(Value=="3")
    return int(Qt::AlignLeft | Qt::AlignVCenter);
    }
    return QSqlQueryModel::data(item,role);
    }

    =============== MAIN PROGRAM =======================
    MyQSqlQueryModel *model = new MyQSqlQueryModel;
    model->setQuery("SELECT * FROM SPSSourceLines");
    model->AligmentDefinition << "1" << "2" << "3";
    QModelIndex index;
    index = model->index(0,0);
    model->data(index,7);