I have a vector.
QVector<QPushButton*> buttonVector;
With this function I add dynamically buttons to the UI.
void MainWindow::createButton()
{
for(int x = 0; x < list.length(); x++)
{
QPushButton *button = new QPushButton(this);
button->setText(QString::number(list.at(x)->ID()));
button->setGeometry(x_cor,y_cor,50,50);
//button->setVisible(true);
buttonVector.append(button);
}
}
At the start of my program this function triggers and works perfectly, every button is showing.
But after I recreate every button with this function after I press a button, they are all invisible if I don't add the line:
button->setVisible(true);
Why is that? At the beginning they are all visible without this line.
Related
I have a scenario where I am asking the user for a number between 1 and 10 and creating that number of buttons of the type QPushButton. I then want to create a function such that when I click the button the number on the button gets printed.
Just use a lambda function like this:
for (int i = 1; i < numButtons; i++)
{
QPushButton *btn = new QPushButton(...);
connect(btn, &QPushButton::clicked, [=]() {
// Do something with 'i'
}
}
With the following code to create radio buttons in a group box I get no results. A bit of background : in my display every objects has multiple variants and the user must choose which one to display (or all). What update/refresh command did I miss, or what is wrong ?
for(int i = 0; i < MAX_NUM_VARIANTS+1; i++)
{
m_variantButtons[i] = new QRadioButton();
m_variantButtons[i]->setText(QString::number(i));
m_variantButtons[i]->setObjectName(QString("m_pbDisplayVariant%1").arg(i));
QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
sizePolicy.setHeightForWidth(true);
m_variantButtons[i]->setSizePolicy(sizePolicy);
((QGridLayout*)(ui.m_groupBoxVariants->layout()))->addWidget(m_variantButtons[i], 1, i);
((QGridLayout*)(ui.m_groupBoxVariants->layout()))->update();
connect(m_variantButtons[i], SIGNAL(clicked(bool)), this, SLOT(updateDisplaySettings()));
m_variantButtons[i]->setVisible(true);
}
((QWidget*)(ui.m_groupBoxVariants))->updateGeometry();
I have a QTableWidget and for all rows I set a setCellWidget at one column to a button.
I would like to connect this button to a function that delets this row.
I tried this code, which does not work, because if I simply click my button I do not set the current row to the row of the button.
ui->tableWidget->insertRow(ui->tableWidget->rowCount());
QPushButton *b = new QPushButton("delete",this);
ui->tableWidget->setCellWidget(ui->tableWidget->rowCount()-1,0,b);
connect(d,SIGNAL(clicked(bool)),this,SLOT(deleteThisLine()));
...
void MainWindow::deleteThisLine()
{
int row = ui->tableWidget->currentRow();
ui->tableWidget->removeRow(row);
}
How can I connect my button to a function in a way that the function knows which button (at which row) was pressed?
To remove the row we must first get the row, if we are inserting widgets inside the cells the currentRow() method will not return the appropriate row, in many cases it will return the row of the last cell without widget that has been selected.
For that reason you must opt for another solution, for this case we will use the indexAt() method of QTableWidget, but for this we need to know the position in pixels of the cell. when one adds a widget to a cell, this cell will be the parent of the widget, so we can access from the button to the cell using the parent() method, and then get the position of the cell with respect to the QTableWidget and use it in indexAt(). To access the button we will use the sender().
When the current cell is removed the focus is lost, a possible solution is to place the focus again in another cell.
void MainWindow::deleteThisLine()
{
//sender(): QPushButton
QWidget *w = qobject_cast<QWidget *>(sender()->parent());
if(w){
int row = ui->tableWidget->indexAt(w->pos()).row();
ui->tableWidget->removeRow(row);
ui->tableWidget->setCurrentCell(0, 0);
}
}
Use this connection way to connect signal to a slot:
connect(ui->btnDelete, &QPushButton::clicked, this,&MainWindow::deleteRow);
And delete for example a row on call function:
void MainWindow::deleteRow()
{
int row = ui->tableWidget->currentRow();
ui->tableWidget->removeRow(row);
}
Create a custom class, where you pass the created push button object and the row index. From your custom push button class, handle the push button press event and emit a custom signal (it will carry the index number) handled from the object where your custom pushbutton is created. Some related code are below, to give you a hint:
.h
class mypushbutton {
explicit mypushbutton(QObject *parent = 0, QPushButton *pushbutton = 0, int index = 0);
signal:
void deleteRow(int index);
}
.cpp
mypushbutton() {
connect(pushbutton, SIGNAL(clicked(bool)), this, SLOT(actionButtonClick(bool)));
}
actionbuttonclicked() { emit deleteRow(index);}
I have created a QTableWidget in which I've used setCellWidget(QWidget*). I've set QLineEdit in the cell widget. I've also created a delete button and clicking that button sends a signal to the function deleteRow. I've also used a function currentRow() to get the current row, but it returns -1 because of the QLineEdit. The code snippet is below.
void createTable() {
m_table = new QTableWidget(QDialog); //member variable
for (int i = 0; i < 3; i++)
{
QLineEdit *lineEdit = new QLineEdit(m_table);
m_table->setCellWidget(i, 0, lineEdit);
}
QPushButton *deleteBut = new QPushButton(QDiaolg);
connect(deleteBut, SIGNAL(clicked()), QDialog, SLOT(editRow()));
}
editRow() {
int row = m_table->currentRow(); // This gives -1
m_table->remove(row);
}
In above scenario I click in the QLineEdit and then click on the button delete. Please help me out with a solution.
Just tried it here, it seems that currentRow of the table returns -1 when clicking the button right after program start, and when first selecting a cell, then selecting the QLineEdit and then clicking the button, the correct row is returned.
I would do the following as a workaround: Save the row number in the QLineEdit, e.g. by using QObject::setProperty:
QLineEdit *lineEdit = new QLineEdit(m_table);
lineEdit->setProperty("row", i);
m_table->setCellWidget(i, 0, lineEdit);
Then, in the editRow handler, retrieve the property by asking the QTableWidget for its focused child:
int row = m_table->currentRow();
if (row == -1) {
if (QWidget* focused = m_table->focusWidget()) {
row = focused->property("row").toInt();
}
}
The accepted solution, as is, would not work if rows might get deleted while the program runs. Thus the approach would require to update all the properties. Can be done, if this is a rare operation.
I got away with an iteration approach:
for(unsigned int i = 0; i < table->rowCount(); ++i)
{
if(table->cellWidget(i, relevantColumn) == QObject::sender())
{
return i;
}
}
return -1;
Quick, dirty, but worked, and in my case more suitable, as rows got deleted often or changed their positions, only buttons in the widget were connected to the slot and the slot was never called directly. If these conditions are not met, further checks might get necessary (if(QObject::sender()) { /* */ }, ...).
Karsten's answer will work correctly only if QLineEdit's property is recalculated each time a row is deleted, which might be a lot of work. And Aconcagua's answer works only if the method is invoked via signal/slot mechanism. In my solution, I just calculate the position of the QlineEdit which has focus (assuming all table items were set with setCellWidget):
int getCurrentRow() {
for (int i=0; i<myTable->rowCount(); i++)
for (int j=0; j<myTable->columnCount(); j++) {
if (myTable->cellWidget(i,j) == myTable->focusWidget()) {
return i;
}
}
return -1;
}
Alright I tried using a QMaemo5ListPickSelector together with a QMaemo5ValueButton, but when I click on the button, a popup dialog box does come up, but it doesnt any list ..
Here is a picture of what I mean:
This is the code I'm using to start up the above mentioned two components and to populate the lists:
QMaemo5ValueButton *x = new QMaemo5ValueButton("Testing .. !");
QStandardItemModel model (10,2);
int j,k;
for(j=0;j<=1;j++)
{
k=0;
for(i=0;i<=9;i++)
{
QStandardItem *item = new QStandardItem(QString("%0").arg(k));
k+=5;
model.setItem(i,j,item);
}
}
x->setValueLayout(QMaemo5ValueButton::ValueBesideText);
QMaemo5ListPickSelector *sel = new QMaemo5ListPickSelector();
sel->setModel(&model);
x->setPickSelector(sel);
hbox->addWidget(x);
I would say I'm probably populating the list incorrectly ..