Loading QStringList value received from signal slot - c++

In my qt c++ application a QStringList is sent from one cpp file(MainWIndow) to another cpp file(Dialog) via signal and slots mechanism! I want to display the elements in the qtringList on a combo box in the Dialog.ui when the interface gets loaded(no button click)!
following is my code
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
for(int i=0;i<subMessages.size();i++){
ui->comboBox->addItem(subMessages[i]);
}
}
//slot which is used to get the qstringList
void Dialog::receiveSubMessages(QStringList List){
subMessages=List;
}
The QStringList is received successfully through the slot(already verified).Though I used a for loop and tried display (as in the code) nothing was displayed on the combo box! How can I fix this issue?

In order to get a working code you need to place your for llop inside you slot:
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
}
//slot which is used to get the qstringList
void Dialog::receiveSubMessages(QStringList List){
ui->comboBox->addItems (List);
}
If you want to fill the comboBox with the contents of some QStringList upon Dialog construction then you should either pass this list as constructor argument:
Dialog::Dialog(QStringList List, QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
ui->comboBox->addItems (List);
}
or call Dialog::receiveSubMessages() right after Dialog object construction:
// somewhere in code, where you construct Dialog object
// ...
auto parent = SomeQWidgetDerivedClass (...);
QStringList someStringList {
"string 1",
"string 2"
};
// ...
auto dialog {new Dialog ()};
dialog->receiveSubMessages (someStringList);
// ...
The code that you have provided will never allow you to achieve the desired result because your for loop that is supposed to fill the QComboBox is executed on your Dialog object creation. At that point your subMessages is empty. The slot that you have created is not called before the constructor - the slot is just a member function that can only be called after the object is created. You can only call a member function without an object if the function itself is static, in which case it is definitely not a slot.

I did this answer rather to show you how to solve your problem. (I've the feeling that I even didn't understand what your actual problem is.)
When asking a question the chances to get a helpful answer increase if an MCVE is provided. (Please, follow this link. It teachs you really basic skills every S/W developer shouldmust have. I would also recommend to follow-up to How to debug small programs.)
As I did understand your problem I made such an MCVE. This is the code testQComboBox:
#include <QtWidgets>
int main(int argc, char **argv)
{
// build appl.
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
// a QStringList with items
QStringList items;
items
<< QString::fromUtf8("first item")
<< QString::fromUtf8("second item")
<< QString::fromUtf8("third item");
// build GUI
QDialog dlg;
QVBoxLayout vBox;
QComboBox cmbBox;
cmbBox.addItems(items);
vBox.addWidget(&cmbBox);
dlg.setLayout(&vBox);
dlg.show();
app.exec();
// done
return 0;
}
I compiled it in VS2013 with Qt 5.9.2 on Windows 10 (64 bit). This is how it looks:
As you see, the usage of combobox is rather easy – no secret trap doors to use it. The actual code which is directly related to QComboBox is exactly 4 lines of code:
QVBoxLayout vBox;
QComboBox cmbBox;
cmbBox.addItems(items);
vBox.addWidget(&cmbBox);
And there is exactly one line of code where items are added to the QComboBox:
cmbBox.addItems(items);
Note:
I used QComboBox::addItems() instead of QComboBox::addItem() as the former has already a loop built-in to add a complete QStringList. It doesn't make any difference to the loop you used in your code Dialog::Dialog().
So, finally I dare to do the following statement:
If your combobox doesn't show items then:
You added items from an empty list.
Or, you forgot to add the items from list.
Or, something very weird happend.
I would always bet for 1. or 2. reason – the 3. reason is for real emergency cases only (e.g. broken Qt installation).
Concerning 3. reason:
I saw many questions where some lines of innocent looking code were presented which looked exactly as they should but were claimed to fail. And finally almost everytimes it showed that these lines worked fine when isolated in an MCVE but they didn't in the original code. How can this happen? Either there is some context which changes the behavior of the code in your original program or there is UB – undefined behavior. Something else does bad things but instead of crashing your process immediately (which would mean you're lucky) it goes on for a while corrupting the data more and more until finally everything breaks completely. Looking into the core-dump doesn't help at all. Therefore my recommendation of How to debug small programs.

Related

MsgBox event loop and .show()

