Changing a label in Qt - c++

I'm trying to make a simple program consisting of a button and a label. When the button is pressed, it should change the label text to whatever is in a QString variable inside the program. Here's my code so far:
This is my widget.h file:
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget();
private:
Ui::WidgetClass *ui;
QString test;
private slots:
void myclicked();
};
And here's the implementation of the Widget class:
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent), ui(new Ui::WidgetClass)
{
ui->setupUi(this);
test = "hello world";
connect(ui->pushButton, SIGNAL(clicked()), ui->label, SLOT(myclicked()));
}
Widget::~Widget()
{
delete ui;
}
void Widget::myclicked(){
ui->label->setText(test);
}
It runs but when the button is clicked, nothing happens. What am I doing wrong?
Edit: after i got it working, the text in the label was larger than the label itself, so the text got clipped. I fixed it by adding ui->label->adjustSize() to the definition of myclicked().

You are connecting the signal to the wrong object. myclicked() is not a slot of QLabel, it is a slot of your Widget class. The connection string should be:
connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(myclicked()));
Take a look at the console output of your program. There should be an error message saying something like:
Error connecting clicked() to
myclicked(): No such slot defined in QLabel

Related

QPushButton signal

I'm trying to get a QPushButton's action method running doing the following.
My login.h:
//
// Created by simon on 28.04.22.
//
#ifndef RESTCLIENT_LOGIN_H
#define RESTCLIENT_LOGIN_H
#include <QWidget>
#include <QPushButton>
#include <QLineEdit>
QT_BEGIN_NAMESPACE
namespace Ui { class Login; }
QT_END_NAMESPACE
class Login : public QWidget {
Q_OBJECT
QPushButton * loginButton;
QLineEdit * passwordInput;
QLineEdit * usernameInput;
QObject::connect(loginButton, &QPushButton::click, this, &buttonPressed);
public slots:
void buttonPressed();
public:
explicit Login(QWidget *parent = nullptr);
~Login() override;
private:
Ui::Login *ui;
};
#endif //RESTCLIENT_LOGIN_H
The corresponding login.cpp:
#include "login.h"
#include "ui_Login.h"
Login::Login(QWidget *parent) :
QWidget(parent), ui(new Ui::Login) {
ui->setupUi(this);
}
Login::~Login() {
delete ui;
}
void Login::buttonPressed() {
//todo process login
}
The build fails, and Clion marks the code line containing the connect method in red. I'm aware that my attempt to connect the signal to my function is wrong, I hope someone can help me.
The issue is that QPushButton::click() is not a signal, it is a function that performs a click.
The signal emitted when clicking the button is: QPushButton::clicked().
And as already mentioned, you should call the QObject::connect() function from inside a function (in the constructor for example). It makes no sense to call it in the class declaration.
The connect call looks mostly fine, except that click is not a signal as Fareanor first noticed in his answer; use the clicked signal from QPushButton's base class QAbstractButton instead. See also QAbstractButton Signals for all available signals.
Additionally, connect needs to be inside of a function, not in the class declaration. The button needs to be initialized for the connection to work, so the constructor of your Login class seems like a logical place for it, for example:
Login::Login(QWidget *parent) :
QWidget(parent), ui(new Ui::Login) {
ui->setupUi(this);
QObject::connect(loginButton, &QPushButton::clicked, this, &buttonPressed);
}
From the code you're showing it seems that loginButton is separate from the other GUI stuff in ui, so you probably also need to create that button first, i.e., adding , loginButton(new QPushButton) after ui(...), or move the loginButton to your .ui file...

How to dynamically add widget inside a QStackedWidget

