Qt no such signal, but it does exist - c++

Qt can't see a signal that exists.
I have a main window that opens up a child window, and the connect statement for that works absolutely fine:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "addstaffform.h"
#include "stafflist.h"
#include "editstaffwindow.h"
#include <QDialog>
#include <QString>
#include <QList>
#include "person.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_btn_add_clicked();
void refreshStaffList();
void receiveData(Person& newPerson);
void receiveEditedPerson(Person &editedPerson, int index);
void updateDeleteEnabled();
void updateEditEnabled();
void on_btn_delete_staff_clicked();
void on_btn_staff_edit_clicked();
private:
Ui::MainWindow *ui;
QString s;
QMainWindow *newWin;
QMainWindow *editStaffWin;
StaffList *m_staffList;
QList<Person> m_personList;
Person m_person;
};
#endif // MAINWINDOW_H
The method in mainwindow.cpp that works with no problem:
void MainWindow::on_btn_add_clicked()
{
//Open the add staff window, which is a form
newWin = new AddStaffWindow(this);
//connect the signal from the new form to the slot in this window to receive the person object
connect(newWin, SIGNAL(sendData(Person&)), this, SLOT(receiveData(Person&)));
newWin->show();
}
Signal in addstaffwindow.h (the instantiation of newWin)
signals:
void sendData(Person &p);
Now, in the edit form (editStaffWin), I have the signal, and I've made sure that Q_OBJECT definitely IS there, cleaned, run QMake and build several times, but it doesn't think that the signal exists.
editstaffwindow.h
signals:
void sendPerson(Person &, int index);
So in the mainwindow.cpp for editing, sendPerson(Person &, int) doesn't show up:
void MainWindow::on_btn_staff_edit_clicked()
{
//Get the index of the widget
int index = ui->lst_staff->currentRow();
int size = ui->lst_staff->count();
if (index > -1 && index <= size)
{
//get from staff list
m_person = m_staffList->getStaffAt(index);
editStaffWin = new EditStaffWindow(this, m_person, index);
connect(editStaffWin, SIGNAL(sendPerson(Person &, int)), this, SLOT(receiveEditedPerson(Person&,int)));
editStaffWin->show();
}
}
Any ideas why? I'm not doing anything different for either of them.
EDIT: full EditStaffWindow header:
#ifndef EDITSTAFFWINDOW_H
#define EDITSTAFFWINDOW_H
#include <QMainWindow>
#include "mainwindow.h"
#include "person.h"
#include <QObject>
namespace Ui {
class EditStaffWindow;
}
class EditStaffWindow : public QMainWindow
{
Q_OBJECT
public:
explicit EditStaffWindow(QWidget *parent, Person &p, int index);
~EditStaffWindow();
signals:
void sendPerson(Person &, int index);
private:
Ui::EditStaffWindow *ui;
Person m_person;
int m_index;
public slots:
void showData(Person &p, int index);
private slots:
void on_btn_save_clicked();
void on_btn_cancel_clicked();
};
#endif // EDITSTAFFWINDOW_H

It seems that not using the code autocompletion is probably part of the answer, as I have to manually type the signal
connect(editStaffWin, SIGNAL(sendPerson(Person &, int)), this, SLOT(receiveEditedPerson(Person&,int)));
Running clean, qmake, build all may have been part of it as well. What could have also caused a problem was how I was writing the signal for the connect statement, but looking back, it's the same.
What I did do, though, was remove the int declarations from the sendPerson signal, clean, build, then put them back, and it worked.
Apart from that, I'm not sure what caused it not to work.

Related

setWindowState from QMainWindow from QWidget

