QtWebKit c++ connect: cannot convert QWebView to SOCKET - c++

Recently started doing some programming for Windows and I simply can't get my program to work. I am trying to achieve an environment in which I mainly can use HTML for the frontend and control the backend with Javascript. On Linux I've managed to add functions and stuff to the "JavaScriptCore" but Windows haven't been to kind with me.
Currently I'm trying to catch the URL change event, allowing for special URLs to execute commands, however I get the following error:
error: C2664: 'connect' : cannot convert parameter 1 from 'QWebView *' to 'SOCKET'
There is no context in which this conversion is possible
I didn't manage to find a single search result concerning "QWebView to SOCKET" so I have no clue what to do but to ask you guys.
Here is my code. I'm not too good with programming to please be gentle ;)
#include <QtGui>
#include <QtWebKit>
#include <QApplication>
#include <QWebView>
#include <iostream>
using namespace std;
void test()
{
cout << "Hello world";
}
int main(int argc, char** argv) {
QApplication app(argc, argv);
QWebView view;
view.setWindowFlags(Qt::CustomizeWindowHint);
view.setWindowFlags(Qt::FramelessWindowHint);
view.setFixedSize(1000,600);
view.setStyleSheet("background:transparent;");
view.setAttribute(Qt::WA_TranslucentBackground);
view.setUrl(QUrl("http://google.com"));
view.setWindowTitle("test v0.1");
connect(view, SIGNAL(urlChanged(QUrl)), SLOT(test()));
view.show();
return app.exec();
}

Try this instead:
QObject::connect(&view, &QWebView::urlChanged, test);
You are using the old connection syntax which works only with QObjects and slots, test is not a slot and it is not a function of a QObject derived class, it is a free funciton, so you have to use the new syntax, available since Qt 5.
When you are not inside a QObject you don't have access to connect(), that is why my example uses the QObject namespace to invoke it in main(). In your case as DNT noted it is just some other function that happens to be named "connect".
Another mistake you made is you passed the view, but connect() works with pointers, so you have to use the & operator to get a pointer to the view.

Related

Modbusclient as a console application, "Stuck in Connectingstate loop"

I'm trying hardly to convert the Modbusmaster example (qt example) which is a widget application to a console application. I wanted to build a connection between a local slave and my master. The problem I'm facing is that my code is changing its state to “Connecting state” ,gets stuck and doesn't want to build a connection. That's why, I recon that the Modbus library is limited and it's only compatible with the widget form.
Could someone tell me if my guesses are right.
down below you will find my code:
#include <QCoreApplication>
#include <QDebug>
#include <QModbusDataUnit>
#include<iostream>
#include <QTimer>// this bib was add to the 50ms Loop check
#include <string>
#include <QString>
#include <QThread>
#include <QModbusTcpClient>
#include <QModbusDataUnit>
#include <QUrl>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Mainmodbus T ;
T.modbusDevice = new QModbusTcpClient();
if (!T.modbusDevice) qDebug()<<"error 1";
if (T.modbusDevice->state() != QModbusDevice::ConnectedState) {
T.modbusDevice->setConnectionParameter(QModbusDevice::NetworkAddressParameter, "127.0.0.1");
T.modbusDevice->setConnectionParameter(QModbusDevice::NetworkPortParameter, 502);
T.modbusDevice->connectDevice();
while(true){
qDebug()<<T.modbusDevice->state();}
}
return a.exec();
}
I can be wrong but I think the QModbusDevice::ConnectingState you see actually means your server is up and running and waiting for a connection.
I guess what you are missing is opening a connection from a Modbus client. You can do that with different tools, I guess running the client example
would be a good idea. Otherwise, you can use QModMaster or any other tool you like.
Once you open the connection from the client the state on your server should change to QModbusDevice::ConnectedState.
Be aware that the server you built is just an empty shell, there is no register map defined so if you query the contents of any register from the client you will get an error.
At the very minimum, you should at least define a map with some default values or get them from command-line options. To do that you need to look at the server example a bit more carefully.
First you need to define the register map with something like this:
QModbusDataUnitMap reg;
reg.insert(QModbusDataUnit::Coils, { QModbusDataUnit::Coils, 0, 10 });
reg.insert(QModbusDataUnit::DiscreteInputs, { QModbusDataUnit::DiscreteInputs, 0, 10 });
reg.insert(QModbusDataUnit::InputRegisters, { QModbusDataUnit::InputRegisters, 0, 10 });
reg.insert(QModbusDataUnit::HoldingRegisters, { QModbusDataUnit::HoldingRegisters, 0, 10 });
modbusDevice->setMap(reg);
setupDeviceData();
And then for the setupDeviceData(); you can copy the function in the example but instead of taking the data from the widget, you will have to load default values or something from the command line.
In answer to your question: no, there should be no limitation and you should be able to run the server from the command line. I wonder why somebody on his/her right mind would want to do that when you have excellent alternatives like libmodbus. But honestly, I won't miss much sleep wondering.

