Map QWidget to variable - c++

The idea was to connect QWidget with a variable so that when text changes on a widget it will be also changed in a variable.
And do this with just one line like this
WidgetMapper::connect(ui->lineEdit, SIGNAL(textChanged(QString)), someClass.var);
which would connect for example QLineEdit with a variable.
1) This would display var in a lineEdit
2) when lineEdit fires an textChanged(QString) signal - WidgetMapper would convert this QString to correct mapped type with stringstream and write it to var.
But i dont really know templates that well, and dont know if it is possible at all.
I dont think it is possible to use one WidgetMapper for every type, so i also tried creating separate instances for each type (WidgetMapper<int> mapper;) which would still be betten then writing setters and onTextChangedSlots for each QLiteEdit but i could not figure out how to make it work as well (converter part still could not figure out the correct type).
WidgetMapper is using QSignalMapper to map signal to QWidget, and it worked fine, the part i have troubles with - is converting QString to template variable.
So is it possible? And if yes how could i do this? Or maybe there already a solution for this problem? (Somehow use QDataWidgetMapper with a class that contains variables maybe?)

First of, connecting the variable would do nothing else than calling some function if it were possigle.
Second try using QSignalMapper, this way you could use a single slot for all widgets, given you keep their pointers in an array with the index being the signal(int) emitted by the SignalMapper. This way your slot can just use MyWidgetArray[i]->text().

Related

Sending JavaScript Object QML signal parameter

I am trying to connect a QML signal to a Qt slot with following parameter types:
in QML side:
signal Sig(var info)
in Qt side:
QObject::connect(topLevel, SIGNAL(Sig(QVariantMap)), &mObj, SLOT(mSlot(QVariantMap)));
Which gives me the following:
QObject::connect: No such signal QQuickWindowQmlImpl_QML_24::Sig(QVariantMap) in ...
So, I assume that types var and QVariantMap does not match. According to this document, QVariantMap types are converted to JavaScript objects. But I am not sure if it also does the other way around.
I have implemented an opposite type of connection(Qt signal with QVariantMap, QML handler with "Connections" element) which worked just fine. I was able to get the signal's argument as a JS object.
By the way, I have also tried the same connection with string argument types in my code, so I don't think that there is another unrelated mistake in my code.
How do I pass JS objects to Qt(C++) side using signal/slot mechanism? I haven't been able to find a solution. Not even an example that matches my case(signal and slot argument types), actually. Which makes me think that I am doing some sort of design mistake.
The parameters are QVariants on C++ side, so you need to do
QObject::connect(topLevel, SIGNAL(Sig(QVariant)), &mObj, SLOT(mSlot(QVariant)));
Note that you also need to change mSlot parameter type, because QVariant can't be implicitly converted to QVariantMap. To get the map in the slot, use QVariant::toMap() method, if it indeed is a map (if it isn't, this method returns empty map, and you need to do some debugging).
It works the other way around, because QVariantMap can be implicitly converted to QVariant.

Is there a way to connect a QSlider and a QLineEdit object to each other?

I'm trying to connect a Slider and LineEdit widget together so that when one is changed the other will match this value.
I'm struggling since lineEdit takes strings and Slider takes ints. I already used setValidator on the lineEdit so that only ints can be entered.
I tried using the old signals and slots syntax with no luck using a couple different methods from a quick Google search.
connect(textbox, SIGNAL(textEdited(QString)),slider,
SLOT((QString)));
Should I be using a different widget entirely than LineEdit?
Use the lineEdit() method of QSpinBox():
connect(textbox, &QLineEdit::textEdited, slider->lineEdit(), &QLineEdit::setText);
I'm using stackoverflow firsty to answer others' question,Hahaha.
The better binding signal for QSlider is QSlider::sliderMoved, and do not bingding QSlider::valueChanged, otherwise they will conflict, maybe you can try it.
Binding QLineEdit::textChanged signal for QLineEdit.
code here:
connect(ui->horizontalSlider,&QSlider::sliderMoved,this,[=]{
int val=ui->horizontalSlider->value();
//You can process the variable val here.....
ui->lineEdit->setText(QString::number(val));
});
connect(ui->lineEdit,&QLineEdit::textChanged,this,[=]{
int val=ui->lineEdit->text().toInt();
//You can process the variable val here.....
ui->horizontalSlider->setValue(val);
});

Referencing QWidget from different class