I have a QMainWindow Application which also includes an QStackedWidget.
The pages of the QstackedWidget are promoted to ui widgets for example heating_widget.ui
If I use a button slot on my QMainWindow I can use this to get my application to fullscreen:
void SmartHome::on_fullscreen_on_clicked()
{
SmartHome::setWindowState(Qt::WindowFullScreen);
}
But how can I do this from a button which is in the heating_widget.cpp file?
Using:
void heating_widget::on_fullscreen_on_clicked()
{
SmartHome::setWindowState(Qt::WindowFullScreen);
}
obviously doesn't work and throws this error at me:
cannot call member function 'void
QWidget::setWindowState(Qt::WindowStates)' without object
SmartHome::setWindowState(Qt::WindowFullScreen);
I know this has something to do with parent() but I can't get it to work.
Do you have any idea?
My smarthome.h file:
#ifndef SMARTHOME_H
#define SMARTHOME_H
#include <QTime>
#include <QMainWindow>
namespace Ui {
class SmartHome;
}
class SmartHome : public QMainWindow
{
Q_OBJECT
public:
explicit SmartHome(QWidget *parent = 0);
~SmartHome();
private slots:
void on_Info_Button_clicked();
void on_News_Button_clicked();
void on_Heating_clicked();
void timerslot();
void on_Config_clicked();
void on_About_clicked();
public slots:
void setFullscreen();
private:
Ui::SmartHome *ui;
QTimer* myTimer;
};
#endif // SMARTHOME_H
My heating_widget.h :
#ifndef HEATING_WIDGET_H
#define HEATING_WIDGET_H
#include "smarthome.h"
#include <QWidget>
namespace Ui {
class heating_widget;
class SmartHome;
}
class heating_widget : public QWidget
{
Q_OBJECT
public:
explicit heating_widget(QWidget *parent = 0);
~heating_widget();
private slots:
void on_fullscreen_on_clicked();
private:
Ui::heating_widget *ui;
};
#endif // HEATING_WIDGET_H
and my heating.widget.cpp:
#include "heating_widget.h"
#include "ui_heating_widget.h"
#include "smarthome.h"
#include "iostream"
heating_widget::heating_widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::heating_widget)
{
ui->setupUi(this);
QObject::connect(ui->fullscreen_on, SIGNAL(clicked()), this , SLOT(SmartHome::setFullscreen()));
}
heating_widget::~heating_widget()
{
delete ui;
}
void heating_widget::on_fullscreen_on_clicked()
{
parentWidget()->setWindowState(Qt::WindowFullScreen);
std::cout<<"clicked"<<std::endl;
}
I would do it in the following way:
void heating_widget::on_fullscreen_on_clicked()
{
foreach(QWidget *widget, QApplication::topLevelWidgets()) {
if (auto mainWindow = qobject_cast<SmartHome *>(widget)) {
mainWindow->setWindowState(Qt::WindowFullScreen);
}
}
}
The idea is finding your main window among application top level widgets and change its state. This code can be called from anywhere in your application regardless of the windows hierarchy.

missing ';' before '*' after instance declaration

I've encountered an error which I cannot seem to find a solution to anywhere else.
The error occurs when I'm trying to declare an instance of the "EncodeWindow" class.The compiler is giving errors C2143,C4430 and C2238. I am simply trying to give the "MainWindow" class an instance of "EncodeWindow".
File mainWindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QString>
#include <QLabel>
#include "Image.h"
#include "encodewindow.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
/*Check whether a given file path is valid*/
bool CheckFilePath(QString);
/*Sets UI widgets*/
void setOriginalImage_Label(const char*);
void setEncodedImage_Label(const char*);
void setDebug_TextBox(QString);
/*Saves all information about current encoding/decoding*/
void saveFile();
private slots:
void on_Encode_Button_clicked();
void on_Reset_Button_clicked();
void on_Save_Button_clicked();
void on_AddEncodeImage_Debug_Button_clicked();
void on_AddImage_Button_clicked();
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
EncodeWindow *CurrentEncodeWindow = new EncodeWindow; //ERROR HERE!! C2143
int fileNumber = 0;
};
#endif // MAINWINDOW_H
File encodeWindow.h:
#ifndef ENCODEWINDOW_H
#define ENCODEWINDOW_H
#include <QMainWindow>
#include "mainwindow.h"
namespace Ui {
class EncodeWindow;
}
class EncodeWindow : public QMainWindow
{
Q_OBJECT
public:
explicit EncodeWindow(QWidget *parent = 0);
~EncodeWindow();
/*Get filepaths from 'result' object (For access to filepaths without 'encode' Window)*/
const char* getOriginalFilePath();
const char* getEncodeFilePath();
const char* getSaveFilePath();
bool checkUI(const char*,const char*,const char*,bool*);
bool CheckFilePath(const char*);
std::string readInText(const char*);
private slots:
void on_RedChannel_CheckBox_clicked(bool);
void on_GreenChannel_CheckBox_clicked(bool);
void on_BlueChannel_CheckBox_clicked(bool);
void on_AlphaChannel_CheckBox_clicked(bool);
void on_BitDepth_Slider_sliderMoved(int);
void on_BitDepth_SpinBox_valueChanged(int);
void on_Encode_Button_clicked();
private:
Ui::EncodeWindow *ui;
Encoded result; //Enocoded object (child of Image class)
};
#endif // ENCODEWINDOW_H
Any help would be great. The code was done in Qt for an image steganography project.
Thanks.
You have circular includes. "mainwindow.h" includes "encodewindow.h" and "encodewindow.h" includes "mainwindow.h". The include guards stop the cycle, but the class definitions for whichever header is included first won't be complete in the second include file, which will result in your errors.
In the snippet above, there's nothing that I see in encodewindow.h that uses anything in mainwindow.h, so just remove the include of mainwindow.h from encodewindow.h.

