QTableWidget::setCellWidget() disables signals from QTableWidget? - qt

I have a QTableWidget instance with its cellEntered(int,int) signal associated to a slot X (that higlights the row in which the cell is contained). Also I have one column containing check boxes.
The problem is adding the checkboxes to the cells of the table using QTableWidget::setCellWidget() method:
QTableWidgetItem *checkBoxItem = new QTableWidgetItem("");
ui->tableWidget->setItem(rowCount, column, checkBoxItem);
QCheckBox* checkBox = new QCheckBox();
ui->tableWidget->setCellWidget(rowCount, column, checkBox);
connect(checkBox, SIGNAL(clicked(bool)),
this, SLOT(checkbox_clicked(bool)));
makes the slot X not to be called when the cursor is over a cell in that column.
The problem is not particular for check boxes but for other types of widgets too.
I have read something about the SignalMapper class in some posts, but that class seems to be useful to map signal from the widget to a slot. Instead, my problem is relative to a signal from the table.
Any suggestion?
Cheers,
Pablo

Why don't you use QTableWidgetItem and set it to checkable with QTableWidgetItem::setCheckState(Qt::CheckState state)?
QTableWidgetItem *check_item = new QTableWidgetItem;
check_item->setCheckState(Qt::Unchecked);
You can also do it with flags.
check_item->setFlags(Qt::ItemIsUserCheckable);
Connect QTableWidget::itemChanged(QTableWidgetItem * item) signal to a slot, and check if the item is checked there.

Related

qt signal-slot on QCheckBox(es) previously added recursively