I'm sorry if this question is duplicate but i am really struggling with finding any answer.
Please take in mind that i am novice in c++ programmming.
My problem is this. I have an GUI made in QtCreator. There are two listeners binding keyReleaseEvent, one on main class (SuperFalcon) , one on QTextEdit ( which is separate and modified class ). I have QFrame which i would like to toggle hide/show on "Ctrl + f" key event. Since that QFrame (object name is findWidget) widget belongs to SuperFalcon->ui, there's no problem, everything works fine, problem starts when i try to make "Ctrl + f" in QTextEdit because it's separate event listener. Basically i tried this.
main class name is "SuperFalcon" so:
in superfalcon.h i've made an public static pointer like this:
public:
static QFrame *fWidget;
then in superfalcon.cpp, i firstly execute
ui->findWidget->hide(); and then
fWidget = ui->findWidget; hoping to get pointer on widget.
Next in my QTextEdit class in keyReleaseEvent function i've tried to get that pointer like SuperFalcon::fWidget->show() but i get undefined reference on it.
So , to make things simpler, i don't know how , if possible, to get reference of QFrame widget which is part of one class (SuperFalcon), from another class (QTextEdit class) in order to execute some commands on QFrame.
If it's not clear enough i can provide some code.
You must have a definition of any static member variable.
This definition has to be in a source file because of the one definition rule.
Simply add the line:
QFrame* SuperFalcon::fWidget;
to "superfalcon.cpp".
You have to initialize your static variable, in superfalcon.cpp:
QFrame* SuperFalcon::fWigdet = nullptr;

Qt signal mapping

I understand that we could use QSignalMapper to collect a set of parameterless signals, and re-emit them with integer, string or widget parameters corresponding to the object that sent the signal.
But could we do the reverse?
For example, is it possible to achieve:
connect(control,startVehicle(0),vehcileList[0],startReceived());
connect(control,startVehicle(1),vehcileList[1],startReceived());
connect(control,startVehicle(2),vehcileList[2],startReceived());
instead of having 3 different signals from control as
startVehicle_1();
startVehicle_2();
startVehicle_3();
There is a simpler way:
connect(control, SIGNAL(startVehicle(int)), this, SLOT(startReceived(i)));
//in startReceived(i) slot
vehcileList[i]->startReceived();

qt/c++ naming of variables dynamically

I am in the process of developing a html editor in Qt for one of my university assignments, and i am having a problem regarding naming of some variables.
the problem is this:
when the user decides to load their "project" the program iterates through the folder and finds how many .html files are in there, it then creates tabs for them to be displayed in.
I have a custom QTextEdit which has a customer completer and syntax highlighting etc. the problem i am having at the moment is how to create them depending on the number needed.
i create a QStringList of file names:
QStringList m_files;
m_files = aDialog.m_loadDirectory->entryList(QStringList("*.html"),QDir::Files|QDir::NoSymLinks);
then i iterate through each one of the list:
for(int i=0; i<m_files.count();i++)
{
}
and for each one i need to create a new custom QtextEdit
TextEdit *name = new TextEdit;
then add to the tab
tabs->addTab(name,"someTitle");
but as each TextEdit needs to be different for each tab (i think this is correct) i need a different Variable name for each one.
i thought about creating a list/array of TextEdit objects but as i dont know how many i need to use, i could end up easily with too many (wasted memory) or not enough..
any ideas on how i can get around this?
one thought..
would it be possible to create a TextEdit object before the loop
then make a copy of that object in the loop and add the copied object to the tab? (still variable naming problem...)
thanks
but as each TextEdit needs to be different for each tab (I think this is correct)
Yes, you need a different TextEdit in each tab.
I need a different Variable name for each one.
No, you don't need a different variable name for each one. You need different objects, but variable names don't have much to do with that.
A simple:
for (...) {
TextEdit *te = new TextEdit(...);
// set up that text edit in whatever way you need
tabs->addWidget(te, "foo");
}
does exactly what you want. The variable name te is completely irrelevant (it won't even appear in the executable outside of debugging symbols). Each time through the loop, you'll be working on a separate TextEdit instance.
If you need to refer to that TextEdit by name at runtime, you can keep all your widgets in a collection, a QMap for instance.
QMap<QString, QWidget*> all_editors;
...
for (...) {
TextEdit *te = ...;
all_editors[filename] = te;
...
}
You have discarded quickly the only viable solution : put your text edits in a collection. The textedit have to be created with new, so the collection itself will not waste space.
You can use a QPair<QTabWidget*, QTextEdit*> for simplest cases. For more complicated cases create a custom widget, and just make a list of those.
Copying a QObject is a really bad idea. I think the copy constructor is private so you will not even be able to do that