I currently have a problem where my QMessageBox has to be closed twice before it finally goes away. I was wondering if the local event loop QMessageBox::exec() is being triggered twice by the QApplication::exec() but I am not sure if that's right assumption to make. I then decided to switch the QMessageBox::exec() to .show() and the QMessageBox instantly disappears, not sure why I either. An explanation and a solution would be great.
#include "texteditor.h"
#include "./ui_texteditor.h"
TextEditor::TextEditor(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::TextEditor)
, m_texteditor(new QTextEdit(this))
{
ui->setupUi(this);
connect(ui->actionAbout, &QAction::triggered, this, &TextEditor::on_actionAbout_triggered);
connect(ui->actionExit, &QAction::triggered, [](){ QApplication::quit();});
}
TextEditor::~TextEditor()
{
delete ui;
}
void TextEditor::on_actionAbout_triggered()
{
const QString projectName = QString("Project Name: %1").arg(PROJECT_NAME);
const QString version = QString("Version: %1").arg(TextEditor_VERSION);
QMessageBox msgBox(this);
msgBox.setText(projectName);
msgBox.setInformativeText(version);
msgBox.exec();
msgBox.show();
}
As is turned out during the discussion in the comments:
Either on_actionAbout_triggered should be renamed, possibly into something not matching the on_childObject_signal pattern or the manual connection connect(ui->actionAbout, &QAction::triggered, this, &TextEditor::on_actionAbout_triggered); should be removed.
The reason for the dual call is QMetaObject::connectSlotsByName, which is usually (and also in this case) called by setupUi. It automatically connects the methods matching on_childObject_signal naming convention to their name-designated signals.

Qt adding child widget in resizeEvent