Using QPainter with QCoreApplication

We have an application (QCoreApplication) that takes some images as input, does something to them, and exports them again. We now need to add some text to the images, and tried to do this with the QPainter class. It all worked well when using it in one of our other apps (using QApplication), but not in our main QCoreApplication app.
Here is the code:
void drawTextOnImage(QImage* image, const QString& text, const QFont& font)
{
QPainter p;
if (!p.begin(image)) return;
p.setFont(font);
p.drawText(image->rect(), Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, text);
p.end();
}
The application crashes on the drawText line.
Any ideas?
It is a very simple text, so suggestions without using Qt will also be appreaciated.
When using classes from "Qt Gui" like QPainter, you are supposed to use a QGuiApplication, not a QCoreApplication.
You might get lucky and be able to make some GUI stuff works while using only a QCoreApplication. But as you have discovered, it makes your application very brittle. Some classes like QPixmap will print an error message, but others will just crash.
The same is applicable with "Qt Widget": if you use a widget related class, you must use a QApplication.
Note that since QApplication inherits QGuiApplication, if you have a QApplication you can use "Qt Gui".
In case you need to run a non-GUI application on something without a windowing system, you need, aside from creating an instance of QGuiApplication, to also choose an appropriate Qt platform.
For me, offscreen platform worked fine. I was generating images with textual elements and saving them to files on a headless Raspberry Pi. My code then was like the example below. Note that setenv is a POSIX function and may need a replacement on Windows, though I'm not sure whether windowless Windows is a thing at all.
#include <stdlib.h>
#include <QImage>
#include <QPainter>
#include <QGuiApplication>
int main(int argc, char** argv)
{
setenv("QT_QPA_PLATFORM","offscreen",1);
QGuiApplication app(argc,argv);
QImage img(128,128, QImage::Format_RGB888);
img.fill(Qt::white);
QPainter p(&img);
p.drawText(QPoint(0,64), "Works!");
img.save("/tmp/test.png");
}

Qt must construct QApplication before a QWidget

Qt recently started crashing without having a reason for it. The most recent one which is currently grinding my nerves down to a pulp is crashing due to starting another form programmatically. The "must construct QApplication before a QWidget" apparently is a common issue with Qt 5.7.* versions and the solutions I have found so far in StackOverflow haven't helped me.
This is a screenshot of the error message I got after the application crashed:
And here is the bit of the code that I remove which allows me to restart the application without any noticeable problems:
#include "operations.h"
Operations o;
void mainWindow::on_thisButton_clicked()
{
o.show();
this->hide();
}
----
The main.cpp as requested :)
#include "mainWindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
mainWindow w;
w.show();
return a.exec();
}
Try this:
#include "operations.h"
void mainWindow::on_thisButton_clicked()
{
Operations *o = new Operations();
o->show();
this->hide();
}
You might want to declare Operations *o as a member of mainWindow and initialize it the the constructor if you don't want to create a new one each time the button is clicked.
"must construct QApplication before a QWidget" is the standard type of error you get with Qt applications, when linking something incompatible ( like mixing debug/release ).
So in most use cases this indicates a build problem and has nothing to with the code itself.
Don't create Operations object as a global variable, as it will be created as a static BEFORE running main(), therefore the error message is simply correct and relevant. This is a C++ issue, not a Qt one.
All other suggestions work because you now create the object at the right time, after the QApplication...
Okay, I have managed to find a solution, however, it is borderline idiotic as it does not make any sense why it does not work in its prior state. Technically, all you need to do in order to have the error not appearing is to stick the declaration of the form class you are referring within the function itself(ie Operations o;).
Here is the code solution itself:
#include "operations.h"
void mainWindow::on_thisButton_clicked()
{
Operations o;
o.show();
this->hide();
}
Bare in mind that this is not the end of all problems as I currently have the problem of the new form closing in the very same 1 second period it opens. If I manage to solve it I will update my solution.