In order to replicate the problem I have I prepared a small verifiable example.
I have 2 QStackedWidgets inside a QGroupBox with a couple more components as shown below:
I created another widget called QBoxForm which carries a QComboBox only.
This last widget should appear on the QStackedWidget on the left as soon as the QCheckbox is ticked.
The QStackedWidget receive something because it becomes bigger but it does not show the QComboBox. How to make sure that a component is fully visible inside a QStackedWidget?
mainwindow.cpp
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
mCombo = new CBoxForm;
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_checkBox_toggled(bool checked)
{
if(ui->checkBox->isChecked())
{
if(checked)
{
ui->stackedWidget->insertWidget(0, mCombo);
ui->stackedWidget->show();
}
}
if(!ui->checkBox->isChecked())
{
ui->stackedWidget->removeWidget(mCombo);
}
}
mainwindow.h
#include <QMainWindow>
#include "cboxform.h"
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_checkBox_toggled(bool checked);
private:
Ui::MainWindow *ui;
CBoxForm *mCombo;
};
Lastly the additional combobox handled by another widget:
cboxform.h
#include <QWidget>
namespace Ui {
class CBoxForm;
}
class CBoxForm : public QWidget
{
Q_OBJECT
public:
explicit CBoxForm(QWidget *parent = nullptr);
~CBoxForm();
private:
Ui::CBoxForm *ui;
};
cboxform.cpp
CBoxForm::CBoxForm(QWidget *parent) :
QWidget(parent),
ui(new Ui::CBoxForm)
{
ui->setupUi(this);
}
CBoxForm::~CBoxForm()
{
delete ui;
}
What I have done so far:
1) I followed the official documentation and applied the method insertWidget() as advised. In fact here is what I have done exactly. This part works and can be confirmed by the fact that the QStackedWidget become larger as I check the box.
Also consequently I remove the widget in a similar way applying removeWidget() method available in the official documentation.
Everything seems to follow the correct functioning, but the only missing part is that I don't understand why the QComboBox does not appear on the QStackedWidget as I followed precisely the official documentation.
Any idea on what I might be missing or forgot to include in the above code?
Thanks for pointing in the right direction for solving this problem.
You should add ui->stackedWidget->setCurrentIndex(0) after ui->stackedWidget->insertWidget(0, mCombo) to make it visible.

Can't use slots in connect qt

When I run my project I can't use train_button to add lines in text. Because of I got this error:
QObject::connect: No such slot QTextEdit::onClick()
I try to solve it, but searched only information about adding Q_OBJECT, but I got this. My project is standart Qt Widget Application.
.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPushButton>
#include <QTextEdit>
#include <QString>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void onClick(){
text->append("first\nsecond");
}
private:
QPushButton *train_button;
QTextEdit *text;
Ui::MainWindow *ui;
//QString a = "sdfsdfsdfsdf";
};
# endif // MAINWINDOW_H
.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow){
ui->setupUi(this);
this->setFixedSize(800,600);
text = new QTextEdit(this);
train_button = new QPushButton(this);
text->setGeometry(50,50,500,500);
text->setPlaceholderText("Here we go ...");
train_button->setText("example");
train_button->setGeometry(600,50,100,50);
train_button->setStyleSheet( "background-color: rgb(0, 255, 0);border-style: inset;border-width: 0px;border-radius: 5px;border-color: beige;font: bold 14px;min-width: 10em; padding: 2px;" );
connect(train_button,SIGNAL(clicked()),text,SLOT(onClick();));
}
MainWindow::~MainWindow()
{
delete train_button;
delete solver_button;
delete text;
delete ui;
}
I use QMake version 3.0 using Qt version 5.2.1.
The error is quite clear:
No such slot QTextEdit::onClick()
The documentation is clear as well. QTextEdit has no onClick slot anywhere.
It's not clear what you're trying to do. In any case, you aren't doing it correctly: you cannot connect an inexistent slot to a signal.
By looking at your code, I see that you defined onClick as a member function of MainWindow.
Therefore probably this is what you want:
connect(train_button, &QPushButton::clicked, this, &MainWindow::onClick);
That is, probably you want to attach a slot of the class MainWindow to the button, not a slot of a QTextEdit.

QT: simple text from QLineEdit to QLabel of different class