I have a widget W deriving from QFrame with layout set to an instance of QVBoxLayout. I wonder if the following resizeEvent implementation is correct or is it going to cause an infinite loop:
void W::resizeEvent(QResizeEvent *event) {
for (/* some condition based on the new size of this widget */) {
// Infinite loop or not?
qobject_cast<QVBoxLayout *>(layout())->addWidget(new QWidget());
}
}
So far it worked for me, is this by pure luck?
This is okay. W owns a QLayout which owns QWidget. Adding the QWidget to the QLayout does not change the size of W. You see this all the time. For example, if you place a child widget in a parent and the parent is too small, the child widget will be clipped. Stately differently, the size of the parent does not stretch to accommodate the size of the child. I believe your code would be a typical way to hide or show widgets based on the size of the parent (for example, when the window size changes).
Painting and constructing a hierarchy of widgets are two different things. So, adding QWidgets is just fine, but using QPainter directly in resizeEvent not.
Hierarchy of QWidgets
A hierarchy of QWidgets derivatives (QLineEdit, QPushButton, ...) is a high level specification of how the graphical user interface should look like and may be ordered using QLayout items.
Painting
Painting (using QPainter) is the process of actually drawing something on the screen and is purely done in the virtual function QWidget::paintEvent. Every derivative of QWidget should provide an implementation of this empty base function. The default derivatives (QLineEdit, ...) provide an implementation of paintEvent based on their current state (size of the widget, current text for a QLineEdit, ...) and the current QStyle object, which is typically automatically set based on your OS, but may be changed programmatically using QWidget::setStyle or QApplication::setStyle. A repaint can be requested using QWidget::update.
"Should not/need not" vs "may not"
The sentence "No drawing need be (or should be) done inside this handler." is meant for people implementing a custom QWidget (with a new implementation of paintEvent) to make it clear that you should not implement your painting here, but that a paintEvent will be automatically triggered.
"Should not/need not" is some advice, they do not write "may not". So, if you for some reason (ex. real-time applications) want an immediate screen refreshment, you may invoke a repaint immediately using repaint, resulting in paintEvent being called during resizeEvent. As long as all the QPainter operations on a QWidget are inside a paintEvent (as required by the warning in the QPainter documentation), everything is just fine.
Adding widgets to the layout, using addWidget, within the resizeEvent function is not a problem as it does not instantly trigger a drawing.
You can easily verify this by compiling and executing this simple project:
dialog.h:
#pragma once
#include <QDialog>
class Dialog : public QDialog
{
Q_OBJECT
public:
Dialog(QWidget *parent = 0);
~Dialog();
void resizeEvent(QResizeEvent *event);
void paintEvent(QPaintEvent *event);
private:
bool resizing;
};
dialog.cpp:
#include "dialog.h"
#include <QResizeEvent>
#include <QVBoxLayout>
#include <QPushButton>
#include <QDebug>
Dialog::Dialog(QWidget *parent)
: QDialog(parent),
resizing(false)
{
new QVBoxLayout(this);
}
Dialog::~Dialog()
{
}
void Dialog::resizeEvent(QResizeEvent *event)
{
resizing = true;
if ( event->size().width() == event->size().height() )
{
qDebug() << "Adding widget";
// Infinite loop or not?
layout()->addWidget(new QPushButton());
}
resizing = false;
}
void Dialog::paintEvent(QPaintEvent *event)
{
if ( resizing )
{
qDebug() << "Painting while resizing widget";
}
}
main.cpp:
#include "dialog.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
w.show();
return a.exec();
}
When you run the program, resize the dialog to make it be square (width==height), some buttons are inserted ("Adding widget" is printed to the console), but you'll never see "Painting while resizing widget" message. This is most likely because addWidget sets a dirty display flag that is processed later by the framework. It invalidates the display, but does not repaint it right away.
So what you are doing is fine and does not violate the framework requirement ("No drawing need be (or should be) done inside this handler.").
However, if you are not confident (maybe the painting could be operated right away on different OS, or in future Qt versions....you can't be sure), you can also delay the insertion by emitting a signal connected to a slot using Qt::QueuedConnection, this slot would be executed "later" and then do the call to addWidget, guaranteeing that it's done outside the resizeEvent function.

Qt and C++ - my own class and signals/slots

I've started learning Qt with C++ by writing a simple GUI. At the beginning, after I had learnt mechanism of signals and slots I decided to write program which gives us ability to control industrial robot arm. So the idea is simple: We've 6 buttons and depending on which one we pressed, then a text appears describing what have we done; for example: "Arm moved to the left".
I am going to build it up but first I have some questions to you.
Here is my code:
Arm.h:
#ifndef ARM_H
#define ARM_H
#include <QVector>
#include <QString>
#include <QLabel>
class Arm{
public:
Arm();
static void displayMoves(QLabel *ptrQLabel); //function for display QString listMoves
QVector<bool(*)(void)> vctrMovesFun; //contains pointers for function which defines moves of industrial robot
private:
static QString listMoves; //contain every move which industrial robot has done
static bool moveArmForward();
static bool moveArmBackward();
static bool moveArmLeft();
static bool moveArmRight();
static bool spinArmLeft();
static bool spinArmRight(); //all this functions define moves of robot's arm
};
#endif // ARM_H
Arm.cpp:
#include "arm.h"
QString Arm::listMoves = ""; //empty string
//***************************************************************
Arm::Arm(){
vctrMovesFun = {&moveArmForward, &moveArmBackward, &moveArmLeft,
&moveArmRight, &spinArmLeft, &spinArmRight}; //set reference to functions
}
//***************************************************************
bool Arm::moveArmForward(){
listMoves+= "Arm moved forward\n";
return true;}
//***************************************************************
bool Arm::moveArmBackward(){
listMoves+= "Arm moved backward\n";
return true;}
//***************************************************************
bool Arm::moveArmLeft(){
listMoves+= "Arm moved to the left\n";
return true;}
//***************************************************************
bool Arm::moveArmRight(){
listMoves+= "Arm moved to the right\n";
return true;}
//***************************************************************
bool Arm::spinArmLeft(){
listMoves+= "Arm spinned to the left\n";
return true;}
//***************************************************************
bool Arm::spinArmRight(){
listMoves+= "Arm spinned to the right\n";
return true;}
//***************************************************************
void Arm::displayMoves(QLabel *ptrQLabel){
ptrQLabel -> setText(listMoves);
}
MainWindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "arm.h"
#include <QMainWindow>
#include <QPushButton>
namespace Ui {
class MainWindow;}
class MainWindow : public QMainWindow{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
QPushButton *button0;
QPushButton *button1;
QPushButton *button2;
QPushButton *button3;
QPushButton *button4;
QPushButton *button5;
QLabel *label;
Arm arm;
private slots:
void useVector0();
void useVector1();
void useVector2();
void useVector3();
void useVector4();
void useVector5();
};
#endif // MAINWINDOW_H
MainWindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui -> setupUi(this);
this -> setGeometry(0,0,800,700);
this -> setStyleSheet("background-color:rgb(188, 198 ,204)");
button0 = new QPushButton("Move forward", this);
button0 -> setGeometry(50,50, 100,50);
button0 -> setStyleSheet("background-color:rgb(108, 118, 143)");
connect(button0, SIGNAL (clicked()), this, SLOT (useVector0()));
button1 = new QPushButton("Move backward", this);
button1 -> setGeometry(50,150, 100,50);
button1 -> setStyleSheet("background-color:rgb(108, 118, 143)");
connect(button1, SIGNAL (clicked()), this, SLOT (useVector1()));
button2 = new QPushButton("Move left", this);
button2 -> setGeometry(50,250, 100,50);
button2 -> setStyleSheet("background-color:rgb(108, 118, 143)");
connect(button2, SIGNAL (clicked()), this, SLOT (useVector2()));
button3 = new QPushButton("Move right", this);
button3 -> setGeometry(50,350, 100,50);
button3 -> setStyleSheet("background-color:rgb(108, 118, 143)");
connect(button3, SIGNAL (clicked()), this, SLOT (useVector3()));
button4 = new QPushButton("Spin left", this);
button4 -> setGeometry(50,450, 100,50);
button4 -> setStyleSheet("background-color:rgb(108, 118, 143)");
connect(button4, SIGNAL (clicked()), this, SLOT (useVector4()));
button5 = new QPushButton("Spin right", this);
button5 -> setGeometry(50,550, 100,50);
button5 -> setStyleSheet("background-color:rgb(108, 118, 143)");
connect(button5, SIGNAL (clicked()), this, SLOT (useVector5()));
label = new QLabel("", this);
label ->setStyleSheet("background-color:rgb(0, 0, 0)");
label -> setGeometry(300,50,300,600);
}
//************************************************************************
MainWindow::~MainWindow(){
delete ui;
}
//*************************************************************************
void MainWindow::useVector0(){
arm.vctrMovesFun[0]();
arm.displayMoves(label);}
//*************************************************************************
void MainWindow::useVector1(){
arm.vctrMovesFun[1]();
arm.displayMoves(label);
}
//*************************************************************************
void MainWindow::useVector2(){
arm.vctrMovesFun[2]();
arm.displayMoves(label);
}
//*************************************************************************
void MainWindow::useVector3(){
arm.vctrMovesFun[3]();
arm.displayMoves(label);
}
//*************************************************************************
void MainWindow::useVector4(){
arm.vctrMovesFun[4]();
arm.displayMoves(label);
}
//*************************************************************************
void MainWindow::useVector5(){
arm.vctrMovesFun[5]();
arm.displayMoves(label);
}
main.cpp:
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
As you can see there is nothing special. My questions:
I don't understand ui in MainWindow class. What is it and how can it be helpful in Qt?
When I create vector of pointers to my functions I need to make them static, in another way I can't put them into vector. Why? (class Arm)
Constructor in MainWindow. Generally constructor is being called only once when we are creating our object, so why method connect in MainWindow.cpp work for the whole program?
As you can see, there is 6 method to use my own function. I named them for example as: void useVector0(). I am truly sure that it's very bad to do. There should be one method but if I do something like:
void MainWindow::useVector(unsigned short k){
arm.vctrMovesFun[k]();
arm.displayMoves(label);
I can't use it as a slot because signal clicked() has no arguments. How to solve it? Overload clicked() method?
Maybe you have a general opinion about my code so write it. I'll be very happy for every words of criticism.
As others have already pointed out, your question needs some improvement. I suggest you read How to ask, where you'll find nice guidlines about what can I ask around here and how do I ask a nice question.
Nonetheless, I'm going to give you a brief answer to your questions, hoping that it will allow you to ask a more specific, new question, if you have one.
What are .ui files, of a "Qt-Form-Class" good for?
Right now you are creating your buttons inside of the MainWindow's constructor. That might be okay for simple GUIs, but you have to kind of "guess" the positions of the buttons.
If you use the Qt Designer you can create your layouts with the help of some tools. Once you've placed some elements with the designer you will be able to access them from code like this:
ui->label1->setText("hello World");
You can connect those UI widgets' signal to slots either by using connect() in your code or by using the Designer to add them to the UI file.
How can I create a pointer to a member function?
http://en.cppreference.com/w/cpp/language/pointer#Pointers_to_member_functions
Not sure what you're asking here
How can I execute different code in a slot, depending on the sender?
Take a look at QSignalMapper.
It will not give you a unsigned short k as you asked for, but a QString depending on which widget emitted the signal.
Could you review my code?
Now that's definitely a question for the Code Review Stack Exchange site.
QMainWindow is basically same as QWidget when used as a (guess what) main window, the noticeable difference is that QWidget expects you to have only 1 window in ur application, while QMainWindow is more about serving as the most important window which will "control" all the rest (like alert message boxes for example). you really should use QWidget as the base in most cases unless you are sure you even need QMainWindow.
i am not completely sure about it so please don't count it as a biblical rule, but if i remember correctly: member class functions are not duplicated per object, means every instance of the class calls the one and only address assigned to the function in class creation. in other words - they are static.
notice, that "everywhere" in the program is actually inside the constructor itself. kek.
most of Qt coding happens in the scope of the main window constructor function upon it's creation. it is a bit hard to understand if you are used to main() inside main.cpp . ofcourse the "connect" method is working anywhere inside the constructor because the constructor is in the same scope as any other method of the class (constructor is a method too afterall)
indeed there is a better way. the new "connect" version of qt5 is taking a reference to both signal and slot functions instead of macros SLOT() and SIGNAL(), means you can fit-in more dynamically and flexibly. you shall adopt that new version or at least know about it's existence, as it is awesome. (you are using qt4 version of connect, which is still supported tho)
unfortunately, TLDR :D
you can take it as a critics. good luck in your project m9
I don't understand ui in MainWindow class. What is it and how can it be helpful in Qt?
Currently you're creating your GUI in code. However, there are applications (like Qt Creator's "Design" mode) that will write the code that creates your GUI for you. The problem with that is that, if you then edit that code, Qt Creator will have a very hard time reconciling your modifications with any changes it wants to make.
To avoid the issue, you use the object in the ui instance variable. That object is what Qt Creator generates, and you don't touch that code. Instead, all your code goes into your MainWindow.
When I create vector of pointers to my functions I need to make them static, in another way I can't put them into vector. Why? (class Arm)
static functions are standalone functions. They don't have an object associated with them. Member functions (non-static functions in an object) on the other hand, have a "this". So, to call a standalone function, you just call MyFunction( 1 ) or whatever, whereas to call a member function, you need to tell it which object's member function you want to call (myObject->MyMemberFunction( 1 )).
Your is defined to hold pointers to standalone functions, so doesn't have any room to store the object pointers to go with a member function.
If you want to learn more about pointers to member functions, look up that topic in any good C++ textbook. That said, Qt hides C++'s pointers to member functions behind slots and signals. So you might just want to not keep an array and instead define an array of those.
Constructor in MainWindow. Generally constructor is being called only once when we are creating our object, so why method connect in MainWindow.cpp work for the whole program?
There is only one MainWindow object in your project, and it is created at the start of main() and only goes away once main() exits. So it lives just as long as your entire application.
As you can see, there is 6 method to use my own function. I named them for example as: void useVector0(). I am truly sure that it's very bad to do. (...) I can't use it as a slot because signal clicked() has no arguments.
I think you want QSignalMapper for that: Passing an argument to a slot

