How to communicate with Qt widget through external command? - c++

I'm working on a tool, on the main window of the tool there are few Qt widgets added on it.
When we used to RMB click on the Qt widget, a context menu pops up (and via eventFilter few functions have been called) to do the required work- say, doTask() slot gets called up with the receiver object.
Now I have to add a banner menu on the window, which has to copy all the features of RMB context menu.
Since this banner menu is not of Qt, but written in some internal functions (say, LISP) I have problems in calling that slot function - doTask(), as I don't know what is the receiver object.
How can I communicate with a Qt widget through some external command/language?
Please add comment if anything is not clear in this.

Can you not expose a simple C style method from a QT aware object that acts as a proxy for the slot calls. ie Your banner calls method, method then calls appropriate slots?

Your basic problem is just knowing the receiver object. Once you do, you can call its slot directly (doesn't need to go through a signal).
The menu knows this, because it keeps a pointer to the receiver object. Your own banner menu must do the same. "It doesn't know the receiver object" must therefore be fixed.

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.

QComboBox Qt Creator signals slots never fire

I have a very simple Qt window that contains combo box, and I try to create signal slots for this combo box with Qt Creator. I tried activated, currentIndexChanged, currentTextChanged, nothing works.
What may be the reason?
Other signals (button click, menu item click) on the same window fire normally. Operating system is Windows 7.
When you create slots in Qt Designer, on a Form, like a QMainWindow Form, if you right click and Go to slot..., it uses naming conventions to automagically connect the ui form elements to slots based on their name.
After you create those slots, you go and change the object name to something else.
Like instead of comboBox1, you change it to myComboBox, it will break the automagically connected ui form elements, because the name is different.
http://doc.qt.io/qt-5/designer-using-a-ui-file.html#automatic-connections
Widgets and Dialogs with Auto-Connect
Although it is easy to implement a custom slot in the dialog and
connect it in the constructor, we could instead use QMetaObject's
auto-connection facilities to connect the OK button's clicked() signal
to a slot in our subclass. uic automatically generates code in the
dialog's setupUi() function to do this, so we only need to declare and
implement a slot with a name that follows a standard convention:
void on_<object name>_<signal name>(<signal parameters>);
That is the most likely reason why your combobox started to not connect.
If it wasn't that you can see the output of every explicit connect call when they fail based on naming:
QObject::connect(ui->comboBox, SIGNAL(misspelled_signal()), this, SLOT(non_existent_slot()));
And you will get very useful output in your Application Output tab at runtime to help diagnosis the errors.
Hope that helpls.

Qt 5 - How to send data back from child dialog in real time

I have a settings dialog that has some settings that require another dialog to fully configure. My window shows a preview of the data as it's being tweaked by these settings. Upon clicking on the configuration button I launch another modal dialog with some knobs to twist to fine tune the particular setting.
I wish to send the result of the twisting of the knobs on the child dialog back to the parent dialog so that it can show the new preview data as the knobs on the child are being played with. The way I imagine it is I have a "refresh preview" function in the parent that is called after modification of it's data preview member variables. The question is, how do I do this? How can I access getters/setters from the parent dialog as a modal child dialog? If I do access them will the preview change or will it be blocked because of the modality of the child?
Thank you!
In Qt world, it is generally encouraged to exploit the Signal/Slot mechanism. In short, classes can send signals when something changes within that class. And slots can receive such signals provided we notified the receiving classes appropriately.
Let us look at how we can do it for our present case.
In our settings dialog constructor, we include this code (assumption is that you display the "another" dialog when a button is pressed):
Dialog *dialog = new Dialog();
connect(dialog->dial(), &QDial::valueChanged, this, &QSettingsDialog::changeTemp);
Code walkthrough:
Our QDialog has been constructed with a QDial object, dial. We access that member pointer with dialog->dial().
We tie the signal that emits the value changed on the dial to the slot called changeTemp that receives the value changed and sets the display widget on the settings dialog (parent) accordingly.
The changeTemp method might be like so:
void QSettingsDialog::changeTemp(int val)
{
lineEdit->setText(QString::number(val));
}
Notes:
You need to declare the Q_OBJECT macro on all classes that need to implement Signals and slot. In this case, both the settings dialog and the child dialog.
The above signal/slot signature is the new Qt5 signature. If you are on a version below 5.0, the signature is different. Refer to the docs.

Qt Designer, missing "go to slot" in context menu?

I've been watching a Qt tutorial series on YouTube, in which the author shows how to call a function, when a button is pressed. He right-clicked on the button in Qt Creator IDE and chose "Go to slot", from where he chose the signal which would fire the generated function. Since I am used to develop with Netbeans, I simply tried to follow his example using the embedded Qt Designer. Unfortunately, there is no "Go to slot..." entry when I right-click on my button or any widget. I could, of course, create a new slot for my main window and then connect the button's signal to it, but doing it with a single function just seems way more convenient and clean to me. Is there a way to fix is, or if not, at least a way to do with via code entirely, without having to add a new slot to the main window for every single button that servers a different purpose? Thanks for your help.
While I don't know why the QtDesigner in Netbeans doesn't provide this feature, I know what the feature does: It just creates a slot with a special name in your widget class. Note that it does not add a connect statement. It uses the automatic connection feature, which works like this:
For each slot which name matches this pattern:
void on_X_Y(...)
it will be connected to the signal named Y of the object named X. So if you have a QPushButton named button, and you want to handle the signal pressed, simply create a slot with the following signature:
void on_button_pressed()
If you wonder how this slot gets connected to the signal: This happens in the ui_...h file at the end of setupUi():
QMetaObject::connectSlotsByName(WidgetName);

Callback for button in Qt Designer?

I just started using QtCreator tonight, and it seems it puts all of the interface stuff inside of the ui file. I followed a tutorial to create a resource for my icons, then I added them to a menu bar at the top.
I need to make a connection when one of them is clicked though, and cannot figure out how to make a callback for it.
Am I going to have to completely create them through code or is there some way to add a callback for them (rather than just making them interact with other objects).
Menu bar items are action objects. To do something when they are clicked, you need to catch the triggered() signal from the action. Read more about signals and slots here.
To do this, you need to declare a new slot in your MainWindow class. Qt also supports doing this automatically, without the need to connect anything, but I prefer doing it myself. If you're not interested, just skip this part.
First, we declare a new slot in your window class:
private slots:
void clickMenuButton();
Then, in your constructor, you need to connect the triggered signal to your new slot:
connect(ui.actionObject, SIGNAL(triggered()), this, SLOT(clickMenuButton()));
The first argument is the object that holds the signal we'll listen to (your menu button). The second is the name of the signal. The third is the object that holds the receiving slot (in this case, our window). The fourth is the slot.
And just like that, clickMenuButton() will be called whenever the action is clicked.
As I said before, Qt can also automatically connect signals to slots. The disadvantage here seems to be that you can't change the slot's name, but you don't need to connect it either.
Qt Creator supports creation of slots for widgets: in the case of your menu action, you should go to the form designer, and you should see a list of actions in your form (if you don't, find the Action Editor). Right click the action you want, and push Go to slot.... There, double click triggered().
Qt Creator will then open the new slot in your code editor, and you can do whatever you want to here!
To do that you'll need to add a QAction, add it to the menu, associate an icon with it and then create a callback for it. I'm using the VS Integration so I don't know the details of how to do it in Creator but it should be possible without creating stuff in code.
There should be somewhere an actions editor. from there you add an action, then right-click it or something to add an icon to it, then drag it do the menu and then possibly double click it to create a slot for it. This is how it works in the VS Integration atleast.