How to get state of all checkbox and get row and column of checked?
Onclick PushButton function.
QTableWidget *t = ui->tableWidget;
t->setRowCount(2);
t->setColumnCount(2);
QStringList tableHeader;
tableHeader<<"item01"<<"item02";
t->setHorizontalHeaderLabels(tableHeader);
for (int i = 0; i < t->rowCount(); i++) {
for (int j = 0; j < t->columnCount(); j++) {
QWidget *pWidget = new QWidget();
QHBoxLayout *pLayout = new QHBoxLayout(pWidget);
QCheckBox *pCheckBox = new QCheckBox();
pLayout->setAlignment(Qt::AlignCenter);
pLayout->setContentsMargins(0,0,0,0);
pLayout->addWidget(pCheckBox);
pWidget->setLayout(pLayout);
t->setCellWidget(i, j, pWidget);
}
}
And when I clicked the button, I need get all selected elements with rows, columns of each.
void Widget::on_pushButton_clicked()
{
// Code here
// For example: Selected ["item01", 2]
}
I simply iterate over all cell widgets:
for (int i = 0; i < t->rowCount(); i++) {
for (int j = 0; j < t->columnCount(); j++) {
QWidget *pWidget = t->cellWidget(i, j);
QCheckBox *checkbox = pWidget->findChild<QCheckBox *>();
if (checkbox && checkbox->isChecked())
qDebug() << t->horizontalHeaderItem(j)->text() << i;
}
}
It's been awhile since I've programmed with Qt, but I believe there is not really good way of doing this. I've done all of these solutions with success.
1) Iterate through all the cell widgets like svlasov's answer says. This has some scalability issues.
2) Create hash maps where the pointer to the button is the key and the indices you want are the values. You can get which button was clicked with QObject::sender().
3) Store the indices you want as properties on the button when you create the buttons (see setProperty() in QObject's documentation). For example,
button->setProperty("x index", x);
In your slot, use QObject::sender() to get the pointer to the button and then call
button->property("x");
I've generally found the third option to be the cleanest and best performing.
Note that these answers also work for QTreeWidgets and QListWidgets.
Related
im trying to change the font size of a QTextEdit by using a QComboBox which is filled in with different values, so for example when I choose a value in the QComboBox it will change the QTextEdits size to the value I have selected. I have values in the QComboBox but I don't know how to change the QTextEdit's value to the value I have selected.
Below is the code I used to fill the QComboBox with values:
for (int i = 0; i < 102; i+=2){
QStringList list = (QStringList()<<QString::number(i));
ui->combobox->addItem(list);
Any help on what to do from here would be appreciated thank you!
QTextEdit* textEdit = new QTextEdit(......);
QComboBox* fontSizeCombo = new QComboBox(....);
for (int i = 1; i < 102; i += 2) {
fontSizeCombo->addItem(QString::number(i));
}
connect(fontSizeCombo, SIGNAL(currentIndexChanged(QString), SLOT(changeFontSize(QString));
void MyClass::changeFontSize(const QString& selected)
{
textEdit->setFontPointSize(selected.toInt());
}
Don't need appending QStringList with each item.
Don't set font size to 0. Excerpt from the Qt docs:
Note that if s is zero or negative, the behavior of this function is
not defined.
Hi my question is simple, I just asked in the QT Forums but nobody answer to me.
I just wanted to make a 2D array of a QLabel, can somebody help me, All I read about it, they use a dynamic vector, something like this:
<QVector <Data_Type>>
I can't use that (My project don't have to use that yet, crap specifications I know), so I have to use a 2D like in C++ or C.
EDIT: I have the 2D Array but dont know how to show it, All I have is this, and don't give me errors:
QWidget *mainWidget = new QWidget;
QLabel **maze;
maze= new QLabel*[x];
for (int i = 0; i < x; i++) {
maze[i]= new QLabel[y];
}
for(int i=0;i<x;i++){
for(int j=0;j<y;j++){
maze[i][j].setPixmap(test);
maze[i][j].move(i*60,j*60);
}
}
mainWidget->show();
setCentralWidget(mainWidget);
Now I just want to show the images, once I run the project, no images appear, is the Widget thing right? How to show in the Main Window? I need a 2D Widget too?
Thanks for your time.
Assuming that the x and y are number of rows and columns, correspondingly, you can simply do this trick:
[..]
QGridLayout *grid = new QGridLayout;
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
QLabel *label = new QLabel(this);
label->setPixmap("Path_Of_The_Image");
grid.addWidget(label, i, j);
}
}
[..]
I am making a 2-dimensional grid (2-d Cellular Automaton). So I made full code for console. But now I need to implement that with GUI. I am using linux, so I read out that QT Creator will be the best choice.
Can somebody give me a small tip. How is better to start. Which Views/widjets you recommend to use for that? Any help would be useful.
In c++ code I made a 2-dimensional char array of size 15/15 elements which have elements of type '1' or '0'.
I will be very grateful for any help! Thank you in advance.
One of ways: create a QImage and fill it with your data using setPixel. Convert it to QPixmap and use QLabel to display it.
Below is the two simple examples of how to show arrays on GUI. There are possible other variations too, of course, depending on your needs.
Widget with a grid layout
QWidget *mainWidget = new QWidget;
QGridLayout *layout = new QGridLayout;
for (int r = 0; r < 15; r++) {
for (int c = 0; c < 15; c++) {
QLabel *label = new QLabel("1", mainWidget); // Text could be 1 or 0.
layout->addWidget(label, r, c);
}
}
mainWidget->setLayout(layout);
mainWidget->show();
Using table view
QTableWidget *table = new QTableWidget(15, 15);
for (int r = 0; r < 15; r++) {
for (int c = 0; c < 15; c++) {
QTableWidgetItem *item = new QTableWidgetItem("1"); // Text could be 1 or 0.
table->setItem(r, c, item);
}
}
table->show();
I need to add a widget (QTableWidget) into QFileDialog's layout. I know that it is QGridLayout with sizes (3,4). The table must be in 3-rd row and span all columns.
QTableWidget* tableWidget = new QTableWidget(this);
QGridLayout *layout = static_cast<QGridLayout*>(QFileDialog::layout());
layout->addWidget(tableWidget, 2, 0, 1, 4);
With this code the original 3-rd row which contains lineEdit and save/open pushButton disappears. How can I add widgets between already existing widgets of QGridLayout so that original widgets remain in the layout.
I strongly recommend you not to rely on QFileDialog's implementation. The layout can be different on different platforms or different versions of Qt. It may be more correct to place your table under the dialog or to the right of it. This can be done easily without altering the layout of the QFileDialog itself. Just create a QVBoxLayout and put QFileDialog and QTableWidget inside it.
However, the question has been asked, and the solution exists. QGridLayout has no functionality such as QBoxLayout::insertItem. So we need to implement this behavior manually. The plan is:
Obtain the list of layout items placed in 3rd and 4th rows.
Calculate new positions of items.
Take elements out of item and add them back at new positions.
Working code:
QFileDialog* f = new QFileDialog();
f->setOption(QFileDialog::DontUseNativeDialog, true); //we need qt layout
QGridLayout *layout = static_cast<QGridLayout*>(f->layout());
QList< QPair<QLayoutItem*, QList<int> > > moved_items;
f->show();
for(int i = 0; i < layout->count(); i++) {
int row, column, rowSpan, columnSpan;
layout->getItemPosition(i, &row, &column, &rowSpan, &columnSpan);
if (row >= 2) {
QList<int> list;
list << (row + 1) << column << rowSpan << columnSpan;
moved_items << qMakePair(layout->takeAt(i), list);
i--; // takeAt has shifted the rest items
}
}
for(int i = 0; i < moved_items.count(); i++) {
layout->addItem(moved_items[i].first,
moved_items[i].second[0],
moved_items[i].second[1],
moved_items[i].second[2],
moved_items[i].second[3]);
}
QTableWidget* tableWidget = new QTableWidget();
layout->addWidget(tableWidget, 2, 0, 1, 4);
I'm beginning in C++ and Qt. I have a matrix of QPushButtons and I want to handle the click event for them. Problem is I'm not being able to tell the slot the coordinates os the button in the array so that I can play with them. I've succeed in passing a integer to my slot, but not both coordinates. I'm not sure if I'm making myself clear enough... That's my problematic code:
for (int i = 0; i < mapSize_x; i++) {
for (int j = 0; j < mapSize_y; j++) {
buttonsArray[i][j] = new QPushButton();
ui->mainLayout->addWidget(buttonsArray[i][j], i, j);
connect(buttonsArray[i][j], SIGNAL(clicked()),
signalMapper, SLOT(map()));
signalMapper->setMapping(buttonsArray[i][j], i, j); // here
}
}
connect(signalMapper, SIGNAL(mapped(int, int)),
this, SLOT(buttonClick(int, int)));
setMapping only accepts two parameters, and I want to pass three. Is there a workaround? I've googled a lot and still can't find an answer. I've also tried to pass the QPushButton object instead of the coordinates, but unsuccessfully as well. Thanks in advance.
Consider using a QHash to store your pushbuttons, keyed by the buttons themselves and pointing to a pair containing their row and column. You should then be able to set your mapping based on the widget pointer and then look up the associated row and column when the signal mapper emits its signal. For example, declare a class data member as follows:
QHash<QPushButton*, QPair<int, int> > buttonHash;
Then your code above could become
for (int i = 0; i < mapSize_x; i++) {
for (int j = 0; j < mapSize_y; j++) {
QPair<int, int> gridPair(i, j);
QPushButton* button = new QPushButton();
buttonHash.insert(button, gridPair);
ui->mainLayout->addWidget(button, i, j);
connect(button, SIGNAL(clicked()),
signalMapper, SLOT(map()));
signalMapper->setMapping(button, qobject_cast<QWidget*>(button));
}
}
connect(signalMapper, SIGNAL(mapped(QWidget*)),
this, SLOT(buttonClick(QWidget*)));
Finally, your buttonClick slot would become the following:
void SomeClass::buttonClick(QWidget* widget) {
QPair<int, int> pair = buttonHash.value(qobject_cast<QPushButton*>(widget));
int myRow = pair.first;
int myColumn = pair.second;
...
}
There are also at least 2 other ways of tackling this problem:
You could try to combine the row and column into a string and use QSignalMapper::setMapping(QObject*, const QString&). This would then require some logic to pull the row and column out of the string in the buttonClick slot.
You could try to combine the row and column into a single integer by using bit shifting and a bitwise OR. You could then rely on QSignalMapper::setMapping(QObject*, int). This would require some logic to pull the row and column out of the integer in the buttonClick slot.
I won't go into detail about these other solutions because they're somewhat ugly. The solution I provided above remains the most intuitive.
The QSignalMapper class can be very useful in certain circumstances, but it may be overkill for your current use-case.
Instead, consider using a QButtonGroup, which was designed for exactly what you're trying to do, and provides a much cleaner and simpler API.