PDA

View Full Version : Dynamically configured tableview



mikrocat
3rd December 2015, 11:39
I want to read measured data from a device. At first the device tells me what data I can read from it, then the user is able to select the data he wants to measure. He can set an intervall time for measuring and then start the process.





//"monitorwindow.h"
QStringList AvailableData;
QCheckBox *DataCheckbox[];

This is the first proto type of the list that will be created (because communication to the device isn't ready yet):


void MonitorWindow::on_CreateListButton_clicked(){
QVBoxLayout* verticalLayout = new QVBoxLayout;

AvailableData.append("Temp1");
AvailableData.append("Temp2");
AvailableData.append("Temp3");
AvailableData.append("Temp4");

QLabel* tempLabel[AvailableData.count()];
QHBoxLayout* horizontalLayout[AvailableData.count()];

for (int i = 0; i< AvailableData.count(); i++){
DataCheckbox[i] = new QCheckBox;
tempLabel[i] = new QLabel;
horizontalLayout[i] = new QHBoxLayout;

connect(DataCheckbox[i],SIGNAL(clicked()),SLOT(setTransducerFlags()));
horizontalLayout[i]->addWidget(DataCheckbox[i]);

tempLabel[i]->setText(AvailableData.at(i));
horizontalLayout[i]->addWidget(tempLabel[i]);

horizontalLayout[i]->setStretch(1,9);
verticalLayout->addLayout(horizontalLayout[i]);
}
ui->groupBox->setLayout(verticalLayout);
}

On the basis of this list I want to create a tableview that shows me the selected data in different columns while measuring. But I really have no idea of creating a tableview dynamically, I always worked on the base of a model (that already was created).

So step by step. How can I add a new column and set the columnheader text to AvailableData.at(i)?

Thank You! :)

Vikram.Saralaya
3rd December 2015, 17:01
Its not clear to me what "dynamically" means here.

Is there a problem with storing the data generated by the device in a QAbstractTableModel and set a QTableView on this model?

mikrocat
4th December 2015, 08:35
I solved the problem on my own, thank you. :) Maybe dynamically is the wrong word. Sorry.


My next problem is: The way i created the CheckBox seems to be wrong. I want a global declared CheckBox because in other functions I need to check if the CheckBox[i] is checked or enable/disable them. I get to know how many CheckBox I need while runtime.
Header:

QCheckBox *DataCheckbox[];


void MonitorWindow::on_CreateListButton_clicked(){
AvailableData.append("Temp1");
AvailableData.append("Temp2");
AvailableData.append("Temp3");
AvailableData.append("Temp4");

for (int i = 0; i< AvailableData.count(); i++){
DataCheckbox[i] = new QCheckBox;
...
}
}

How do I declare it right? Because this seems to be wrong: If i click on the button everything works fine but when I close the last window of my application, my debug says that the program is crashed and I dont get my return 0.

Vikram.Saralaya
4th December 2015, 11:37
So what you are doing is allocating memory for the QCheckboxes in heap without a parent and not freeing it? I am not surprised it crashes..

Ps: I would recommend against using global checkboxes. There is always a better way if you need it in multiple places.

mikrocat
4th December 2015, 12:43
oh I copied the wrong Code. In my code i set the parent (this) but it still crashes. :( What do you mean with freeing?

Thank You. But what is the better way? How can I check for example if the Box is checked in another function?

Vikram.Saralaya
4th December 2015, 12:51
Ok, so you are creating the checkbox as a child of MonitorWindow. DataCheckbox[i] = new QCheckBox(this);

But there are other classes that access its status.

When the Monitor window destructor is called and the memory is freed, other classes might be trying to check the checkbox status! So the crash.



This is exactly why global objects should be avoided. I cannot suggest another approach without seeing your code, but ideally you need to create this checkbox in say Monitor window and the classes that need access should have a pointer to Monitor window.
Then when they need to check the status they can call monitorWindowObj->GetCheckboxStatus().

mikrocat
4th December 2015, 12:59
Monitor Window is the only class who should have access to the CheckBoxes. I declared it private.

So here a small example of how I use the checkboxes in other functions:


void MonitorWindow::on_CreateListButton_clicked(){
QCheckBox *DataCheckbox[AvailableData.count()];

for (int i = 0; i < AvailableData.count(); i++){
DataCheckbox[i] = new QCheckBox(this);
connect(DataCheckbox[i],SIGNAL(clicked()),SLOT(setTransducerFlags()));
}
}




void MonitorWindow::setTransducerFlags(){
for (int i = 0; i< AvailableData.count(); i++){
if(DataCheckbox[i]->isChecked()){
...
}
else{
...
}
}
}


void MonitorWindow::startRecord(){
...
for (int i = 0; i < AvailableData.count(); i++){
DataCheckbox[i]->setEnabled(false);
}
...
}