qTreeView scrollToBottom() ignored

Overflowers!
I'm getting crazy trying using scrollTo() in qTreeView (or QListView) widget. To make my question simple I've reduced my code to a simple scrollToBottom() which I can't manage to use as well. Here is the mainWindow code:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <iostream>
#include <qfilesystemmodel.h>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QFileSystemModel *model = new QFileSystemModel(this);
QModelIndex modelRootIndex = model->setRootPath(QDir::rootPath());
ui->treeView->setModel(model);
ui->treeView->setRootIndex(modelRootIndex);
ui->treeView->scrollToBottom();
if(modelRootIndex.isValid()) std::cout << "validIndex" << std::endl;
}
MainWindow::~MainWindow()
{
delete ui;
}
As far as I know it's all ok (I get the "ValidIndex" string on standard output), but the widget doesn't scroll to bottom at all.
I'm using Desktop QT5.0.2 msvc2010 32bit.
Any Idea? Thanks. L
QFileSystemModel and the QFileSystemWatcher are kept up-to-date in a separate thread. Thus, simply setting the model on the tree view does not ensure that the model will be fully populated by the time you make the call to scrollToBottom. Use a single shot timer with a small delay to give the model time to populate.
QTimer::singleShot(1000, ui->treeView, SLOT(scrollToBottom()));
Additionally, (and I don't know your application, so this may or may not be true) it may be confusing to your users that the data they need to see is at the bottom of the view anyway. You may think about whether you can sort the view items in reverse order (thus having the data you need at the top) to avoid scrolling and potentially make the usage more intuitive.
This is because of the asynchronous way that QFileSystemModel works, and what appears to be a bug in Qt that was never fixed: https://bugreports.qt.io/browse/QTBUG-9326
You can work around it by doing QApplication::sendPostedEvents() immediately before the call to scrollTo(), but you must call them in a function that is connected to the directoryLoaded signal:
MyFileBrowser::MyFileBrowser(QWidget *parent) : QWidget(parent), ui(new Ui::MyFileBrowser) {
//...
connect(model, SIGNAL(directoryLoaded(QString)), this, SLOT(dirLoaded(QString)));
QModelIndex folderIndex = model->index("path/to/dir");
files->setCurrentIndex(folderIndex);
files->expand(folderIndex);
}
void WFileBrowser::dirLoaded(QString dir) {
if (dir == model->filePath(files->currentIndex())) {
QApplication::sendPostedEvents(); // booyah!!
files->scrollTo(files->currentIndex(), QAbstractItemView::PositionAtTop);
}
}

Qt C++ GUI QSpinBox Storing Input?

How would I take the user input from the a spinbox and use that as a value? In other words if I wanted to store the input from the QSpinBox into a variable how would I go about doing this. Im really new at Qt GUI so any input would be greatly appreciated.
To react to GUI elements in Qt, you connect to the signals that those elements give off. Also if you have a pointer to the instance of it, you can query and change its states and properties.
Here is a quick example of what you are looking for
#include <QApplication>
#include <QVBoxLayout>
#include <QLabel>
#include <QSpinBox>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// The widget, contains a layout
QWidget * w;
w = new QWidget;
// The layout arranges and holds
// all the children of the widget
QVBoxLayout * vbox;
vbox = new QVBoxLayout;
// The user input element, the spinbox!
QSpinBox * spinbox;
spinbox = new QSpinBox();
spinbox->setValue(5);// example of using a pointer to edit its states
// now add it to the layout
vbox->addWidget(spinbox);
// add in an element to connect to,
// the infamous QLabel
QLabel * label;
label = new QLabel("spinbox output");
// add it also to the layout
vbox->addWidget(label);
// connection can happen anytime as long as the two elements
// are not null!
// This connection takes advantage of signals and slots
// and making their connection at runtime.
// if a connect call fails you should be able to see why in the
// application output.
QObject::connect(spinbox, SIGNAL(valueChanged(QString)),
label, SLOT(setText(QString)));
// associate the layout to the widget
w->setLayout(vbox);
// make the widget appear!
w->show();
return a.exec();
}
I usually put most of the initializing and connecting of GUI elements into the constructor or a method of the main QWidget or the QMainWindow. I often take the signal from a GUI input element, like a spinbox and I connect it to a custom slot defined on my subclassed QWidget. Then if I want to display it with the input value differently or increase the output by 2, I can do so easily.
// in the constructor of my Widget class
// after spinbox has been initialized
QObject(m_spinbox, SIGNAL(valueChanged(int)),
this, SLOT(on_spinboxValueChanged(int)));
void Widget::on_spinboxValueChanged(int i)
{
// here m_label is a member variable of the Widget class
m_label->setText(QString::number(i + 2));
// if accessing the value in this function is inconvenient, you can always
// use a member variable pointer to it to get its stored value.
// for example:
int j = m_spinbox->value();
qDebug() << "Spinbox value" << j;
}
Identical things can be done in QML and Qt Quick, and for many people it is easier and more intuitive because of how close it is to javascript and css.
Also Qt Creator has a tool for generating forms, and it provides another way to create your widgets with layouts and then when you access your elements you do it through a ui variable.
Also the Qt docs and examples are awesome. Taking time to learn them and read up on them is well worth the effort.
Hope that helps.