Passing the parent pointer in Qt | ERROR: no member named in QObject

I am new to qt and I am trying to create a program where the MainWindow calls a QDialog to enter some data.
The problem is that the parent() at my QDialog does not have any access to the public methods of the MainWindow in our case the
void save_city(const City *city); //public method of MainWindow
The code is actually big so here is some of the code.Thanks.
mainwindow.h
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QMainWindow>
#include <QTextStream>
#include <QVector>
#include <QDebug>
#include <QFile>
#include "dialog_add_city.h"
#include "street.h"
#include "city.h"
#include "map.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
//main Window constructor
explicit MainWindow(QWidget *parent = 0);
//main Window deconstructor
~MainWindow();
/*utility function to save the city
*the function is public so that also QDialogs
*data saves can */
//////////////
//here is the public function
void save_city(const City *city);
private slots:
private:
Map mainMap;
Ui::MainWindow *ui;
QGraphicsView view;
QGraphicsScene scene;
};
dialog_add_city.h
#ifndef DIALOG_ADD_CITY_H
#define DIALOG_ADD_CITY_H
#include <QDialog>
#include "mainwindow.h"
#include "City.h"
namespace Ui {
class Dialog_Add_City;
}
class Dialog_Add_City : public QDialog
{
Q_OBJECT
public:
explicit Dialog_Add_City(QWidget *parent = 0);
~Dialog_Add_City();
private slots:
//Add New City Button clicked-Adds an new city to our city_locations.txt
void on_PushButton_Add_New_City_clicked();
private:
Ui::Dialog_Add_City *ui;
};
#endif // DIALOG_ADD_CITY_H
dialog_add_city.cpp
#include "dialog_add_city.h"
#include "ui_dialog_add_city.h"
Dialog_Add_City::Dialog_Add_City(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog_Add_City)
{
ui->setupUi(this);
}
Dialog_Add_City::~Dialog_Add_City()
{
delete ui;
}
void Dialog_Add_City::on_PushButton_Add_New_City_clicked()
{
City *city=new City(ui->lineEdit_cityName->text(),
ui->lineEdit_X_Ko->text().toDouble(),
ui->lineEdit_Y_Ko->text().toDouble());
qDebug() << ui->lineEdit_cityName->text()
<< ui->lineEdit_X_Ko->text()
<< ui->lineEdit_Y_Ko->text();
/////////////////////////////
//HERE IS THE PROBLEM
parent()->save_city(city);
}
Any other suggestions are welcomed!
The Problem is that parent() will return a pointer the parent object as QObject.
QObject Documentation
As dreschrjm pointed out you could try to cast the object via
MyWidget *myWidget = qobject_cast<MyWidget *>(obj);
from The Meta-Object System
Suggestion: Use Qt's signal/slot mechanism to avoid a backward reference to the parent.
Declare save_city as signal in Dialog_Add_City.
Declare save_city in MainWindow as slot
Connect both where the dialog is created:
e.g.
void MainWindow::show_add_city_dialog()
{
Dialog_Add_city dialog;
connect(&dialog, &Dialog_Add_city::save_city, this, &MainWindow::save_city);
dialog.exec();
}
Replace parent()->save_city(city); in Dialog_Add_City with emit save_city(city);
Ensure that the new city object doesn't leak, I think a better design would be to create the City object elsewhere not in the dialog.
so
emit save_city(ui->lineEdit_cityName->text(),
ui->lineEdit_X_Ko->text().toDouble(),
ui->lineEdit_Y_Ko->text().toDouble());
and the slot
void MainWindow::save_city(const QString &cityName, double x, double y)
{
City *city=new City(cityName, x, y);
// do some interresting things with city.
}

C++, Qt Signals & slots

