I have created a set of QlineEdits successfully and assigned each LineEdit an Object name but unfortunately when I try to read and get them into a QStringList I get an error stating:
"Textbox was not declared in this scope"
my code is as follows:
for(int i=0;i<5;i++){
f1 = new QFrame();
f2 = new QFrame();
f3 = new QFrame();
a= new QLabel(f1);
b=new QLineEdit(f2);
c=new QLineEdit(f3);
QString oName= QString::number(i);
b->setObjectName("Textbox"+oName);
ui->verticalLayout->addWidget(f1);
ui->verticalLayout_2->addWidget(f2);
ui->verticalLayout_3->addWidget(f3);
a->setText(newList[i]);
}
and from the button click event I won't to get each text in the dynamically created QLineEdits!
void NewOrders::on_pushButton_2_clicked()
{
for(int i=0;i<getList.size();i++){
QString oName= QString::number(i);
getList<<(ui->("Textbox"+oName)->text());
}
}
Here getlist and newlist are QStirngLists are already defined as public!
How can I correct this?
To get the object through the objectName you must use the findChild
void NewOrders::on_pushButton_2_clicked()
{
for(int i=0;i<5;i++){
QLineEdit *le = findChild<QLineEdit*>(QString("Textbox%1").arg(i));
if(le){
getList<<le->text();
}
}
}
Related
In my programm, I fill my interface with a lot of checkbox by this way :
void VGCCC::addMaterialToUI(QDomNodeList _materialNodeList, QWidget* _areaWidget, QLayout* _layout, QWidget* _layoutWidget, int _maTable)
{
for(int i=0; i< _materialNodeList.count();i++)
{
QDomElement materialElement = _materialNodeList.at(i).toElement();
QString elementFile = materialElement.attribute("file");
QString elementId = materialElement.attribute("id");
QString elementLabel = elementId;
elementLabel += " - ";
elementLabel += materialElement.attribute("label");
QCheckBox* checkbox = new QCheckBox(elementLabel);
_layout->addWidget(checkbox);
_layoutWidget->adjustSize();
_areaWidget->setMinimumHeight(_layoutWidget->height());
_areaWidget->setMinimumWidth(_layoutWidget->width());
configuration c;
c.path = (m_igmPath+elementFile).toStdString();
c.id = elementId.toInt();
c.name = elementLabel.toStdString();
if(_maTable==0)
{
m_materialSectionMap[checkbox] = c;
}
else
{
m_materialPostMap[checkbox] = c;
}
}
}
I would like to know how to retrieve these "abstract" checkbox. More exactly, if one of these checkbox is checked, I would like to call another function like this :
connect(anyCheckbox,SIGNAL(stateChanged(anyCheckbox)), this, SLOT(doSomethingFunctionIfCheckboxIsChecked()));
The difficulty is that in my UI, these checkbox didn't exist, so I can't connect them to my function. How can I solve it ?
You can e.g. collect pointers to your checkbox objects to a list so can access or "retrieve" them later.
You can connect each checkbox's stateChanged signal to a same slot which is then called when state of any of the checkboxes is changed. In the slot you can cast the sender() to a checkbox if you need to know which specific checkbox is in question. Another alternative is to use QSignalMapper.
In your class declaration:
private slots:
void checkboxStateChanged(int state)
private:
QList<QCheckBox*> m_checkboxes;
In your class definition:
void VGCCC::addMaterialToUI(QDomNodeList _materialNodeList, QWidget* _areaWidget, QLayout* _layout, QWidget* _layoutWidget, int _maTable)
{
...
QCheckBox* checkbox = new QCheckBox(elementLabel);
m_checkboxes.append(checkbox);
connect(checkbox, SIGNAL(stateChanged(int)), this, SLOT(checkboxStateChanged(int)));
...
}
void VGCCC::checkboxStateChanged(int state)
{
// Here your can e.g. call doSomethingFunctionIfCheckboxIsChecked()
QCheckBox* checkbox = qobject_cast<QCheckBox*>(sender());
if (checkbox)
{
// checkbox points to the object whose state changed
}
}
I'm creating a new instance of QTableWidgetItem for each row the user may add, and adding it to a QVector of QTableWidgetItems.
I'd like to do soemthing like the following to name each instance in the following iteration with the row number included in the instance name:
QVector<QCheckBox> *checkBox_array;
for(int r=0;r<user_input;r++)
{
ui->tableWidget->insertRow(r);
*checkBox%1.arg(r) = new QCheckBox; //create an instance "checkBox1" here
checkBox_array->pushBack(checkBox%1.arg(r))
}
or something like the following, which does not compile in its current state:
for(int r=0;r<7;r++)
{
ui->tableWidget->insertRow(r);
checkBox_array->push_back();
checkBox_array[r] = new QCheckBox;
ui->tableWidget->setCellWidget(r,2,checkBox_array[r]);
}
is this possible? How can I work around this issue? All I need is to get the new widgets into the array without having to name them explicitly. Thanks in advance!
Thanks in advance.
Try something like this:
for(int r=0;r<7;r++)
{
ui->tableWidget->insertRow(r);
ui->tableWidget->setCellWidget(r,2,new QCheckBox(QString("checkBox%1").arg(r)));
}
It creates some widgets.
When you want change something in this widget or get data then use cellWidget() method, but don't forget cast it! For example:
for(int r=0;r<7;r++)
{
QCheckBox* curBox = qobject_cast<QCheckBox*>(ui->tableWidget->cellWidget(r,2));
if(curBox)
{
qDebug() << curBox->text() << curBox->isChecked();
curBox->setText("This is new Text");
}
else
qDebug() << "fail";
}
I generate checkboxes as follows:
foreach(QString filt, types){
QCheckBox *checkbox = new QCheckBox(filt, this);
checkbox->setChecked(true);
vbox->addWidget(checkbox);
}
I need to get access to these checkboxes by name but they are all called the same?
I need to read the text they display.
How can I go about this?
Is it possible to run a for loop and attach the value of i onto the end of the checkbox. So in effect, the checkbox would be called checkbox[0], checkbox [1], etc?
EDIT:
I've changed the code to the following:
for(int i=0; i<types.count(); ++i)
{
QString filt = types[i];
*checkboxCount = *checkboxCount + 1;
QCheckBox *typecheckbox[i] = new QCheckBox(filt, this);
typecheckbox[i]->setChecked(true);
vbox->addWidget(typecheckbox[i]);
}
I thought this was a way to dynamically name the checkboxes so I can loop through them to get the text value from them.
I'm getting the error 'variable-sized object may not be initialized' on this line QCheckBox *typecheckbox[i] = new QCheckBox(filt, this);
Any ideas to a solution/ alternate approach?
If you want to access the checkboxes later, you can just use the find children method as follows:
QStringList myStringList;
QList<QCheckBox *> list = vbox->findChildren<QCheckBox *>();
foreach (QCheckBox *checkBox, list) {
if (checkBox->isChecked())
myStringList.append(checkBox->text());
}
In my menu, I am setting data to the menu actions. How can I extract that data in my slot? Or even better, instead of connecting a slot, can I also connect a member function that is able to extract the action data (like in the 1st connect)? The action data is meant to identify each action. As a sidenode, I am not sure if I can use several menu action entries on only one openNote-action.
void Traymenu::createMainContextMenu() {
QAction *actionNewNote = m_mainContextMenu.addAction("Neue Notiz");
actionNewNote->setIcon(QIcon("C:\\new.ico"));
actionNewNote->setIconVisibleInMenu(true);
QObject::connect(actionNewNote,&QAction::triggered,this,&Traymenu::newNote);
QString menuEntryName;
QAction *openNote;
QVariant noteID;
for (int i = 0; i<m_noteList.count(); i++) {
std::string noteTitle = m_noteList[i].data()->getTitle();
menuEntryName = QString::fromStdString(noteTitle);
openNote = m_mainContextMenu.addAction(menuEntryName);
connect(openNote,SIGNAL(triggered()),this,SLOT(s_showNote()));
noteID.setValue(m_noteList[i].data()->getID());
openNote->setData(noteID);
}
m_mainIcon.setContextMenu(&m_mainContextMenu);
}
And the slot:
void Traymenu::s_showNote() {
QObject* obj = sender();
//int noteID = data.toInt();
//Search all notes in noteList for that ID and show it
}
Using QObject::sender()
You can use QObject::sender() to get the signal's sender, followed by qobject_cast to cast the sender pointer to the right type.
void Traymenu::s_showNote()
{
QAction* act = qobject_cast<QAction *>(sender());
if (act != 0)
{
QVariant data = act->data();
int noteID = data.toInt();
showNote(noteID); // isolate showNote logic from "get my ID" stuff
}
}
void Traymenu::showNote(int noteID)
{
// Do the real work here, now that you have the ID ...
}
As the Qt documentation warns, "This function violates the object-oriented principle of modularity." It's still a fairly safe and standard practice, though — just one with some shortcomings. In particular, note that you're committing to having a s_showNote method that only works when it's accessed as a slot (otherwise sender is 0).
Using QSignalMapper
Alternatively, you can use the QSignalMapper class to return a pointer to teh item or to associate a unique identifier (int or QString) with each item.
Something like this:
void Traymenu::createMainContextMenu()
{
signalMapper = new QSignalMapper(this); // (or initialize elsewhere)
// ... (create your newNote here same as before) ...
QString menuEntryName;
QAction *openNote;
int noteID;
for (int i = 0; i<m_noteList.count(); i++) {
std::string noteTitle = m_noteList[i].data()->getTitle();
menuEntryName = QString::fromStdString(noteTitle);
openNote = m_mainContextMenu.addAction(menuEntryName);
noteID = m_noteList[i].data()->getID();
openNote->setData(QVariant(noteID)); // (if you still need data in the QActions)
signalMapper->setMapping(openNote, noteID);
}
connect(signalMapper, SIGNAL(mapped(int)),
this, SLOT(showNote(int)));
m_mainIcon.setContextMenu(&m_mainContextMenu);
}
void Traymenu::showNote(int noteID) {
// Now you have the ID ...
}
This pattern has the benefit of isolating all the ugly "Wait, how do I get my identifier?" stuff in one spot, instead of having both the initialization code and the slot function having code for associating actions and IDs.
I would write it like:
void Traymenu::s_showNote() {
QObject* obj = sender();
QAction *action = qobject_cast<QAction *>(obj);
int id = action->data().toInt();
for (int i = 0; i < m_noteList.count(); i++) {
if (m_noteList[i].data()->getID() == id) {
[..]
}
}
}
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 ..