Problem using an integer in a const function after changing its value
-
Coming from here: https://forum.qt.io/topic/144712/how-to-emit-signal-back-to-a-subclassed-sqltablemodel?_=1683088470390
Basically I subclassed the QSqlTableModel and reimplemented the flags function to make only a particular row in a QTableView editable. Works fine, except I have to manually enter the number. Have a look:Qt::ItemFlags ViewFacultyCustomSqlModel::flags(const QModelIndex& index) const{ Qt::ItemFlags flags; flags = QSqlTableModel::flags(index); qDebug<<"clicked_row in flags is: <<clicked_row; if(index.row()==0 ) //here is the issue, if I put clicked_row in place of 0 {flags |= Qt::ItemIsEditable; return flags; } return (QSqlTableModel::flags(index) & ~Qt::ItemIsEditable); }
I declared an
int clicked_row
as a public variable and put it in the above function like this:index.row()==clicked_row
, whileclicked_row
receives a signal of the row number from another class accurately (I checked using qDebug <<"clicked_row received is" <<clicked_row; in the receiving slot).However in flags
clicked_row
goes haywire and gives random values because its not initialized. So I initialize it and then it just stays on that value forever with a gap in between when it receives the signal from another class. Even then in flags its value doesn't change.clicked_row in flags is 41 clicked_row in flags is 41 clicked_row in flags is 41 clicked_row in flags is 41 clicked_row in flags is 41 clicked_row in flags is 41 clicked_row received is 0 //thats accurate clicked_row in flags is 41 //goes haywire again clicked_row in flags is 41 clicked_row in flags is 41 clicked_row in flags is 41 clicked_row in flags is 41 clicked_row in flags is 41 clicked_row in flags is 2097188 //another row selected in QTableView clicked_row in flags is 2097188 clicked_row in flags is 2097188 clicked_row in flags is 2097188 clicked_row in flags is 2097188 clicked_row in flags is 2097188
If I initialize
clicked_row
with a zero I get this:clicked_row in flags is 0 clicked_row in flags is 0 clicked_row in flags is 0 clicked_row in flags is 0 clicked_row in flags is 0 clicked_row in flags is 0 clicked_row received is 1 //I clicked on second row, it doesn't become editable because clicked_row is always zero in flags clicked_row in flags is 0 clicked_row in flags is 0 clicked_row in flags is 0 clicked_row in flags is 0 clicked_row in flags is 0 clicked_row in flags is 0 clicked_row received is 0 //I clicked on first row. it becomes editable because clicked_row is always zero in flags
Bottom line: I receive accurately the value of the row the user wants to edit, but that row doesn't become editable because the integer doesn't retain the value in a const function. The problem is the const function flags. How do I solve this?
(I have tried
static int clicked_row
but it says unidentified declared variable. I tried in desperation for a QList<int> clicked_rows to insert the value at index zero when received, compare it in flags, then reinsert new value at 0 index when new row is clicked. It said,index out of range
because it is a const function. Nothing seems to work inside it) -
@MH24
Honestly, I don't seem to understand what the issue really is. Why should an integerretain the value in a const function
?
The fact that the const function itself can't modify the integer doesn't mean that nobody else can.To begin with, a member variable
int clicked_row
can't receive a signal. It can be modified in a slot or lambda, which is connected to a signal. But that slot/lambda isn't shown in the code, neither are the slot/signal connection and the initialization of the member.The given code is a const member function called
flags
.
Unlessclicked_row
is mutable, it can't be changed withinflags
.
flags
doesn't contain a modification statement anyway.
=> it is safe to assume thatflags
doesn't changeclicked_row
.But
flags
does observe value changes happening elsewhere (i.e. in a non const function which is not shown).If we were soothsayers, we could certainly see the code that is hidden from us and tell you where the problem is. Unfortunately, we aren't.
But why not give it a try:
clicked_row
is modified in a slot connected toQAbstractItemView::clicked(const QModelIndex &index)
.
It is set to the row ofindex
.
The slot containsqDebug() << "clicked_row received is" << clicked_row;
This statement is responsible for the lines containing the right values.Somewhere in the rabbit hole (the part of the code that is hidden from us), the following happens:
clicked_row
is initializedflags
is called and qDebugs the outcome of the data race between slot and initialization.
My crystal ball leaves me with one burning question unanswered:
Why isclicked_row
needed at all?QAbstractItemView::currentIndex()
can be a very reliable friend.... -
@MH24 Sounds like you're dealing with two different instances of the value. Can you show where exactly is your variable declared? Can you show the code that updates its value?
My suspicion is you're updating a local variable and reading from a different one in the flags function or something like that.To make sure you're updating and reading the same variable you can print out its address in both places:
qDebug() << &clicked_row;
it should be the same in both places. If it's not then you messed up somewhere and you're dealing with two different variables.
It said, index out of range because it is a const function.
It said index out of range because you probably tried to access index 0 in an empty list. Nothing to do with function being const. It's the same issue. You're updating and reading from two different variables (int or list doesn't matter)
-
-
@MH24
Everything both @Axel-Spoerl & @Chris-Kawa have said.This whole "clicked row" in the model is a bit "sniffy". But if you are going to use it, one observation: it's all very well where you set
clicked_row
but how careful are you where you clear it (set it to -1)? There will be quite a few potential places you may need to think of once you get the clicking working.... -
Oh, when @JonB finds something sniffy, I'd better get rid of it fast ;-)
-
@Axel-Spoerl
No, your reply was good, and I upvoted it!I'm just not mad keen on why a model would want/to need to know about some "click" in some attached view? This feels like a view-side thing, and models really shouldn't know about views. Just for example, you can have multiple views attached to the same model, in which case how could the model have some single "clicked row" state??
I have not thought it through, but perhaps this "clicking" (if needed at all) belongs either on the selection model or on a proxy model interposed between view and source model? Such that it is unique/variable per view.
-
@Axel-Spoerl said in Problem using an integer in a const function after changing its value:
@MH24
Honestly, I don't seem to understand what the issue really is. Why should an integerretain the value in a const function
?
The fact that the const function itself can't modify the integer doesn't mean that nobody else can.To begin with, a member variable
int clicked_row
can't receive a signal. It can be modified in a slot or lambda, which is connected to a signal. But that slot/lambda isn't shown in the code, neither are the slot/signal connection and the initialization of the member.The given code is a const member function called
flags
.
Unlessclicked_row
is mutable, it can't be changed withinflags
.
flags
doesn't contain a modification statement anyway.
=> it is safe to assume thatflags
doesn't changeclicked_row
.But
flags
does observe value changes happening elsewhere (i.e. in a non const function which is not shown).If we were soothsayers, we could certainly see the code that is hidden from us and tell you where the problem is. Unfortunately, we aren't.
But why not give it a try:
clicked_row
is modified in a slot connected toQAbstractItemView::clicked(const QModelIndex &index)
.
It is set to the row ofindex
.
The slot containsqDebug() << "clicked_row received is" << clicked_row;
This statement is responsible for the lines containing the right values.Somewhere in the rabbit hole (the part of the code that is hidden from us), the following happens:
clicked_row
is initializedflags
is called and qDebugs the outcome of the data race between slot and initialization.
My crystal ball leaves me with one burning question unanswered:
Why isclicked_row
needed at all?QAbstractItemView::currentIndex()
can be a very reliable friend....I had mentioned at the beginning that the rest of the relevant code was in a previous post: https://forum.qt.io/post/756349. I didn't want to clutter with something that was already working. So I had given a written description. My apologies.
Here is
Viewfaculty.cpp
with the relevant parts highlighted:ViewFaculty::ViewFaculty(QWidget *parent) : QMainWindow(parent), ui(new Ui::ViewFaculty) { ui->setupUi(this); ViewFaculty::setWindowTitle("View Faculty Members"); QWidget *contentWidget = new QWidget(); QGridLayout *layoutG = new QGridLayout(); QGroupBox *boxTables = new QGroupBox(contentWidget); boxTables->setFixedWidth(475); QVBoxLayout *layoutV = new QVBoxLayout(boxTables); layoutG->addWidget(boxTables,0,0, Qt::AlignLeft); layoutG->setColumnStretch(0, 10000); layoutG->setVerticalSpacing(50); layoutG->setHorizontalSpacing(200); ui->viewFacultybBckButton->setGeometry(700,30,8,5); connect(ui->viewFacultybBckButton, SIGNAL(clicked()),this, SLOT(close())); QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL"); db.setHostName("localhost"); db.setDatabaseName("uniapp"); db.setUserName("*****"); db.setPassword("*********"); bool ok = db.open(); if(!ok){ qDebug()<< db.lastError(); } else{ qDebug() << "Connected to mysql admin"; } QList<QString> depList; //dynamic array QList<QString> uniquedepList; ViewFacultyCustomSqlModel *model = new ViewFacultyCustomSqlModel(0,db); model->setTable("employee"); model->select(); for (int i = 0; i < model->rowCount(); ++i) { QString department = model->record(i).value("department").toString(); depList.insert(i,department); qDebug() << "Department is: "<<depList[i]; } for (int j = 0; j< depList.size();j++){ int depCount = 0; for (int k = j; k<depList.size() && depCount <2;k++){ if(depList[j]==depList[k]){ depCount++; } } if(depCount == 1){ uniquedepList.push_back(depList[j]); } } int start_y = 10; for (int i = 0; i< uniquedepList.size();i++){ QString match_dept = uniquedepList[i]; ViewFacultyCustomSqlModel *modelLoop = new ViewFacultyCustomSqlModel(0,db); modelLoop->setTable("employee"); modelLoop->select(); QString querystring = QString("department = %1%2%3").arg("'").arg(uniquedepList[i]).arg("'"); qDebug() << querystring; modelLoop->setFilter(querystring); int dynamic_rows = modelLoop->rowCount(); QLabel *label = new QLabel; label->setText(uniquedepList[i]); label->setGeometry(30,start_y,100,20); modelLoop->setHeaderData(0, Qt::Horizontal, QObject::tr("ID")); modelLoop->setHeaderData(1, Qt::Horizontal, QObject::tr("Name")); modelLoop->setHeaderData(2, Qt::Horizontal, QObject::tr("Department")); QTableView *view = new QTableView; QVBoxLayout *layoutVButtons = new QVBoxLayout; QHBoxLayout *layoutMergeWithTables = new QHBoxLayout; layoutMergeWithTables->addWidget(view); layoutMergeWithTables->addLayout(layoutVButtons); view->setModel(modelLoop); view->setEditTriggers(QAbstractItemView::NoEditTriggers); view->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed); view->setColumnWidth(1,150); view->setGeometry(30,start_y+10+label->geometry().height(),365,200); layoutV->addWidget(label); layoutV->addLayout(layoutMergeWithTables); //This creates a button with every row of the QTableView. Upon clicking it sends the row number **for(int i = 0; i< dynamic_rows;i++){ QPushButton *button_dynamic = new QPushButton; button_dynamic->setText("Edit"); layoutVButtons->addWidget(button_dynamic); layoutVButtons->setAlignment(Qt::AlignTop); layoutVButtons->setContentsMargins(0,25,0,0); connect(button_dynamic,&QPushButton::clicked,[button_dynamic,view,i,modelLoop, this](){ if(button_dynamic->text()=="Edit"){ emit signal_clickedRow(i); button_dynamic->setText("Save"); modelLoop->setEditStrategy(QSqlTableModel::OnManualSubmit); view->setSelectionMode(QAbstractItemView::SingleSelection); view->setSelectionBehavior(QAbstractItemView::SelectItems); view->selectRow(i); view->setEditTriggers(QAbstractItemView::SelectedClicked); } else if(button_dynamic->text()=="Save"){ //QModelIndex tableIndex = view->model()->index(i,0,QModelIndex()); //view->edit(tableIndex); //tried above too with same result view->edit(view->currentIndex()); button_dynamic->setText("Edit"); modelLoop->submitAll(); view->setEditTriggers(QAbstractItemView::NoEditTriggers); } });** } start_y = start_y+240; } contentWidget->setLayout(layoutG); QScrollArea *scrollArea = new QScrollArea(); scrollArea->setWidget(contentWidget); ui->viewFacultybBckButton->setParent(scrollArea); ui->viewFacultybBckButton->setGeometry(700,30,50,30); setCentralWidget(scrollArea); }
This is
Viewfaculty.h
:namespace Ui { class ViewFaculty; } class ViewFaculty : public QMainWindow { Q_OBJECT public: explicit ViewFaculty(QWidget *parent = nullptr); ~ViewFaculty(); signals: void on_viewfacultycloseButtonClicked(); void signal_clickedRow(int); //signal that sends row value public slots: void closeEvent(QCloseEvent *event); private slots: void on_viewFacultybBckButton_clicked(); private: Ui::ViewFaculty *ui; }; #endif // VIEWFACULTY_H
This is
ViewFacultyCustomSqlModel.h
:class ViewFacultyCustomSqlModel : public QSqlTableModel { Q_OBJECT public: int clicked_row; //Declaration ViewFacultyCustomSqlModel(QObject *parent = 0, QSqlDatabase db = QSqlDatabase()); public slots: //Slot receiving row value void receivedFromViewFac(int indexFromViewFac){ clicked_row = indexFromViewFac; qDebug() << "Clicked row received is" <<clicked_row; } // Accurately shows the value of the row Qt::ItemFlags flags(const QModelIndex& index) const; }; #endif // VIEWFACULTYCUSTOMSQLMODEL_H
This is
ViewFacultyCustomSqlModel.cpp
:ViewFacultyCustomSqlModel::ViewFacultyCustomSqlModel(QObject *parent, QSqlDatabase db): QSqlTableModel(parent,db){ } Qt::ItemFlags ViewFacultyCustomSqlModel::flags(const QModelIndex& index) const{ Qt::ItemFlags flags; flags = QSqlTableModel::flags(index); qDebug() << "Clicked row in flags is" <<clicked_row; if(index.row()==clicked_row) return flags; } return (QSqlTableModel::flags(index) & ~Qt::ItemIsEditable); } {flags |= Qt::ItemIsEditable;
Both of these classes have their signal and slot connected in a third class unimain.cpp:
connect(viewFaculty,SIGNAL(signal_clickedRow(int)),viewfacultycustomsqltablemodel,SLOT(receivedFromViewFac(int)));
(This was the topic of my last post: https://forum.qt.io/topic/144712/how-to-emit-signal-back-to-a-subclassed-sqltablemodel?_=1683181051649
I have to update this^ to latest Qt standards of slots and signals)@Axel-Spoerl said in Problem using an integer in a const function after changing its value:
My crystal ball leaves me with one burning question unanswered:
Why is clicked_rowneeded at all? QAbstractItemView::currentIndex() can be a very reliable friend....Because the user can click anywhere in the table. So, only the button that they clicked should have the row enabled. This information is to be conveyed to the
flags
function in the subclassed model. That is why a signal-slot connection was needed and it works. Just that I cannot convey info to the subclassed model, yet.@JonB said in Problem using an integer in a const function after changing its value:
@MH24
Everything both @Axel-Spoerl & @Chris-Kawa have said.This whole "clicked row" in the model is a bit "sniffy". But if you are going to use it, one observation: it's all very well where you set
clicked_row
but how careful are you where you clear it (set it to -1)? There will be quite a few potential places you may need to think of once you get the clicking working....Wouldn't the new value emitted from the signal update the value in the slot?
@Chris-Kawa said in Problem using an integer in a const function after changing its value:
Sounds like you're dealing with two different instances of the value. Can you show where exactly is your variable declared? Can you show the code that updates its value?
My suspicion is you're updating a local variable and reading from a different one in the flags function or something like that.
To make sure you're updating and reading the same variable you can print out its address in both places:
qDebug() << &clicked_row;I did put two qDebugs:
//When view is opened: Address of clicked_row in flags is: 0x559335619f28 Address of clicked_row in flags is: 0x559335619f28 Address of clicked_row in flags is: 0x559335619f28 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335619f28 Address of clicked_row in flags is: 0x559335619f28 Address of clicked_row in flags is: 0x559335619f28 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335619f28 Address of clicked_row in flags is: 0x559335619f28 Address of clicked_row in flags is: 0x559335619f28 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335619f28 Address of clicked_row in flags is: 0x559335619f28 Address of clicked_row in flags is: 0x559335619f28 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335619f28 Address of clicked_row in flags is: 0x559335619f28 Address of clicked_row in flags is: 0x559335619f28 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335619f28 Address of clicked_row in flags is: 0x559335619f28 Address of clicked_row in flags is: 0x559335619f28 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335619f28 Address of clicked_row in flags is: 0x559335619f28 Address of clicked_row in flags is: 0x559335619f28 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 // I have three QTableViews, first one has 1 row and 3 columns, 2nd one has two rows and 3 columns, third one has 3 rows and 3 columns. You can see 3,6,9 pattern above. It is generating a different clicked_row for every QTableView. //Now when I click say 2nd button (2nd row) of third table: Address of clicked_row in slot is: 0x55933561bc08 //Here is the one updated Address of clicked_row in flags is: 0x559335644bb8 //But there is another one used in flags Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8// I clicked many times on a particular index to see if its enabled for editing Address of clicked_row in flags is: 0x559335619f28 //Back to the 3,6,9 pattern Address of clicked_row in flags is: 0x559335619f28 Address of clicked_row in flags is: 0x559335619f28 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 //I clicked some more trying to edit Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335619f28 Address of clicked_row in flags is: 0x559335619f28 Address of clicked_row in flags is: 0x559335619f28 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335623b08 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 edit: editing failed //I clicked 'Save' on my button Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8 Address of clicked_row in flags is: 0x559335644bb8
How do I declare it correctly? Apologies for a very long post but I cannot post again. There is a time limit.
-
@MH24 said in Problem using an integer in a const function after changing its value:
@JonB said in Problem using an integer in a const function after changing its value:
This whole "clicked row" in the model is a bit "sniffy". But if you are going to use it, one observation: it's all very well where you set clicked_row but how careful are you where you clear it (set it to -1)? There will be quite a few potential places you may need to think of once you get the clicking working....
Wouldn't the new value emitted from the signal update the value in the slot?
If a new signal is emitted, yes of course. But what if no new signal/click is performed? I clicked on a row 10 minutes ago, and since then I have done all sorts of operations on the view without clicking a row again. I have used the keyborad instead of clicking, I have added/deleted/sorted/re-filled the rows so that the index no longer identifies the correct row, and so forth. Meanwhile your variable still holds the index of what I clicked a long time ago, and you are doing whatever you do to act on that. This is the sort of thing
currentIndex()
orselectedIndex()
/selection model looks after, you will have/ought to do the same....Your output from
qDebug() << &clicked_row;
seems to show multiple different addresses for it. I'm not sure what might be going on. If you search the whole of your source code forint clicked_row
--- note theint
, we are looking for declarations of a variable with that name --- what does it come up with? -
@MH24 Here's your problem:
ViewFacultyCustomSqlModel *model = new ViewFacultyCustomSqlModel(0,db);
this creates a model that you never set on any view.
for (int i = 0; i< uniquedepList.size();i++){ ViewFacultyCustomSqlModel *modelLoop = new ViewFacultyCustomSqlModel(0,db); ...
this creates a bunch of other models, one for each of a bunch of views.
Each of all of these models have their ownclicked_row
member.
All of those models are leaking memory by the way, because you're not giving them parents.Then for each of the views and each of the buttons you emit
signal_clickedRow
, without indicating which view it was clicked in or which model should the variable be set in.Then you have this single connect:
connect(viewFaculty,SIGNAL(signal_clickedRow(int)),viewfacultycustomsqltablemodel,SLOT(receivedFromViewFac(int)));
which means that no matter from which view the click came from the
clicked_row
variable will always be updated only in that sameviewfacultycustomsqltablemodel
, whatever that is.So yeah, you're updating the value in one model and then trying to read it from a bunch of completely different models, which obviously won't work as you expect., as each of the models has their own copy of the variable.
Your code is kinda messy, so I'm not sure what you want to achieve, but if you really want to have a separate model for each view then you have to have a different clicked connection for each. Since you're already mixing model and view code (which is quite messy) you might as well have that signal in your model or view class and not in the containing MainWindow.
In any case, apart from fixing that issue don't forget to fix the leaks. Also when doing some algorithms check if Qt doesn't provide a ready made solution, as it would make your code a lot cleaner. For an example all of this mess:
for (int j = 0; j< depList.size();j++){ int depCount = 0; for (int k = j; k<depList.size() && depCount <2;k++){ if(depList[j]==depList[k]){ depCount++; } } if(depCount == 1){ uniquedepList.push_back(depList[j]); }
you can replace with simply
depList.removeDuplicates();
-
@JonB said in Problem using an integer in a const function after changing its value:
But what if no new signal/click is performed? I clicked on a row 10 minutes ago, and since then I have done all sorts of operations on the view without clicking a row again. I have used the keyborad instead of clicking, I have added/deleted/sorted/re-filled the rows so that the index no longer identifies the correct row, and so forth. Meanwhile your variable still holds the index of what I clicked a long time ago, and you are doing whatever you do to act on that. This is the sort of thing currentIndex() or selectedIndex()/selection model looks after, you will have/ought to do the same....
This is true but my main issue is that I want one row only to be editable based on which button is clicked, while the model applies editable property to all its rows and columns regardless of which button was clicked. That is why I subclassed the model in the first place.
@JonB said in Problem using an integer in a const function after changing its value:
. If you search the whole of your source code for int clicked_row --- note the int, we are looking for declarations of a variable with that name --- what does it come up with?
Just this one instance in the code I put above.
@Chris-Kawa said in Problem using an integer in a const function after changing its value:
Here's your problem:
ViewFacultyCustomSqlModel *model = new ViewFacultyCustomSqlModel(0,db);this creates a model that you never set on any view.
This model is just to obtain values from the database that I can filter to extract names of departments and occurrences. Based on that I dynamically generate new models and associate them with their own views. Should I have used a QSqlTableModel here instead? Can we use the default and subclassed one in same class?
@Chris-Kawa said in Problem using an integer in a const function after changing its value:
Then for each of the views and each of the buttons you emit signal_clickedRow, without indicating which view it was clicked in or which model should the variable be set in.
Yes I am aware of that. Whenever I use
index.row() == 0
for example, the first rows of all three QTableviews become editable and nothing else. My main focus was to first get the connection going between button click and only particular row enabled for editing. So if I click 2nd button of any table all 2nd rows of all tables would be edit enabled. Not final solution but intermediary one but const function is a huge roadblock.@Chris-Kawa said in Problem using an integer in a const function after changing its value:
Your code is kinda messy, so I'm not sure what you want to achieve, but if you really want to have a separate model for each view then you have to have a different clicked connection for each. Since you're already mixing model and view code (which is quite messy) you might as well have that signal in your model or view class and not in the containing MainWindow.
My target is this: Display dynamically the tables pertaining to each department of a university. 3 departments, 3 tables for eg. Each table will contain faculty of that department only. Each faculty member can only edit their own row in their department's table and nothing else. Without subclassing QSqlTableModel, even if I disable 'Edit' button for other rows, the issue is that whole table (pertaining to one particular department) becomes editable and you can edit someone else's row & click on 'Save' on your own button and that value is edited. When I subclass I can manually set a particular row to be enabled but not from user input via a button.
I tried having a separate clicked connection for a model but it brought me to the chicken and egg problem that both classes (view and subclass) were including each other's headers and diving into infinite db connections. See my last thread here: https://forum.qt.io/topic/144712/how-to-emit-signal-back-to-a-subclassed-sqltablemodel?_=1683088470390Sorry for the long reply. Not challenging your ideas and am grateful for them but totally lost on how to disable editing in a QTableView based on some dynamic user-input criteria.
-
@MH24 said:
Should I have used a QSqlTableModel here instead? Can we use the default and subclassed one in same class?
Models are for displaying in a view. You don't need a model to get data out of a database. Use QSqlQuery instead and as a local variable. You don't need to allocate everything dynamically if you only use it locally. You can construct a SQL query that will get you those unique values while you're at it. Simpler and shorter.
So if I click 2nd button of any table all 2nd rows of all tables would be edit enabled
Then the problem is still the same - you're writing a variable in one model and read different variables in different models. Either write the variable to all the models or read from a single place that you write to.