Well its used with all QWidgets so would make sense.
Its something to be aware of when creating GUI and also the little note that
any QWidget that are not given a owner/parent, will become a window.
That can be surprised when coming from other frameworks.
Say you make a new label
QLabel *lab= new QLabel();
Since its given no parent, it will become a window.
That was pretty surprising to me first time as i wanted to insert it into the main window.
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.
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!
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.
I don't know if there are any Qt models that support SQL for trees. I think they were all built for tables so you might have to build one yourself.
Have you checked out the Simple Tree Model example? I found it pretty helpful: http://doc.qt.io/qt-5/qtwidgets-itemviews-simpletreemodel-example.html . Also, if you find it easier, you can use a QStandardItemModel instead of a QAbstractItemModel.
Sorry for the late reply. Hidden row is not working because i want to remove row when user click over that row. I did is using TableView's on_table_clicked slot. if i hidden row from model tableView's index and model's index are not going to match. Is there any other solution?
OK but I use the class to encapsulate all data and logics on that data. The collection of all data to fill drop-down boxes, lists reports etc... are all in the class together with the hiding of the record data by get and put protection. So if I have to create an instance every time, I'll spend a whole needless bunch of heap for every list. If I use static functions it's more memory friendly :-)
I have studied the model/view stuff of Qt almost the same thing was used by MS in the MFC time a 20 years ago, they also had a Data/View structure, but then we programmed still in C. So my ignorance is situated there that I have little C++ experience, just played a little with it in the time of Turbo Borland C++ a long time ago.
Professionally I'm a MS programmer but for my son I'm developing a whole suite on Linux and Mono did not give me what I was used to so I switched to Qt and C++. This way the old man has to study again. But it keeps the mind young...