I'm trying to write a very basic program. The main window contains a label. Pressing the "Add New" button opens a QDialog with a QLineEdit. Changing the text, press "Add" and I would like the QLabel in the main window to be updated with the text from QLineEdit. I can get the signals through but the label is not updating. I understand that connect only works on instances of classes, not classes themselves. The problem seems to be the one class is not aware of the instance of the main window.
What I've tried to do is once the Add button is pressed, a signal is emitted. Once that signal is emitted, the slot in the mainWindow class receives a string to use in QLabel::setText().
I've read countless examples and documentation but the examples seem to be too different from the simple task I'm lost in. Any help is appreciated.
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtWidgets>
#include <QLabel>
class QLineEdit;
class QPushButton;
class QLabel;
class addDlg : public QDialog{
Q_OBJECT
public:
addDlg(QWidget *parent = 0);
signals:
void textChanged(const QString &text);
private slots:
void sendText(QWidget *parent);
private:
QPushButton *addButton;
QLineEdit *inputText;
};
class mainWindow : public QWidget{
Q_OBJECT
public:
mainWindow();
QLabel *textLabel;
public slots:
void recvText(const QString &text);
private slots:
void addDlgShow();
private:
QPushButton *addWindow;
addDlg *dialog;
};
#endif // MAINWINDOW_H
MainWindow.cpp
addDlg::addDlg(QWidget *parent)
: QDialog(parent){
inputText = new QLineEdit(tr("enter here"));
addButton = new QPushButton(tr("Accept"));
QVBoxLayout *vLayout = new QVBoxLayout;
vLayout->addWidget(inputText);
vLayout->addWidget(addButton);
setLayout(vLayout);
setWindowTitle(tr("Add new text"));
connect(addButton, SIGNAL(clicked()),
this, SLOT(sendText()));
}
void addDlg::sendText(){
QString text = inputText->text();
emit textChanged(text);
// This connect is where I believe the problem lies.
connect(this, SIGNAL(textChanged(QString)),
mainPtr, SLOT(recvText(QString)));
//mainPtr is uninitialized as I can't seem to point it to the manWindow instance
//I can do mainWindow* mainPtr = new mainWindow but that just creates a new instance.
//How do I pass on the first mainWindow main instance "mainPtr" to this class addDlg?
}
mainWindow::mainWindow()
: QWidget(0){
textLabel = new QLabel(tr("Empty"));
addWindow = new QPushButton(tr("Add New"));
dialog = new addDlg();
QVBoxLayout *vLayout = new QVBoxLayout;
vLayout->addWidget(textLabel);
vLayout->addWidget(addWindow);
setLayout(vLayout);
setWindowTitle(tr("Test 4"));
connect(addWindow, SIGNAL(clicked()),
this, SLOT(addDlgShow()));
}
void mainWindow::addDlgShow(){ dialog->show(); }
void mainWindow::recvText(const QString &text){
QString input = text;
textLabel->clear();
textLabel->setText(input);
textLabel->update();
}
One solution is to put your connect code in mainWindow::mainWindow where you have pointers to both the mainwindow and your newly created dialog. The snippet might change to this:
mainWindow::mainWindow() : QWidget(0) {
// ... existing code ..
// add this
connect(dialog, SIGNAL(textChanged(QString)),
this, SLOT(recvText(QString)));
}

C++ - Adding item to QListWidget from QPushButton

Hello I am trying to add items to a QListWidget from a QPushButton. Both the QListWidget and QPushButton are added as individual widgets inside of a QGraphicsScene. I want the effect of a box that fills with text lines
main.c
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
QGraphicsView view;
QGraphicsScene *scene = new QGraphicsScene(0, 0, 1200, 1200, &view);
scene->setBackgroundBrush(Qt::gray);
view.setScene(scene);
QPushButton *PushButton1;
PushButton1 = new QPushButton();
PushButton1->setGeometry(QRect(19, 20, 154, 4));
QListWidget *ListWidget;
ListWidget = new QListWidget;
scene->addWidget(ListWidget);
scene->addWidget(PushButton1);
QObject::connect(PushButton1, SIGNAL(clicked()),&w, SLOT(handleClick(*QListWidget)));
view.show();
return a.exec();
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::handleClick(QListWidget *List)
{
int test;
List->addItem("TESTING");
//QApplication::quit();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QListWidget>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
private slots:
public slots:
void handleClick(QListWidget *List);
};
#endif // MAINWINDOW_H
This code compiles fine. How I get the following error in the console when the application is running
QObject::connect: No such slot MainWindow::handleClick(*ListWidget) in ..\MenuTest\main.cpp:48
Can someone help me do this? I've seen several tutorials but it's using the designer to make the GUI and I'd like to know how to do it in code without using designer. Thanks.
Your slot accepts QListWidget but you're connecting with ListWidget as the parameter, the signature has to be an exact match due to the way signals and slots work in Qt.
Put handleClick under public slots: and change this line:
QObject::connect(PushButton1, SIGNAL(clicked()),&w, SLOT(handleClick(*ListWidget)));
To this:
QObject::connect(PushButton1, SIGNAL(clicked()),&w, SLOT(handleClick(*QListWidget)));
Update:
I see I missed a key point, the signatures have to match, as in parameter to parameter, so the line up there will not work.
To fix this remove the parameter completely, since PushButton1 can't send it automatically.
QObject::connect(PushButton1, SIGNAL(clicked()),&w, SLOT(handleClick()));
Also remove it here:
void MainWindow::handleClick()
To access the QListWidget you'll have to reference it directly, either by passing it to MainWindow's constructor or iterating the window's controls.