I wrote a program to control device with serial port. It works fine but I'd like to seperate the class which would operate serial ports. I also want to have acess to buttons, comboboxes, etc. from this class.
Here are most important parts of code:
Serialsettings header:
#ifndef SERIALSETTINGS_H
#define SERIALSETTINGS_H
#include <QMainWindow>
#include <QSerialPort>
#include "mainwindow.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class SerialSettings : public MainWindow
{
Q_OBJECT
public:
struct Settings
{
QString name;
qint32 baudRate;
QString stringBaudRate;
QSerialPort::DataBits dataBits;
QString stringDataBits;
QSerialPort::Parity parity;
QString stringParity;
QSerialPort::StopBits stopBits;
QString stringStopBits;
QSerialPort::FlowControl flowControl;
QString stringFlowControl;
};
explicit SerialSettings(QWidget *parent = nullptr);
~SerialSettings();
Settings settings() const;
signals:
private:
void fillPortsInfo();
void fillPortsParameters();
void updateSettings();
private:
Settings m_currentSettings;
};
#endif
Serialsettings source:
#include "serialsettings.h"
#include <QSerialPort>
#include <QSerialPortInfo>
#include "mainwindow.h"
#include "ui_mainwindow.h"
SerialSettings::SerialSettings(QWidget *parent)
: MainWindow(parent)
{
//some functions
}
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QSerialPort>
//#include "serialsettings.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class SerialSettings;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
Ui::MainWindow *ui;
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
// some code
};
#endif
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "serialsettings.h"
#include <QSerialPortInfo>
#include <QSerialPort>
#include <QString>
#include <QDebug>
#include <QTimer>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//some code
};
MainWindow::~MainWindow()
{
delete ui;
}
I don't have any error at this moment but it finishes with: The program has unexpectedly finished.
Could you help me please with this problem?
Related
I am trying to download a txt file from a url in QT but i can't seem to make it work.
I am following this guide https://wiki.qt.io/Download_Data_from_URL. I implemented the filedownloader class exactly like it's made in the guide, but when i try to use it like specified in the guide I cannot make it work. I created a slot to be called when the download is finished, but if i try to call the downloader inside like the guide it says it is an undeclared identifier.
Does anyone know how to correctly implement this code?
this is the .cpp of my code
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "mainwindow.h"
#include <QStringList>
#include <QCoreApplication>
#include <QFile>
#include <QFileInfo>
#include <QList>
#include <QtNetwork/QNetworkReply>
#include <QStringList>
#include <QTimer>
#include <QUrl>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest>
#include <filedownloader.h>
#include <iostream>
#include <QObject>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QUrl emiurl( "url of my file");
// call to the downloader class.In the guide it's made differently, but it doesn't work
FileDownloader emiload(emiurl,this);
//this connect links the end of the download with the textwriter slot
QObject::connect(&emiload, SIGNAL (downloaded()), this, SLOT (textwriter()));
}
>MainWindow::~MainWindow()
{
delete ui;
}
//slot needed to create the txt file from the downloaded one
void MainWindow::textwriter()
{
QByteArray emibyte;
emibyte=emiload->downloadedData(); //this line gives me error
QFile emifile("emi.txt");
emifile.open(QIODevice::WriteOnly);
std::cout << emibyte.size() << std::endl;
QDataStream out(&emifile);
out << emibyte;
std::cout << emifile.size() << std::endl;
}
Now here's the .h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "filedownloader.h"
#include <QMainWindow>
#include <QtNetwork/QNetworkAccessManager>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
private slots:
void textwriter();
};
#endif // MAINWINDOW_H
To make the undeclared identifier go away and successfully compile, you need to add FileDownloader to the class' declaration. This way, it will be known throughout the class.
I chose to go with the approach that's usual in Qt, to declare a pointer to FileDownloader.
#pragma once // <--- this is supported by virtually any compiler today
#include <QMainWindow>
#include <QtNetwork/QNetworkAccessManager>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class FileDownloader; // <-- forward declaration is enough, but you can also #include "filedownloader.h"
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget* parent = nullptr);
~MainWindow();
private:
Ui::MainWindow* ui = nullptr;
FileDownloader* emiload = nullptr; // <--- the important line!
private slots:
void textwriter();
};
And then instantiate and call emiload in the constructor:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// create an instance of FileDownloader with "new".
emiload = new FileDownloader(QUrl("url of my file"), this);
// using member pointer connection available since Qt5
connect(emiload, &FileDownloader::downloaded, this, &MainWindow::textwriter);
}
I'm using the Qt application. When I'm trying to call the subclass from the connect, subclass (doWork) function it's not getting called. please refer to my sample code and help me to solve the issue.
I'm using the Qt application. When I'm trying to call the subclass from the connect, subclass (doWork) function it's not getting called. please refer to my sample code and help me to solve the issue.
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "QMainWindow"
#include <QThread>
#include "Worker.h"
namespace Ui { class MainWindow; }
class MainWindow: public QMainWindow {
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow(); private:
Ui::MainWindow *ui;
QThread *thread;
Worker *worker;
signals:
void requestUpdate(int initial);
};
#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);
thread = new QThread();
worker = new Worker();
worker->moveToThread(thread);
connect(this, SIGNAL(requestUpdate(int)), worker, SLOT(doWork(int)));
int enc = 10;
emit requestUpdate(enc);
}
MainWindow::~MainWindow()
{
delete thread;
delete worker;
delete UI;
}
Worker.h
#ifndef WORKER_H
#define WORKER_H
#include<QObject>
class Worker: public QObject
{
Q_OBJECT
signals:
void workRequested();
public slots:
void doWork(int initial);
};
#endif // WORKER_H
Worker.cpp
#include "Worker.h"
#include <QTimer>
#include <QEventLoop>
#include <QThread>
#include <QDebug>
Worker::Worker(QObject *parent) :
QObject(parent)
{
_working =false;
_abort = false;
}
void Worker::doWork(int initial)
{
qDebug() << "initial" << endl;
}
Thanks & Regards,
Haji
Objective
I've been trying to send data from Arduino to my computer via COM Port and I want to see the values on Debugger Console.
Problem
I can't get and print values although I was able to do them with the same code structure, previously.
QObject::connect: No such slot MainWindow::serialData()
QObject::connect: (receiver name: 'MainWindow')
mainwindow.h file
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QDebug>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
void serialData();
private:
Ui::MainWindow *ui;
QSerialPort *arduino;
QSerialPortInfo port;
};
#endif // MAINWINDOW_H
mainwindow.cpp file
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QDebug>
#include <string>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
/*List available ports with a combo box*/
Q_FOREACH(port, QSerialPortInfo::availablePorts())
{
ui->comboBox->addItem(port.portName());
}
arduino = new QSerialPort(this);
arduino->setPortName("COM10");
arduino->open(QIODevice::ReadOnly);
arduino->setBaudRate(QSerialPort::Baud9600);
arduino->setDataBits(QSerialPort::Data8);
arduino->setParity(QSerialPort::NoParity);
arduino->setStopBits(QSerialPort::OneStop);
arduino->setFlowControl(QSerialPort::NoFlowControl);
connect(arduino, SIGNAL(readyRead()), this, SLOT(serialData()));
}
MainWindow::~MainWindow()
{
delete ui;
arduino->close();
}
void MainWindow::serialData()
{
QByteArray data;
data = arduino->readAll();
qDebug()<<data;
}
Thanks in advance.
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.
The compiler wont let me instanciate fileprocessor *p; in mainwindow.ccp but I am able to in any other class.
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{
fileprocessor *p;
ui->setupUi(this);
QObject::connect(ui->Open, SIGNAL(clicked()),
this,SLOT(on_action_Open_triggered()));
}
MainWindow::~MainWindow()
{
delete ui;
}
-mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QFile>
#include <QFileDialog>
#include <QTextStream>
#include <QStandardItemModel>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
I am given fileprocessor:undeclared identifier and p: undeclared identifier
#user4217633: Include fileprocessor.h in the mainwindow.cpp, not in mainwindow.h. There you need a forward declaration:
class fileprocessor; // Just this
You already have such a forward declaration, in fact:
namespace Ui {
class MainWindow;
}