Application freeze in 3rd party library call

I am working on a c++ measurement software which uses a 3rd party API for the interface all sensors are connected to. This API is not open source and no debug library is available.
In some occasions, the software freezes when starting to read a value from the interface. While I could not determine what criterions cause the problem and why it only happens sometimes so far, I'd like to intercept the freezing and implement some error handling, which would also allow me to better debug the issue.
In my code, I simply have a call
BOOL result = false;
result = pciadioAIStartConversion(board_index, channel_nr, range);
where, if the error occurs, pciadioAIStartConversion never returns. I am looking for some simple functionality to keep the software running and return if the call takes to long.
I am using the Qt framework (4.8.6) so a possible solution would be using the event system and a QTimer, but therefore the call would need its own thread if I'm not mistaken and that seems like overkill to me.
piezol is right You need a separate thread which can be quite a mess but the good news is that Qt thread framework (which is called QtConcurrent) is really helpful.
Here is an example for running a standard function in a separate thread mantaining control of it.
#include <QDebug>
#include <QThread>
#include <QString>
#include <qtconcurrentrun.h>
#include <QApplication>
using namespace QtConcurrent;
void hello(QString name)
{
qDebug() << "Hello" << name << "from" << QThread::currentThread();
}
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QFuture<void> f1 = run(hello, QString("Alice"));
QFuture<void> f2 = run(hello, QString("Bob"));
f1.waitForFinished();
f2.waitForFinished();
}

C++ QNetworkAccessManager (Qt) in conjunction with openGL

I'm really nooby with C++ (as my previous posts mention), however my friend suggested I work with QNetworkAccessManager if I want to send a HTTP GET request to send information.
I am currently working with openGL-es and want to do the following two lines of code to send the get request:
QNetworkAccessManager* netMan = new QNetworkAccessManager(this);
netMan->get(QNetworkRequest(QUrl("something/?userID=1")));
However, it does not like the "this" because it is in the main() method and it does not reference a QObject (I'm guessing QApplication). When I get rid of the "this" my application builds, but just never loads (I put a "printf(1)" at the top which doesn't even run).
Any suggestions or alternatives on how to fix this? Thanks in advance.
-James
The parameter in the QNetworkAccessManager constructor is only needed to specify a QObject based parent which will be responsible for cleaning up (deleting) your object later and isn't necessary if you plan to call delete on it yourself.
I'm not quite sure what you are referring to by "never loads" or where you put a printf but in order to get anything back, you need to actually keep the QNetworkReply pointer that is returned by the call to get().
And to get anything from that, you need an event loop running. If your application is console only (no GUI), you can use a QCoreApplication object.
Try this minimal code:
#include <QCoreApplication>
#include <QNetworkAccessManager>
#include <QUrl>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QNetworkAccessManager *netMan = new QNetworkAccessManager();
QNetworkReply *reply = netMan->get(QNetworkRequest(QUrl("http://google.com")));
a.connect(reply, SIGNAL(finished()), SLOT(quit()));
a.exec();
qDebug() << reply->readAll();
delete netMan;
}