I'm trying to understand Qt 4.8 signals and slots so I wrote some code to test it out for myself. Eventually, I want to be able to use a common source file in my project so that serial ports can be accessed from any source file in the project.
I set up a Qt GUI application and added a C++ class header and source file, shown below.
When I try to build, I get the error message when I try to emit the signal.
/home/user/QTProjects/stest1/stest1/ser.cpp:25: error: invalid use of 'this' in non-member function
I haven't even gotten to the stage of setting up the connections yet!
My newbie status is obvious, I'd be grateful for any help.
Thanks,
James
The following is the MainWindow.cpp:-
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "ser.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ser *j = new ser;
j->init();
connect (this, SIGNAL(click()), ser, SLOT(testprint()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
QByteArray ba1;
ba1.resize(6);
ba1[0]='H'; ba1[1]='e'; ba1[2]='l'; ba1[3]='l'; ba1[4]='o'; ba1[5]='\n';
this->printtext(ba1);
}
void MainWindow::printtext(const QByteArray &data)
{
ui->textEdit->insertPlainText(QString(data));
}
The following is the MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_pushButton_clicked();
void printtext(const QByteArray &data);
private:
Ui::MainWindow *ui;
signals:
// void click;
};
#endif // MAINWINDOW_H
The following is ser.cpp:-
#include "ser.h"
#include <QObject>
ser::ser(QObject *parent) :
QObject(parent)
{
}
void ser::init()
{
// connect(this->, SIGNAL(testsignal), MainWindow, SLOT(printtext(const QByteArray &data)));
}
void ser::testprint()
{
QByteArray ba1;
ba1.resize(8);
ba1[0]='S'; ba1[1]= '0'; ba1[2]= ' '; ba1[3]= 'l'; ba1[4]='o'; ba1[5]='n'; ba1[6]='g'; ba1[7]='\n';
emit this->testsignal(ba1);
}
The following is ser.h
#ifndef SER_H
#define SER_H
#include "mainwindow.h"
#include <QObject>
class ser : public QObject
{
Q_OBJECT
public:
explicit ser(QObject *parent = 0);
void init();
signals:
void testsignal(const QByteArray &data);
private slots:
void testprint();
public slots:
};
#endif // SER_H
Your method is implemented as void testprint() { ... }, but it should be void ser::testprint() { ... }. It's in your cpp file.
Also note that you don't need to use this-> to refer to class members. emit testsignal(ba1); will fork fine.
I think should be
connect (this, SIGNAL(click()), j, SLOT(testprint()));
instead of
connect (this, SIGNAL(click()), ser, SLOT(testprint()));
that apart, I can't spot where you connect testsignal
Great, that worked.
connect (this, SIGNAL(click()), j, SLOT(testprint()));
My next problem is connecting the signal in ser to the slot in the MainWindow. I used
connect(j,
SIGNAL(testsignal),
this,
SLOT(printtext(const QByteArray &data)));
It was inserted immediately after the other connect statement.
This does not print out the expected message "Slong". It also does not give me any error! What is the problem?
James

Application crashes when declaring QPushButton in header

Currently using the latest QT Creator and working on a small tutorial application. Was wanting to have a button that all the function could use and placed it in the header file:
#ifndef GAMEBOARD_H
#define GAMEBOARD_H
#include <QWidget>
#include <QtGui/QPushButton>
class QLCDNumber;
class CannonField;
class QPushButton;
class Gameboard : public QWidget
{
Q_OBJECT
public:
Gameboard(QWidget *parent = 0);
private:
QLCDNumber *remaning_shots;
QLCDNumber *hits;
CannonField *cannon_field;
QPushButton *shootb;
public slots:
void shoot();
void hit();
void missed();
void restart();
};
#endif // GAMEBOARD_H
gameboard.cpp:
#include "cannonfield.h"
#include "gameboard.h"
#include "lcdrange.h"
Gameboard::Gameboard(QWidget *parent)
: QWidget(parent) {
shootb = new QPushButton(tr("Shoot"));
And when I'm trying to run the application it just crashes before it even begins. I don't even have to use the button for anything, it crashes anyway. What am I doing wrong?
Or should I just use signals?
QPushButton *shootb = new QPushButton(tr("Shoot"));
connect(this, SIGNAL(disableShoot(bool)), shootb, SLOT(setDisabled(bool)));
And then I call it like this:
void Gameboard::missed() {
emit disableShoot(true);
}
Correct me if that's an ugly solution.