I'm adding some checkBoxes recursively in tableWidget cells (always in column 1) on a specific function. The final nummber of those checkboxes is not defined and depends on the user input.
QStringList matID;
for(int i=0; i<matID.size(); i++
{
ui->tableWidget->insertRow( ui->tableWidget->rowCount() );
QCheckBox *checkBox = new QCheckBox();
ui->tableWidget->setItem(ui->tableWidget->rowCount()-1,0,checkBox)
}
I would like to connect each one of them with a signal-slot connection which tells me which one has been checked.
Can anyone help me? I don't really understand how to do it...
thanks
Giuseppe
There are four solutions for this problem. I'll only describe the cleanest possiblity.
The best solution is to actually to make your item checkable. You can do this by setting the Qt::ItemIsUserCheckable flag on the item using setFlags(), remember to also keep the defaults.
QStringList matID;
for(int i=0; i<matID.size(); i++
{
ui->tableWidget->insertRow( ui->tableWidget->rowCount() );
QTableWidgetItem *item = ui->tableWidget->getItem(ui->tableWidget->rowCount()-1,0);
item->setFlags(item->getFlags() | Qt::ItemIsUserCheckable);
}
Then, as explained in Qt/C++: Signal for when a QListWidgetItem is checked? (ItemWidgets are similar enough), you can then listen on itemChanged and check using checkState().
The other methods would be:
set an delegate for your column
create a QSignalMapper to map your own QCheckBox pointers to some value identifying your rows
Use the QObject::sender() member function to figure out which checkbox was responsible, and resolve it back to the row on your own.

Qt - Dynamically create, read from and destroy widgets (QLineEdit)

I have the following situation:
I have QSpinBox where the user of my application can select how many instances of an item he wants to create. In a next step, he has to designate a name for each item. I wanted to solve this problem by dynamically creating a number of QLabels and QLineEdits corresponding to the number the user selected in the SpinBox. So, when the number is rising, I want to add new LineEdits, when the number falls, I want to remove the now obsolete LineEdits.
Well, guess what - this turns out much more difficult than I expected. I've searched the web, but the results were more than disappointing. There seems to be no easy way to dynamically create, maintain (maybe in a list?) and destroy those widgets. Can anybody point me in the right direction how to do this?
Take a while and check QListWidget, it does what you exactly want for you by using QListWidgetItem.
An little example: this function adds a new element to a QListWidgetwith a defined QWidget as view and return the current index:
QModelIndex MainWindow::addNewItem(QWidget* widget) {
QListWidgetItem* item = new QListWidgetItem;
ui->listWidget->addItem(item1);
ui->listWidget->setItemWidget(item, widget);
return ui->listWidget->indexFromItem(item);
}
Now, if your user selects X items, you should iterate to create X widgets and you could save all the widgets in a QList:
listWidget.clear();
for (int i=0; i<X; i++) {
QTextEdit* edit = new QTextEdit();
const QModelIndex& index = addNetItem(edit);
qDebug() << "New element: " << index;
listWidget.append(edit);
// Handle edit text event
connect(edit, SIGNAL(textChanged()), this, SLOT(yourCustomHandler()));
}
Now, just show the list with all the edit fields.

Qt - Move a table column to beginning first column index on the table

I am using Qt 5.2.1, I have a tableview in which I have enabled sorting of columns by the user, i.e. they can drag and drop columns by the headers to rearrange them. I want to add a right-click option "Move to front", where the user can right click a column header and when the option is clicked, that column will be moved to the leftmost spot on the table (first column index). I have it set up where it gets to my function properly, but I cannot figure out how to make it move the column once it gets to that point. The rearranging works fine with the drag and drop, but I'm not sure how to have it go automatically to a given index.
void SomeClass::moveColumnToFront(int column, QTableView *table) {
// I assume that you are using QStandardItemModel
QStandardItemModel *model = qobject_cast<QStandardItemModel *>(table->model());
if (model) {
QList<QStandardItem *> columndData = model->takeColumn(column);
model->insertColumn(0, columndData);
}
}
You should learn to search documentation! Yes it is possible to do it using QAbstractItemModel API. But remember that model have to support this feature (QStandardItemModel does)! If you are you using some custom model this may not work.
void SomeClass::moveColumnToFront(int column, QTableView *table) {
bool success = table->model()->moveColumn(QModelIndex(), column,
QModelIndex(), 0);
}

Set selected item for QComboBox

I have a simple QComboBox widget, which has 2 values inside: True and False.
And I have a QString variable currValue, which is one of those values. I want to set my widget's current value with currValue.
I thought that solution is the following:
first lets initialize currValue;
QString currValue = "False";
QComboBox* combo = new QComboBox();
combo->addItem("True");
combo->addItem("False");
combo->setCurrentIndex(combo->findData(currValue));
But it doesn't work.
Am I doing something wrong ?
And Why QComboBox has no member setCurrentItem() or smth like that ?
You actually need to write it in the following way:
QComboBox* combo = new QComboBox();
combo->addItem("True", "True");
combo->addItem("False", "False");
combo->setCurrentIndex(combo->findData("False"));
The problem in your implementation was that you did not set the items' userData, but only text. In the same time you tried to find item by its userData which was empty.
With the given implementation, I just use the second argument of QComboBox::addItem(const QString &text, const QVariant &userData = QVariant())) function that sets the item's userData (QVariant).
UPDATE:
The alternative way to find the combo box item is setting the specific role as the second argument for QComboBox::findData() function. If you don't want to explicitly set the user data, you can refer to the items texts with Qt::DisplayRole flag, i.e.:
QComboBox* combo = new QComboBox();
combo->addItem("True");
combo->addItem("False");
combo->setCurrentIndex(combo->findData("False", Qt::DisplayRole)); // <- refers to the item text
UPDATE 2:
Another alternative could be using text based lookup function QComboBox::findText():
QComboBox* combo = new QComboBox();
combo->addItem("True");
combo->addItem("False");
combo->setCurrentIndex(combo->findText("False"));
I have got answer to my own question.
combo->setCurrentIndex(combo->findText(currValue));

Qt QTabWidget - auto set tab name number

I working on one application and I have problem with tab name.
When I click on push button (NEW) I want to dynamically create new tab.
With this function i create new file:
bool MainWindow::toolbarNewFile()
{
QWidget *page = new QWidget;
QTextEdit *codeEditor = new QTextEdit;
QGridLayout *layout = new QGridLayout;
layout->addWidget(codeEditor);
page->setLayout(layout);
tab_widget->addTab(page,"File");
return true;
}
But all tabs have name "FILE"
How to set in tab name number. When i make new tab auto set number of the tab like this.
File-1, File-2, File-3
I try to set counter i=0; and in addTab(page,"File-"+ i++); Doesn't work.
You need to covert integer to the QString to be able to concat it to the QString. Even better, you can use QString::arg function and get readable and potentially faster code very easily:
tab_widget->addTab(page, QString("File-%1").arg(i++));
Where i is field in your class initialized to 1.

Resources