Toggle dynamically created objects using dynamically created QRadioButtons - c++

I'm working on a QT application. In it the user can create several objects, each one will be added to a list. In the next step the user shall position the objects. The choice which one of the objects shall be positioned, shall be made by clicking QRadioButtons (seems logical as QRadioButtons added to a QGroupbox ensure that only one of them is active).
The problem is I can't find a signal that allows me tell which radio button is active or was clicked. I already connected all radio buttons to one slot, but all I get is a boolean value. How can I get the sender of the signal? Or what would be the standard way to achieve my goal?

QObject::sender is a bit too abstract. Try QButtonGroup::buttonClicked

You can get the sender of the signal using... QObject::sender() method within your slot!

Related

C++ application: Passing a value from a form to the main window private variable

I am developing an application to feed a database. My main window is basically a menu that opens forms for different utilities.
Not sure if it's the best practice but let me explain what I'm trying to do:
my class mainwindow has a private QString that will store the current project name. In the menu, "Load" opens the form (another class) that lists all the existing projects in a combobox. The user chooses the project he wants and clicks OK.
I would like to return the combobox.currentText() into the dedicated private variable. After some research I still cannot figure out how to make it, wether I should use SIGNAL from the form to trigger a SLOT of the mainform or if there is a simple way to just return a value after pressing OK (such as an input dialog). If i am not clear enough, maybe the following sketch could help.
I definitively have a lack of knowledge on the subject but would be grateful for some help.
Indeed if your form for loading a project would emit a signal currentProjectChanged as soon as the user accepts the form (presses the OK button), this signal could be connected to a slot of the main window. For simple things this may be fine and elegant.
On the other hand reacting on actions sometimes needs more logic. If your action triggers a slot that cares for action execution, this slot probably should implement the logic. It should open the form and check whether the user has accepted the project change (pressed OK). In this case the action execution slot could get the new project name from the form and call a main window method to pass the new project name.

How to structure signals/slots?

I am creating a UI with Qt and there are two elements which may or may not be present. Additionally, their parents are different elements as well. However, one affects the other.
How should I structure the signals/slots (or should I not even use that pattern) in the best way?
The methods that come to mind all seem like hacks:
create a signal/slot in all parents and pass up and then back down the signal
create a signal/slot in the closest common parent of both then have the children connect their signals/slots to the parents'
on creation of one navigate the structure of the other to get the element and then connect signals/slots directly. Any guidance here is greatly appreciated.
Edit: "present" means that there is a button that the user may press that creates an element and adds it to the layout. So depending on the combination of button presses, an element may be present or not.
"affect" means it changes its state. for example, there is a list of items and a button elsewhere which adds an element to the list.
For an example, imagine a tabbed pane which contains a todo list. There is a button not in the tabbed pane which adds an item to the list. The tabbed pane does NOT create all the elements of the pane. It creates only the elements of the visible pane and deletes them when the pane is switched away. Therefore, the list may or may not exist.
The UI elements are QWidgets. All QWidgets are QObjects. Any QObject's signals can be connect()ed to any other object's slots. The hierarchy of parent/child relationships is entirely immaterial.
You seem to be confusing signal-slot connections with events, which can be in fact passed up the object hierarchy if they remain ignored by given object.
It's also worth noting that signal-slot connections are safe in spite of QObjects being destroyed. When an object with connected signals or slots gets destroyed, the connections are safely torn down. The only thing you can't do is deleting the sender nor receiver object within a slot - use object->deleteLater() instead.

Is it possible to get information on the control on which an event was issued in Qt?

I am trying to create one event handler for button clicks and connect that to multiple buttons (creating a simple calculator where pressing each number adds its text to the lineEdit).
In C# we would use the sender object which was passed as a parameter and then cast it back to Button and get its Text or other needed property and go on.
I am new to Qt, Do we have such a thing or a similar approach in Qt? Since I couldn't get it out of the signal/slot method of Qt.
On the QObject / QWidget that receives the signal, call this->sender() (QObject::sender()), and cast it with dynamic_cast<MyWidgetType*>(...)
You can find some good examples here for linking back to the issuer of an event.
http://doc.qt.digia.com/qq/qq10-signalmapper.html
They give you different examples for
The sender() Approach (like Jamin Grey's approach below)
The Subclass Approach
The Signal Mapper Approach

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).

Qt-GUI with several "pages", how to synchronize the size of several QWidgets

I am currently writing a wizard-style application using Qt4. I am not using the wizard class however, since going next/back does not make sense from every step in the process.
The user starts off at a "hub"-window with five buttons, each of which take him to another window at a different stage of the process. At the beginning all but the first button of the hub are disabled. After clearing each stage, the user will be directed back to the hub and one new button/stage will get enabled.
Since every stage has significantly differing objectives, I coded every single stage as a single QWidget that gets instantiated in the main() function. To switch between the widgets, I simply hide() the one I am leaving and show() the one I am going to.
However, this leads to problems if the user resized or moved one widget, since the next widget will always show up at its default position instead of the new one.
Is there a way to synchronize the widgets' sizes and positions?
Or, better yet, is there a more elegant way to deal with those different windows than switching between several hidden widgets?
Thank you in advance!
Create one top-level widget that holds the others.
I suggest that you either use QStackedWidget, or, if you want more control, create your own widget and use QStackedLayout directly.
Why not just have one main QWidget as a container for your pages? That way if the user moves the main QWidget and then goes to the next page, it will still open in the new position inside the main widget.
Generally, I've never had occasion to create multiple widgets inside my main method. Don't quite see the point.
I'm beginning on something similar - with different views (perspectives) for different tasks along the way. Using toolbar icons and file menu, not buttons, to move between views. Similar to how MS Outlook allows you to have the window display email, or a calendar, or contacts, etc.
My intent (haven't started yet) is to have one QMainWindow as the application window, containing my various QWidgets that offer the various views. Depending on what task the user is doing, one composite widget will be visible, and the others hidden.