PDA

View Full Version : Referencing a Widget with a command



Prodeine
6th March 2019, 07:39
Hello all and thank you for allowing me the pleasure of asking my noob questions! I am learning by myself so it is nice to know there is a community of people working together! Here is my question.


void Edge::on_slotSizeW_textChanged(const QString &arg1)
{
QSettings settings("slots.ini",QSettings::IniFormat);
QString profileName;
QString slotName;

QString objName = ui->slotSizeW->objectName();
QString objValue = ui->slotSizeW->text();


QList<QListWidgetItem*> items = ui->profileSettingsList->selectedItems();
foreach(QListWidgetItem* item, items)
{
profileName.append(item->text());

QList<QListWidgetItem*> items = ui->slotList->selectedItems();
foreach(QListWidgetItem* item, items)
{
slotName.append(item->text());

settings.beginGroup(profileName);
settings.beginGroup(slotName);
settings.setValue(objName,objValue);
settings.endGroup();

qDebug() << objName;
}
}
}

in this example is there a way to automatically reference the widget here:



QString objName = ui->slotSizeW->objectName();
QString objValue = ui->slotSizeW->text();

I want to be able to remove ui->slotSizeW and automatically return whichever widget is in focus. Possible? Thank you again

Lesiok
6th March 2019, 13:53
I do not really understand what you mean but maybe the solution is QObject::sender ?

tuli
6th March 2019, 14:03
Or QApplication::focusWidget() ?

What do you want to do exactly?

Prodeine
6th March 2019, 17:09
I am trying to create a function that will automatically write settings to a .ini based off of activity. The current function will set the profile Name and slot name. I have to manually configure each widget for the objName and objValue. I found a function to do it with some widgets but it doesn't work for all. Sorry I am not home or I would post another code example

d_stranz
6th March 2019, 20:52
I am not at all sure the code you posted is going to do what you think it will.

First off, "profileName" and "slotName" are method-level QString instances. So, every time through the loop that starts in line 12, you will add more text to the end of the "profileName" string. It will just grow and grow until you get to the end of the first QList of items.

Next, "slotName" will also continue to grow, once for every pass through the loop that starts on line 17. But it will continue growing for the next pass though the profile items list, too.

By the end of both loops, profileName will look like "profile1profile2profile3profile4..." and slotName will look like "slot1slot2slot3slot1slot2slot3slot1slot2slot3slot1 slot2slot3...". I am pretty sure that isn't what you want.

Next, in the code that writes the settings, you call beginGroup() twice, but only call endGroup() once. They need to be paired up. If you don't pair them, then you INI file will turn into a cascading set of groups because the profileName groups never get closed.

Next, in every profile name group and every slot name group inside it, you write exactly the same object name and object text pair. If that is really what you want, why bother with the profile name and slot name groups at all? Just write the object name and text to the ini file once, as a top level key / value pair.

And finally, you use the variable names "item" and "items" for the QList in both the inner and outer loops. The variables in the inner loop "hide" the variables in the outer loop. This is legal C++, but really bad practice. It's confusing, because you have to pay very close attention to where you are when reading the code to know whether "items" and "item" refer to something from the "profileSettingsList" or something completely different from the "slotList". Why don't you name them in a way that makes it easy to keep track of? Like "profileItem" and "profileItems", "slotItem" and "slotItems". Then when you (or someone else) comes along later to edit your code you (or they) will be able to read it and not be confused.

To answer your original question, if what you are trying to do is connect the same slot to many different widgets (instead of just sizeW), you can do as Lesiok says, use the QObject::sender() method inside the slot. This method returns a pointer to the QObject that emitted the signal that eventually got routed to the slot. You can then use qobject_cast() if you want to cast the QObject pointer into a pointer to the QWidget type that is connected to the slot.

If these QWidgets are actually QLineEdit, and you are connecting to their QLineEdit::textChanged() signals, then there is no need to retrieve the text using a QLineEdit::text() call. The new text is what is being sent as the QString argument to the slot (the argument you have named "arg1").



void Edge::on_slotSizeW_textChanged(const QString &arg1)
{
QSettings settings("slots.ini",QSettings::IniFormat);

QObject * pSender = sender();

QString objName = pSender->objectName();
QString objValue = arg1;

QLineEdit * pLineEdit = qobject_cast< QLineEdit * >( pSender );
// ALWAYS check that the cast worked... because if you don't and it didn't, BOOM!
if ( pLineEdit != nullptr )
{
// ...
}

// ...
}

Prodeine
6th March 2019, 22:38
And here is my final Answer! Thank you so much for all of your support. I have many more noob questions to come :confused::confused::confused:



void Edge::on_slotHotkey_keySequenceChanged(const QKeySequence &keySequence)
{
QSettings settings("slots.ini",QSettings::IniFormat);


QObject * pSender = sender();

QString objName = pSender->objectName();


QList<QListWidgetItem*> items = ui->profileSettingsList->selectedItems();
foreach(QListWidgetItem* item, items)
{
QString profileName;
profileName.append(item->text());

QList<QListWidgetItem*> items = ui->slotList->selectedItems();
foreach(QListWidgetItem* item, items)
{
QString slotName;
slotName.append(item->text());

settings.beginGroup(profileName);
settings.beginGroup(slotName);
settings.setValue(objName ,keySequence);
settings.endGroup();

qDebug() << objName;
}
}
}



This will be a reusable function for capturing configurations in real time and easily expandable later on to different widgets!

d_stranz
7th March 2019, 16:07
You seem to still be a little confused about QString. There is no need to call QString::append() to assign a value to a QString. The function is used if you want to add more text to the end of a QString that may already contain some text. Just make a simple assignment:



QString profileName = item->text();

QString slotName = item->text();

Prodeine
7th March 2019, 23:23
Thank you for checking on that, I guess it was just dead code from an old version of the function. I will update it when I get home!

anda_skoa
9th March 2019, 09:10
Btw, a slot name like on_slotHotkey_keySequenceChanged() can easily be confused with a "connect by name" slot for an object called "slotHotKey" and a signal called "keySequenceChanged"

If you accidentally rename one of your UI file objects to "slotHotKey" and it has a "keySequenceChanged" signal then it will also get connected to that slot during "setupUi".

Cheers,
_