main.cpp
#include <QtGui>
#include <QApplication>
int main(int argv, char **args)
{
QApplication app(argv, args);
QTextEdit textEdit;
QPushButton quitButton("Quit");
QObject::connect(&quitButton, SIGNAL(clicked()), qApp, SLOT(quit()));
QVBoxLayout layout;
layout.addWidget(&textEdit);
layout.addWidget(&quitButton);
QWidget window;
window.setLayout(&layout);
window.show();
return app.exec();
}
notepad.cpp
#include <QtGui>
#include <QApplication>
class Notepad : public QMainWindow
{
Notepad::Notepad()
{
saveAction = new QAction(tr("&Open"), this);
saveAction = new QAction(tr("&Save"), this);
exitAction = new QAction(tr("E&xit"), this);
connect(openAction, SIGNAL(triggered()), this, SLOT(open()));
connect(saveAction, SIGNAL(triggered()), this, SLOT(save()));
connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
fileMenu = menuBar()->addMenu(tr("&File"));
fileMenu->addAction(openAction);
fileMenu->addAction(saveAction);
fileMenu->addSeparator();
fileMenu->addAction(exitAction);
textEdit = new QTextEdit;
setCentralWidget(textEdit);
setWindowTitle(tr("Notepad"));
}
Q_OBJECT
public:
Notepad();
private slots:
void open();
void save();
void quit();
private:
QTextEdit *textEdit;
QAction *openAction;
QAction *saveAction;
QAction *exitAction;
QMenu *fileMenu;
};
ERRORS:
extra qualification 'NotePad::' on Member Notepad (Line 8)
notepad::notepad() cannot be overloaded (Line 32)
with notepad::notepad (line 8)
Why am I getting these errors? The constructor looks fine and the class setup looks fine. But I am getting these errors.
The Notepad:: in front of your Notepad() constructor inside the Notepad class is not necessary. Neither is the later declaration, because you have done this and defined it (although privately) above. You might want to consider separating it into a header and cpp file.
There are still various other issues with the code as you have posted, but the errors you posted are most likely caused by what I mentioned above.
You have qualified the inline private constructor with Notepad::
You have then incorrectly overloaded that private constructor as public in a second declaration
Q_OBJECT macro needs to be first in the class declaration before methods and members.
You have at least 4 memory leaks for each instance of Notepad?
etc
Perhaps pick up a book?
Related
I'm trying to create a class for signal/slot connection (old syntax, Qt 4.8) and I am doing something wrong as I keep receiving a template error: invalid declaration of member template in local class... That has obviously something to do with the Q_OBJECT macro... What should I do? Here is a modeled program:
#include <QtGui>
#include <QtCore>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget mw;
mw.setWindowTitle("Main Window");
mw.resize(400, 400);
mw.show();
QLabel label ("Enter something:", &mw);
label.setAlignment(Qt::AlignHCenter);
label.show();
QLineEdit line (&mw);
line.show();
QString a = line.text();
QTextEdit text (&mw);
text.show();
class MyObject : public QObject
{
Q_OBJECT /* the problem is somewhere here... */
public:
QTextEdit text;
QString a;
public slots:
void onClicked() {
text.setText(a);
}
};
QPushButton btn ("Convert", &mw);
QObject::connect(
&btn,
SIGNAL(clicked()),
this,
SLOT(onClicked()));
btn.show();
QVBoxLayout layout_mw;
layout_mw.addWidget(&label);
layout_mw.addWidget(&line);
layout_mw.addWidget(&btn);
layout_mw.addWidget(&text);
mw.setLayout(&layout_mw);
return app.exec();
}
Qt's MOC can process neither nested classes nor local classes. You will have to move the class definition outside main. The documentation only mentions nested classes, but the limitation does apply to local classes too.
I am having difficulty in my Qt program with connecting button signals to my slots. My code is:
Main.cpp
#include <QtGui/QApplication>
#include "MainWidget.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWidget mainWidget;
mainWidget.show();
return app.exec();
}
MainWidget.h
#ifndef MAINWIDGET_H
#define MAINWIDGET_H
#include <QWidget>
class MainWidget : public QWidget
{
public:
MainWidget();
public slots:
void bAdvice_clicked();
void bWeather_clicked();
void bNextMeeting_clicked();
void bQuit_clicked();
};
#endif // MAINWIDGET_H
MainWidget.cpp
#include "MainWidget.h"
#include <QMessageBox>
#include <QPushButton>
#include <QTextEdit>
#include <QVBoxLayout>
MainWidget::MainWidget()
{
QLayout *layout = new QVBoxLayout();
this->setLayout(layout);
QTextEdit *message = new QTextEdit();
layout->addWidget(message);
QPushButton *bAdvice = new QPushButton("Advice");
connect(bAdvice, SIGNAL(clicked()), this, SLOT(bAdvice_clicked()));
layout->addWidget(bAdvice);
QPushButton *bWeather = new QPushButton("Weather");
connect(bWeather, SIGNAL(clicked()), this, SLOT(bWeather_clicked()));
layout->addWidget(bWeather);
QPushButton *bNextMeeting = new QPushButton("Next Meeting");
connect(bNextMeeting, SIGNAL(clicked()), this, SLOT(bNextMeeting_clicked()));
layout->addWidget(bNextMeeting);
QPushButton *bQuit = new QPushButton("Quit");
connect(bQuit, SIGNAL(clicked()), this, SLOT(bQuit_clicked()));
layout->addWidget(bQuit);
}
void MainWidget::bAdvice_clicked()
{
}
void MainWidget::bWeather_clicked()
{
}
void MainWidget::bNextMeeting_clicked()
{
QMessageBox::information(this, "Next Meeting", "Today", QMessageBox::Ok);
}
void MainWidget::bQuit_clicked()
{
this->close();
}
The program outputs the following:
Starting C:\Users\Sameer\Documents\PartAQuestion2\debug\PartAQuestion2.exe...
Object::connect: No such slot QWidget::bAdvice_clicked() in MainWidget.cpp:16
Object::connect: No such slot QWidget::bWeather_clicked() in MainWidget.cpp:20
Object::connect: No such slot QWidget::bNextMeeting_clicked() in MainWidget.cpp:24
Object::connect: No such slot QWidget::bQuit_clicked() in MainWidget.cpp:28
C:\Users\Sameer\Documents\PartAQuestion2\debug\PartAQuestion2.exe exited with code 0
The code seems right, no compiler warnings. Just this output at runtime. But it looks like I hooked the signals and slots up correctly.
Add Q_OBJECT to your class, like this:
class MainWidget : public QWidget
{
Q_OBJECT
You also have to run moc to generate some helper code. qmake does that automatically for your, but if you compile this yourself, you need to run moc.
When I started with Qt, I had this problem a lot. As I see it your slots are defined wrong. If you look at the signature for the signal (Qt Clicked Signal Docs), you will see that the argument list is (bool clicked = false).
The way Qt's signal & slots connect work at run time, is that it will only connect the signal and slot if they have the exact same signatures. If they don't match exactly, no connection.
so in MainWidget.h
public slots:
void bAdvice_clicked(bool);
In MainWidget.cpp
connect(bAdvice, SIGNAL(clicked(bool)), this, SLOT(bAdvice_clicked(bool)));
Things will start working for you.
Edited:
Compiled your code and all the slots were correctly called.
It was just the Q_OBJECT macro that was missing.
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)));
}
I'm programming in QT 4.8.4 with C++. I want to have a drop-down menu, where I can select an option, and then it will run an exe with the selected item on the menu as the option for the exe.
Here's my code:
#ifndef GUI_H
#define GUI_H
#include <QDialog>
#include <QtGui>
class QLabel;
class QLineEdit;
class QPushButton;
class gui : public QDialog
{
Q_OBJECT
public:
gui(QWidget *parent = 0);
public slots:
void gui::on_go_clicked();
private:
QLabel *label1;
QLabel *label2;
QLineEdit *lineEdit;
QPushButton *goButton;
QComboBox cb;
};
#endif
And the .cpp file:
#include <QtGui>
#include <QApplication>
#include <QComboBox>
#include "gui.h"
#include <vector>
gui::gui(QWidget *parent) : QDialog(parent)
{
label1 = new QLabel(tr("Insert Name (Optional):"));
label2 = new QLabel(tr("Class Name (Required):"));
lineEdit = new QLineEdit;
goButton = new QPushButton(tr("&Go"));
goButton->setDefault(true);
connect(goButton, SIGNAL(clicked()), this, SLOT(on_go_clicked()));
QComboBox *cb = new QComboBox();
cb->addItem("Hello", "1");
cb->addItem("Test", "2");
QHBoxLayout *hLayout1 = new QHBoxLayout;
hLayout1->addWidget(label1);
hLayout1->addWidget(lineEdit);
QHBoxLayout *hLayout2 = new QHBoxLayout;
hLayout2->addWidget(label2);
hLayout2->addWidget(cb);
QHBoxLayout *hLayout3 = new QHBoxLayout;
hLayout3->addWidget(goButton);
hLayout3->addStretch();
QVBoxLayout *vLayout = new QVBoxLayout;
vLayout->addLayout(hLayout1);
vLayout->addLayout(hLayout2);
vLayout->addWidget(cb);
vLayout->addLayout(hLayout3);
setLayout(vLayout);
setWindowTitle(tr("TEST"));
setFixedHeight(sizeHint().height());
}
void gui::on_go_clicked()
{
QMessageBox::information(this, "ASDF", cb.currentText());
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
gui *stuff = new gui;
stuff->show();
return app.exec();
}
Right now I'm just trying to figure out how to use QComboBox, which isn't working. My code compiles, but when I run it I get "Object::connect: No such slot gui::on_go_clicked()"
I'm doing exactly what a tutorial says to do. I can't figure out why this isn't working.
Remove gui:: :
class gui : public QDialog{
Q_OBJECT
...
public slots:
void gui::on_go_clicked();
^^^^^
Remove it
I wonder why you code even compiles. No 'extra qualification on member on_go_clicked'.
Remove gui:: from on_go_clicked in your header.
You have two QComboBox objects that you reference.
The first is at the class level:
class gui : public QDialog{
Q_OBJECT
public:
gui(QWidget *parent = 0);
public slots:
void gui::on_go_clicked();
private:
QLabel *label1;
QLabel *label2;
QLineEdit *lineEdit;
QPushButton *goButton;
QComboBox cb; // <<<=== class-level automatic object
};
The second is a local pointer-to-QComboBox object that exists in the constructor
gui::gui(QWidget *parent) : QDialog(parent){
...
QComboBox *cb = new QComboBox(); // <<<=== function-level pointer using the same name
// as the class-level automatic object
To correct the problem, you can change the class-level object to be a pointer and then change the object creation to be a simple assignment instead of a declaration-and-initialisation.
cb = new QComboBox();
Also, once you've done this, you'll need to modify the slot so that the pointer dereference operator is used to access the text() function
void gui::on_go_clicked(){
QMessageBox::information(this, "ASDF", cb->currentText());
}
I am following the Qt example listed in the QtSDK titled: "Getting Started Programming with Qt". My problem is that the program doesn't display any of the objects.
My main.cpp looks like so:
#include <QtGui>
#include <notepad.h>
int main(int argv, char **args) {
QApplication app(argv, args);
QVBoxLayout layout;
Notepad notepad();
QWidget window;
window.setLayout(&layout);
window.show();
return app.exec();
}
The 'notepad.h' file:
#ifndef NOTEPAD_H
#define NOTEPAD_H
#include <QtGui>
class Notepad : public QMainWindow {
Q_OBJECT
public:
Notepad();
private slots:
void open();
void save();
void quit();
private:
QTextEdit *text_edit;
QAction *open_action;
QAction *save_action;
QAction *exit_action;
QMenu *file_menu;
};
#endif // NOTEPAD_H
The 'notepad.cpp' file:
#include "notepad.h"
Notepad::Notepad() {
open_action = new QAction(tr("&Open"), this);
save_action = new QAction(tr("&Save"), this);
exit_action = new QAction(tr("&Exit"), this);
connect(open_action, SIGNAL(triggered()), this, SLOT(open()));
connect(save_action, SIGNAL(triggered()), this, SLOT(save()));
connect(exit_action, SIGNAL(triggered()), qApp, SLOT(quit()));
file_menu = menuBar()->addMenu(tr("&File"));
file_menu->addAction(open_action);
file_menu->addAction(save_action);
file_menu->addSeparator();
file_menu->addAction(exit_action);
text_edit = new QTextEdit;
setCentralWidget(text_edit);
setWindowTitle(tr("Notepad"));
}
void Notepad::open() {
...
}
void Notepad::save() {
...
}
void Notepad::quit() {
}
Any help in resolving the matter would be much appreciated.
Edit
My original question asked why I was I was getting a compile time error for not implementing the "quit" function incase you are wondering :).
You have to implement quit() method defined as private slot in notepad.h . Unresolved errors are linking errors and tells you that linker hasn't found any implementation for the function declaration. Add this to notepad.cpp :
void Notepad::quit() {
...
}
For new question :
Try notepad.show(). Your MainWindow can be notepad object because it is a QMainWindow.
int main(int argv, char **args) {
QApplication app(argv, args);
Notepad notepad();
notepad.show();
return app.exec();
}