Is it possible to get Qlabel name from Qlabel text? - c++

In our project, We have used Qlabels in different UIs and different classes,
such as :
ui->label->setText(label_ABC);
We want to provide label name change access to the user.
Default name already exists. If the user wants to change label name then first they change label_ABC to label_XYZ. this is saved in a database.
We want to replace lable_ABC to label_XYZ in all UI.
What is the best way to doing this?

A way to do it could be to derive QLabel to a child class (let's call it MyQLabel) which will define a setTextEnhanced() method (you can use a better name of course) which will perform the setText() and emit a signal which sends an identifier of the MyQLabel for example.
If you use this class instead of a pure QLabel and connect the raised signal to a slot that will perform the setText() over the others MyQLabel, the job is done.
This slot will be the one to handle the relation between every GUIs MyQLabel by associating the differents MyQLabel with their identifiers for example.
I hope this can help.

Related

Preferred way to design application arhitecture in Qt

I have application which has MainWindow that is divided in three main parts:
Thing is, all three parts need to communicate between themselves. For example, there is a QListView in left section where you select items, and depending on the selected item options change in the right section.
I have come up with three solutions:
draw everything within the MainWindow which would make MainWindow one big superclass:
This solution solves all problems with communication between widgets because all of them are part of MainWindow::ui but then I get one big (potentially messy) class.
put each section in it's own class and make MainWindow a singleton:
This solution is... well a singleton. And I don't really like singletons. I will have access to MainWindow from everywhere (essentially I am creating a global variable) and I would still have to expose MainWindow::ui (and ::uis of other sections) via getter which would mean that everything will have access to ::uis.
put each section in it's own class and connect everything via signals and slots:
This would probably be the best solution but with this solution I need to create getter for each widget from EachSection::ui (to be able to connect it in MainWindow with it's counterparts), I would need a lot of calls to connect() and I also have a problem if two slots react to same signal but they need to react in specific order.
So what would be the best approach?
The best approach would be to define messaging (protocol) between views, so that views is not tightly coupled (all views isolated and dont know about each other) one instance class (main window) know all three and connects them. Imagine a button line edit and label, when you press button label gets value of line edit, button implementation does not depend on lineedit implementation, lineedit does not depend on label and so on, all three classes can be extended or changed and it doesnot affect two other, so you can focus on one of them at the time.

Connecting multiple UI objects with signals and slots

I have many line edits on the form created in the Qt creator designer panel. I want to connect them with the signal and the slot:
connect(ui->lineEdit_AmperageMaxCode,SIGNAL(textChanged(QString)),
this,SLOT(slot_ConvertCodesInValues(QString)));
Is there a way to not use the connect() for each object, but do it with a loop or some other way?
You can get all QLineEdit children from your widget using findChildren:
QList<QLineEdit*> lineEdits = this->findChildren<QLineEdit*>();
and then connect their signals using a loop.
If you want to do it only for some QLineEdit instances, you can give them a specific name, and use it as a parameter for findChildren (see the documentation).

C++ adding two QSliders together?

I have two QSlider-s/QSpinBox-es. Got those working but not sure about the best way of adding the two together to output the total.
Here is a picture of what I got:
You need to connect signals form the sliders and spinboxes to slots in your main widget (or some other QObject derived class). Doing this allows your main widget to be informed whenever they are changed, do the addition, and output the result where you want. Check out some of the tutorials included with Qt for more info.

When will cellChanged signal be fired in QTableWidget?

I am using a QTableWidget to display and edit a data matrix. For validation purpose, I used the QLineEdit as items in this table. As following,
pTable=new QTableWidget(N,N,this);
pItem=new QLineEdit();
pItem->setText(tr("%1").arg(pInfra->adjacencyM(i,j)));
rx=new QRegExp("0|1");
validatorRegexp=new QRegExpValidator(*rx,0);
pItem->setValidator(validatorRegexp);
pTable->setCellWidget(i,j,pItem);
Since I want to know if data in certain cell has been changed, so I tried cellChanged(int, int) signal, and connect it with my own slot cellEdited(int,int), like this
connect(pTable,SIGNAL(cellChanged(int,int)),this, SLOT(cellEdited(int,int)));
But, when I edit QLineEdit in the cell, I can not catch this signal. When will this signal be fired? Or can I do this using another signal or in some other way?
Thanks!
The problem is that the cellChanged() signal is emittet only if the table model is issued the setData() method, which normally comes from the QLineEdit of the delegate. Since You have your own mechanism by setting the cell widget the setData() method of the model will never be called. Which means you'll have to connect to the textChanged() or the textEdited() signal of the QLineEdit object you put in the cells.
Another valid option is the approach mentioned by beduin in the comment.
Also possible: You could subclass the used delegate and make it create QLineEdit objects with your validator. Which would be the cleanest approach since you don't interfere with the model/view architecture and can rely on the signals the table object is sending.
Best regards
D
Not aware about causes of this problem. Considering another ways. You can catch QLineEdit signal textChanged and use QSignalMapper to bind signal, fired by each QLineEdit to particular cell number. Maybe itsn't the best qway to do that, but you can use it in case this problem won't be solved.

Qt/C++ - confused about caller/callee, object ownership

I am creating a GUI to manipulate a robot arm. The location of the arm can be described by 6 floats (describing the positions of the various arm joints.
The interface consists of a QGraphicsView with a diagram of the arm (which can be clicked to change the arm position - adjusting the 6 floats). The interface also has 6 lineEdit boxes, to also adjust those values separately.
When the graphics view is clicked, and when the line edit boxes are changed, I'd like the line edit boxes / graphics view to stay in synchronisation.
This brings me to confusion about how to store the 6 floats, and trigger events when they're updated. My current idea is this:
The robot arm's location should be represented by a class, RobotArmLocation. Objects of this class then have methods such as obj.ShoulderRotation() and obj.SetShoulderRotation().
The MainWindow has a single instance of RobotArmLocation.
Next is the bit I'm more confused about, how to join everything up. I am thinking:
The MainWindow has a ArmLocationChanged slot. This is signalled whenever the location object is changed.
The diagram class will have a SetRobotArmLocation(RobotArmLocation &loc). When the diagram is changed, it's free to change the location object, and fire a signal to the ArmLocationChanged slot.
Likewise, changing any of the text boxes will fire a signal to that ArmLocationChanged slot. The slot then has code to synchronise all the elements.
This kind of seems like a mess to me, does anyone have any other suggestions? I've also thought of the following, does it have any merrit?
The RobotArmLocation class has a ValueChanged slot, the diagram and textboxes can use that directly, and bypass the MainWindow directly (seems cleaner?)
thanks for any wisdom!
Except for really simple cases (e.g. a label that shows the value of a slider) my experience has been to stay away from inter-component signal/slot connections inside Qt Designer. Rather, have the component firing the signal of interest connect to a slog defined in the top level QWidget class you're subclassing (i.e. QMainWidow, etc... let's just call it the Form class). You can also go the other way: if you have a custom signal in the Form class, you can connect it with Qt Designer to one of the public widget slots.
To be specific using your example:
I'm going to assume that you have subclassed QMainWindow and QGraphicsView. Let's call the subclasses RobotMainWindow and RobotView.
RobotMainWindow contains the QLineEdit fields and RobotView. The way you specify RobotView in Qt Designer is to insert a QWidget and use the Promote to... feature to tell Qt that the QWidget should be replaced at compile time with your custom RobotView.
Name the QLineEdit fields edit1, edit2...edit6.
In the Qt Designer signal/slot editor define slots in RobotMainWindow to be called when the value in a QLineEdit changes. There are some more elegant ways of doing this, but for simplicity let's say you define 6 slots named setValue1(float), setValue2(float), etc.
In the source code for RobotMainWindow, go declare and define these slots, such that they update your arm, shoulder, whatever.
Also in the source code, define a signal valueChanged() (or multiple for each field, your choice). Have the slots you defined emit valueChanged().
Back in Qt Designer you can now link the appropriate signal from each QLineEdit to the corresponding slot in RobotMainWindow.
Back in the signal/slot editor add the valueChanged() signal to the RobotMainWindow (so Qt Designer knows about it). Connect this signal to a new slot in RobotView, using the procedure above, so it can update the rendering.
Repeat all of this for handling changes from RobotView to the editing fields (via RobotMainWindow.
In short, I think you'll find everything more straight-forward if your route the signals through your Form subclass (which I think of as the Controller in MVC parlance).