I created a class, whose base class was QObject, Now if I try to add a QTextBrowser in my code, I get the error as no matching function for call to QTextBrowser. I tried to compile the code by adding QWidget class but still I am unable to resolve the error. How can I resolve this.
MainWindow code
#include <QApplication>
#include "window.h"
#include "bbbserver.h"
int main(int argc, char **argv)
{
QApplication app (argc, argv);
bbbServer server;
Window window;
window.setStyleSheet("background-color: rgb(226, 226, 226);");
window.showFullScreen();
return app.exec();
}
Here is the code for window.h
#ifndef WINDOW_H
#define WINDOW_H
#include <QWidget>
class QPushButton;
class QTextBrowser;
class QProcess;
class QFile;
class Window : public QWidget
{
Q_OBJECT
public:
explicit Window(QWidget *parent = 0);
QTextBrowser *statusWindow;
private slots:
};
#endif // WINDOW_H
Here is the code for window.cpp
#include "window.h"
#include <QPushButton>
#include <QProcess>
#include <QTextBrowser>
#include <QDebug>
Window::Window(QWidget *parent) : QWidget(parent)
{
// Create and position the buttons on the main window
/*************** text browser *********************/
statusWindow = new QTextBrowser(this);
statusWindow->setMinimumSize(QSize(0,0));
statusWindow->setMaximumSize(QSize(10000,10000));
statusWindow->setGeometry(175, 50, 440, 420);
statusWindow->setStyleSheet("background-color: rgb(236, 236, 236);");
}
Here is the code for bbbserver.h file
#ifndef BBBSERVER_H
#define BBBSERVER_H
#include <QObject>
#include <QWidget>
#include <QDebug>
#include <QTcpServer>
#include <QTcpSocket>
class bbbServer : public QObject
{
Q_OBJECT
public:
explicit bbbServer(QObject *parent = 0);
signals:
public slots:
void newConnection();
private:
QTcpServer *server;
};
#endif // BBBSERVER_H
this is bbbserver.cpp file
#include "bbbserver.h"
bbbServer::bbbServer(QObject *parent):
QObject(parent)
{
/*************************** SERVER *********************************/
server = new QTcpServer(this);
connect(server, SIGNAL(newConnection()), this, SLOT(newConnection()));
if(!server->listen(QHostAddress::QHostAddress("192.168.0.1"), 5000))
{
qDebug() << "SERVER NOT STARTED";
}
else
{
qDebug() << "SERVER STARTED";
}
}
void bbbServer::newConnection()
{
QTcpSocket *socket= server->nextPendingConnection();
socket->write("Connection from 192.168.0.1 BBB\n");
socket->flush();
socket->waitForBytesWritten(30000);
socket->waitForReadyRead(30000);
qDebug() << socket->readAll();
`HERE I WANT TO ACCESS THE STATUS WINDOW(textbrowser statusWindow)`
}
And this is the full error, which is same as in screenshot.
bbbserver.cpp:8: error: no matching function for call to 'QTextBrowser::QTextBrowser(bbbServer* const)'
The parent parameter passed to the QTextBrowser constructor needs to be of type QWidget * whereas you're passing a QObject *. If you really need the bbbServer to be the parent object of the QTextBrowser then simply do...
infoSpace = new QTextBrowser;
infoSpace->QObject::setParent(this);
Note: The QObject:: qualifier is required because QWidget::setParent(QWidget *) effectively hides its base's QObject::setParent(QObject *) member meaning the latter won't take part in the normal lookup process.
Related
I would like to make some modifications of the main window from another file.
I created another ui file Form1Window (which open when a button is cliked in the MainWindow).
I want to call from the class Form1Window a function named test() of the MainWindow class
I succeed in calling function test() but I can't execute the whole content of the function (I can display a message but can't execute the part where I want to clear an edittext)
MainWindow.h
#include "form1window.h"
public slots:
void nettoyer();
private slots:
void openFrom1();
private:
Ui::MainWindow *ui;
From1Window *uiFrom1;
};
MainWindow.cpp
void MainWindow::openFrom1()
{
uiFrom1 = new From1Window(this);
uiFrom1->show();
}
void MainWindow::nettoyer(){
QMessageBox msgBox;
msgBox.setText("test");
msgBox.setIcon(QMessageBox::Information);
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.exec();
ui->auteur->clear();
//THIS LINE HAS NO EFFECT WHEN CALLED FROM THE OTHER CLASS
}
form1window.cpp
#include "mainwindow.h"
#include "ui_form1window.h"
void From1Window::on_supprimer_clicked()
{
MainWindow *a=new MainWindow ();
a->test();
close();
}
I've read about the role of the pointer of MainWindow class (C++ /Qt Proper way to access ui from another class in qt //Edited) and I've also tried connect()
Thank for your help
//THIS LINE HAS NO EFFECT WHEN CALLED FROM THE OTHER CLASS
this->ui->auteur->clear();
The line will never executed unless you dismiss QMessageBox. This is because you triggered QMessageBox with exec() function. This function has its own event queue and does not return until finishes. You may set QMessageBox as modal and display it with show() method. In that case QMessageBox will not block execution of the the flow.
This problem can also happen with QDialog(s) if you display them with exec().
I provide you a simple two window signal/slot example:
main.cpp
#include "mainwindow.h"
#include "form.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Form f;
f.show();
return a.exec();
}
form.h
#ifndef FORM_H
#define FORM_H
#include <QWidget>
#include <QPushButton>
class Form : public QWidget
{
Q_OBJECT
public:
explicit Form(QWidget *parent = 0);
~Form();
private:
QPushButton *pb;
};
#endif // FORM_H
form.cpp
#include "form.h"
#include "mainwindow.h"
#include <QDebug>
Form::Form(QWidget *parent) : QWidget(parent)
{
MainWindow *mw = new MainWindow();
pb = new QPushButton("clickME", this);
QObject::connect(pb, SIGNAL(clicked()), mw, SLOT(test()));
mw->show();
}
Form::~Form()
{
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QLabel>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void test();
private:
QLabel *l;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
l = new QLabel("test", this);
}
MainWindow::~MainWindow()
{
}
void MainWindow::test() {
qDebug() << "test called!" << endl;
l->setText("text changed");
}
This works for me.
output
I'm using Qt 5 on a Windows and building a GUI App with multiple QDialog classes. I am trying to connect a signal from a QDialog in a triggered action of the QMainWindow class after instances of both have been created. I have read the documentation on Qt here: http://doc.qt.io/qt-4.8/signalsandslots.html and here: https://wiki.qt.io/New_Signal_Slot_Syntax. I have also read through many questions on stackoverflow that have helped correct some of the initial errors I was getting, but haven't helped me solve this problem.
The error I keep getting is:
"expected primary-expression before ',' token"
I have tried both the old syntax for connect
connect(sender, SIGNAL (valueChanged(QString,QString)),
receiver, SLOT (updateValue(QString)) );
and the new syntax (which is shown in the .cpp file below)
connect(sender, &Sender::valueChanged,
receiver, &Receiver::updateValue );
The MainWindow is created in the main.cpp and the 2nd dialog is created on_action_someAction_triggered(), so I know that the instances I am referencing exist. Is there a better way for me to connect the SIGNAL and the SLOT?
Here is the code I am working with (minus the extra unrelated code).
mainwindow .h:
#include <QMainWindow>
#include "shipdia.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void loadSelectedShip(QString shipName);
private slots:
void on_actionNew_Ship_triggered();
private:
Ui::MainWindow *ui;
shipdia *sDialog;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTextStream>
#include <QObject>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_actionNew_Ship_triggered()
{
sDialog = new shipdia(this);
QObject::connect(&shipdia, //this is were I attempt to
&shipdia::sendShip, //connect the signal/slot
this,&MainWindow::loadSelectedShip); //but always get an error
sDialog ->show();
}
void MainWindow::loadSelectedShip(QString shipName)
{
... do something ... //this code works, but the signal is never received
}
qdialog.h
#ifndef SHIPDIA_H
#define SHIPDIA_H
#include "functions.h"
#include <QDialog>
namespace Ui {
class shipdia;
}
class shipdia : public QDialog
{
Q_OBJECT
public:
explicit shipdia(QWidget *parent = 0);
~shipdia();
private slots:
void on_pushButton_2_clicked();
signals:
void sendShip(QString shipName);
private:
Ui::shipdia *ui;
};
#endif // SHIPDIA_H
qdialog.cpp
#include "shipdia.h"
#include "ui_shipdia.h"
#include <QObject>
#include <QMessageBox>
#include <QTextStream>
#include <QDir>
shipdia::shipdia(QWidget *parent) :
QDialog(parent),
ui(new Ui::shipdia)
{
ui->setupUi(this);
}
shipdia::~shipdia()
{
delete ui;
}
void shipdia::sendSelectedShip(QString shipName)
{
emit sendShip(shipName); //I previously just emitted sendSelectedShip,
//but separating the function did not fix it.
}
void shipdia::on_pushButton_2_clicked()
{
//Code below functions up to next comment
QString shipName = ui->line_23->text();
shipName = QDir::currentPath() + "/shipFolder/" + shipName + ".txt";
QFile shipFile(shipName);
QStringList stringList;
if (shipFile.open(QIODevice::ReadOnly))
{
QTextStream in(&shipFile);
while(!in.atEnd())
{
QString line = in.readLine();
if(line.isNull())
break;
else
stringList.append(line);
}
shipFile.close();
}
//Code above functions ^
sendSelectedShip(shipName); //this line does not produce an error
}
I think, the code should be
sDialog = new shipdia(this);
QObject::connect(sDialog,
&shipdia::sendShip,this,&MainWindow::loadSelectedShip);
and it should be placed in the constructor of the MainWindow, right after ui->setupUi(this); and the on_actionNew_Ship_triggered() function should look like this:
void MainWindow::on_actionNew_Ship_triggered()
{
sDialog ->show();
}
In your original code, a new instance of shipdia will be created everytime the on_actionNew_Ship_triggered() is called. That should be avoided.
Hope this helps.
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.
}
I have 3 classes.
class with a mainwindow which comes from the designer(ui-file)
class wich will manage database stuff like inserts
controller class. I want to extend the whole thing to networkcommunication later.
My problem:
I want to connect a simple QPushButton ui->addbutton from the window class with a slot addEntry from the databaseclass, but I get this error :
ERROR: no matching function for call to
'generalControler::connect(QPushButton*, const char*, dbmanager*&,
const char*)'
mydb, SLOT(addEntry()));
//no difference with &mydb or *mydb
MainWindow(0x13f57988, name = "MainWindow") QPushButton(0x13f5f3e0, name = "addButton")
MainWindow(0x13f57988, name = "MainWindow") 0x13f5f3e0//<--?????
//<=Here u see the adresses printed with Qdebug(). top: mainwindowclass. bot: generalcontrolerclass
//why there is missing information after returning the adress of a 'ui->addButton' to another class? Is this maybe the problem?
main.cpp
#include <QApplication>
#include "generalcontroler.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
generalControler controler;
return a.exec();
}
generalcontroler.h
#ifndef GENERALCONTROLER_H
#define GENERALCONTROLER_H
#include <QApplication>
#include "mainwindow.h"
#include "dbmanager.h"
class generalControler : public QObject
{
Q_OBJECT
public:
generalControler();
};
#endif // GENERALCONTROLER_H
generalcontroler.cpp
#include "generalcontroler.h"
#include <QDebug>
generalControler::generalControler(){
MainWindow* window = new MainWindow;
window->show();
dbmanager* mydb= new dbmanager("path_to_my_database.db", window);
mydb->addEntry();
qDebug()<<window->getThis()<<window->getcloseButton();
connect(window->getaddButton(), SIGNAL(clicked()),
mydb, SLOT(addEntry()));
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QMessageBox>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
QPushButton* getaddButton();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow){
ui->setupUi(this);
}
QPushButton* MainWindow::getaddButton()
{
return ui->addButton;
}
dbmanager.h
#ifndef DBMANAGER_H
#define DBMANAGER_H
#include <QSqlDatabase>
#include <QDebug>
#include "mainwindow.h"
class dbmanager: public QObject{
Q_OBJECT
public:
dbmanager(const QString& path);
public slots:
void addEntry();
private:
QSqlDatabase mydatabase;
};
#endif // DBMANAGER_H
dbmanager.cpp
#include "dbmanager.h"
dbmanager::dbmanager(const QString& path)
{
mydatabase = QSqlDatabase::addDatabase("QSQLITE");
mydatabase.setDatabaseName(path);
if (!mydatabase.open())
{
qDebug() << "Error: connection fail";
}
else
{
qDebug() << "Database: connection ok";
}
}
void dbmanager::addEntry()
{
qDebug()<<"addEntry success";
}
I was searching for 6 hours but I never saw such an example with 2 classes, a controler and an ui-file. Could anyone help me?
The connect looks good to me. Try if #include <QPushButton> in generalcontroler.cpp helps. If the compiler knows about QPushButton only by forward-declaration, it doesn't know that it's a QObject and thus the connect() signatures (with QObject* in it) don't match.
I have a problem with my Qt code. I wanted to write an program which are taking a coordinates of point and then that point is drawing in point with that coordinates. My program doesn't have any errors or warnings when i built it but it's crashing at start(MainWindow doesn't show). This is my code:
main.cpp
#include < QApplication >
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow win;
win.show();
return app.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QWidget>
#include <QAction>
#include <QToolBar>
#include <QTextCodec>
#include <QObject>
#include <QDialog>
#include <QLineEdit>
#include <QPushButton>
#include <QString>
#include "addpoint.h"
class MainWindow: public QMainWindow
{
Q_OBJECT
private:
QToolBar *AddToolbar;
QAction *AddPointAction;
AddPoint *AddPointDialog;
QLineEdit *x;
public:
MainWindow();
void createToolbar();
void createActionAdd();
signals:
public slots:
void PointClicked();
void DialogAccepted();
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
MainWindow::MainWindow()
{
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
createActionAdd();
createToolbar();
connect(AddPointAction, SIGNAL(triggered(bool)), this, SLOT(PointClicked()));
connect(AddPointDialog, SIGNAL(accepted()), this, SLOT(DialogAccepted()));
setMinimumSize(480, 320);
}
/**/
void MainWindow::createToolbar()
{
AddToolbar = new QToolBar;
AddToolbar->addAction(AddPointAction);
addToolBar(AddToolbar);
}
/**/
void MainWindow::createActionAdd()
{
AddPointAction = new QAction("Add Road", this);
x = new QLineEdit(this);
x->setFixedSize(100, 30);
x->move(100, 100);
}
/**/
void MainWindow::PointClicked()
{
AddPointDialog = new AddPoint(this);
AddPointDialog->setModal(true);
AddPointDialog->exec();
}
/**/
void MainWindow::DialogAccepted()
{
x->setText("abc");
}
addpoint.h
#ifndef ADDPOINT_H
#define ADDPOINT_H
#include <QWidget>
#include <QTextCodec>
#include <QDialog>
#include <QObject>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QString>
class AddPoint : public QDialog
{
Q_OBJECT
private:
QLabel *XpointL;
QLineEdit *XPoint;
QPushButton *OKButton;
public:
AddPoint(QWidget *parent);
void createButton();
signals:
public slots:
};
#endif // ADDPOINT_H
addpoint.cpp
#include "addpoint.h"
AddPoint::AddPoint(QWidget *parent) :QDialog(parent)
{
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
createButton();
connect(OKButton, SIGNAL(clicked(bool)), this, SLOT(accept()));
setMinimumSize(320, 240);
}
/**/
void AddPoint::createButton()
{
XpointL = new QLabel("Point X:", this);
XpointL->setFixedSize(100, 30);
XpointL->move(10, 10);
XPoint = new QLineEdit(this);
XPoint->setFixedSize(180, 30);
XPoint->move(120, 10);
OKButton = new QPushButton("OK", this);
OKButton->setFixedSize(100, 30);
OKButton->move(200, 150);
}
After running the program i see in aplication output lap:
"The program has unexpectedly finished."
"C:\QT\build-xxx-Desktop_Qt_5_4_2_MSVC2013_64bit-Debug\debug\xx.exe crashed"
I note that i made some experiments with this code and i saw that i have problem with signal accpeted() at mainwindow.cpp. I don't know what can i do with this problem. I hope you will help me.
AddPointDialog is uninitialized pointer, it does not yet point to valid AddPoint in MainWindow's constructor. You cannot call connect on that. Its value will change later, when you do AddPointDialog = new AddPoint(this); and only then will you be able to call connect.
Simply, you should move your connect call to void MainWindow::PointClicked() after you've initialized your pointer. I'd also make AddPointDialog local to that function and store it on the stack (you don't use it anywhere else and you're leaking memory).
The code would be:
void MainWindow::PointClicked()
{
AddPoint AddPointDialog(this);
AddPointDialog.setModal(true);
connect(&AddPointDialog, SIGNAL(accepted()), this, SLOT(DialogAccepted()));
AddPointDialog.exec();
}