Problems with function QTimer::singleShot - qt

I am trying to record sound by QAudioInput. According to the doc in this website QAudioInput. But when I ran, it exported an empty-raw file. After checking, It seems like the function QTimer::singleShot didn't working ( I added statement qWarning << "Done" in void stopRecording() and It didn't display "Done" so I thought it had some mistake in QTimer::singleShot function ).
This is my code used to check function QTimer::singleShot
----Check.pro----
QT += core
QT -= gui
TARGET = Check
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
HEADERS += test.h
-----test.h------
#ifndef TEST_H
#define TEST_H
#include <QCoreApplication>
#include <QTimer>
#include <iostream>
#include <QObject>
#include <test.h>
#include <QDebug>
using namespace std;
class Object: public QObject {
Q_OBJECT
private slots:
void func() { cout << "Hello"; }
};
#endif // TEST_H
----main.cpp----
#include <QCoreApplication>
#include <QTimer>
#include <iostream>
#include <QObject>
#include <test.h>
#include <QDebug>
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Object *o = new Object;
QTimer::singleShot(10000, o, SLOT(func()));
return 0;
}
And this code doesn't working, too. Can anyone explain me? I am newbie at Qt-programming.

Your program exits right after it's set the timer - it has no time to fire.
For the timer to work, you need an event loop running. Without the event loop, no events get processed.
Change the last line of your main to
return a.exec();
Also change your test slot by adding << std::endl or flush std::cout otherwise you might see no output on the console.
Your program should then work as expected (except it won't ever finish since nothing will cause the event loop to stop - just interrupt it).

Related

Doctest and qapplication

I must integrate doctest lib to a QT core project (Qt5 exactly).
At a point, I need a qcoreapplication to run event loop.
But when I try implement my doctest main with a qcoreapplication it looks doctest context and qcoreapplication parasite themself.
Do there are some workarounds? like qeventloop without qcoreapplication? other ways?
Did someone have already encountered this kind of case with other test libs?
Thanks for answers ;)
Edit 1:
For confidentiality reason i can't share actual base code. But i have same issue with basic code.
At my actual point i fall in an infinite loop at the end of execution.
I may just miss something on QCoreApplication execution end.
#define DOCTEST_CONFIG_IMPLEMENT
#include <QDebug>
#include <QObject>
#include <QSignalSpy>
#include <QApplication>
#include <QEventLoop>
#include "../../Core/external/doctest/doctest.h"
TEST_CASE("Basic class") {
SUBCASE("2*2") {
qDebug()<<"2*2";
CHECK_EQ(2*2, 4);
}
SUBCASE("1+1") {
qDebug()<<"1+1";
CHECK_EQ(1+1, 2);
}
SUBCASE("Termination") {
qDebug()<<"End!!";
QCoreApplication::instance()->quit();
}
}
int main(int argc, char** argv) {
doctest::Context context;
// defaults
context.setOption("abort-after", 5);
context.setOption("order-by", "name");
QCoreApplication app (argc, argv);
context.applyCommandLine(argc, argv);
context.setOption("no-breaks", true);
int res = context.run();
if(context.shouldExit())
return res;
int client_stuff_return_code = 0;
return res + client_stuff_return_code + app.exec(); // the result from doctest is propagated here as well
}

How to implement reactive programming rx in Qt creator?

I'm new to QT please help me with how to implement reactive programming in Qt
If you want to use QML, then reactive programming will be very easy. Item properties in QML are naturally of reactive nature (just write a "java script" expression which uses other properties and the reactive connection will be established). Since Qt6, property bindings are available also in C++, see https://www.youtube.com/watch?v=pN0pRBUqrrc
Moreover, you can use property bindings by KDAB https://www.kdab.com/signals-slots-properties-bindings/
There is a project called rqxt that you may want to look into. Check out the samples folder.
For example, this is a sample for signals and slots:
#include <QApplication>
#include <QDebug>
#include <QKeyEvent>
#include <QLineEdit>
#include <QPushButton>
#include <QVBoxLayout>
#include <QWidget>
#include <rxqt.hpp>
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
auto widget = std::unique_ptr<QWidget>(new QWidget());
auto layout = new QVBoxLayout;
widget->setLayout(layout);
{
auto e0 = new QLineEdit("Edit here");
auto e1 = new QLineEdit;
e1->setEnabled(false);
layout->addWidget(e0);
layout->addWidget(e1);
rxqt::from_signal(e0, &QLineEdit::textChanged)
.map([](const QString& s) { return "[[[" + s + "]]]"; })
.subscribe([e1](const QString& s) { e1->setText(s); });
rxqt::from_event(e0, QEvent::KeyPress)
.subscribe([](const QEvent* e) {
auto ke = static_cast<const QKeyEvent*>(e);
qDebug() << ke->key();
});
}
widget->show();
return a.exec();
}

Is there a way to return current viewed page in QPrintPreviewDialog?

I know it is possible with QPrintPreviewWidget via currentPage() function, but is there a way to return current page in QPrintPreviewDialog? Since I like the default QPrintPreviewDialog's interface, and I don't feel confident enough to rebuild it myself, I would like to use QPrintPreviewDialog.
QPrintPreviewDialog is a QDialog that has a QPrintPreviewWidget as internal elements, so using findChild you can obtain that object.
#include <QApplication>
#include <QPrintPreviewDialog>
#include <QPrintPreviewWidget>
#include <QPrinter>
#include <QTimer>
#include <QTextCursor>
#include <QTextDocument>
#include <QDebug>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QPrintPreviewDialog previewDialog;
QObject::connect(&previewDialog, &QPrintPreviewDialog::paintRequested, &previewDialog, [&previewDialog](QPrinter *printer){
QTextDocument document;
QTextCursor cursor(&document);
QTextBlockFormat blockFormat;
for(int i=0; i < 10; i++){
cursor.insertBlock(blockFormat);
cursor.insertHtml(QString("<h1>This is the %1 page</h1>").arg(i+1));
blockFormat.setPageBreakPolicy(QTextFormat::PageBreak_AlwaysBefore);
}
document.print(printer);
if(QPrintPreviewWidget *previewWidget = previewDialog.findChild<QPrintPreviewWidget *>()){
qDebug() << previewWidget->currentPage();
// change page
QTimer::singleShot(100, previewWidget, [previewWidget](){
previewWidget->setCurrentPage(2);
});
}
});
previewDialog.exec();
}

QWebEngineView RAM problems (all memory is taken by it in a minute)

Hello so i have a BIG problem with QWebViewEngine so far. Because all i did was created a QWebEngineView and said .load(QUrl("http://google.com")) and then .showFullScreen(). On start the application took about 130MB of RAM. When i pressed feel lucky on google and the page loaded suddenly the RAM started to climbing by 200mb each second and it stopped when there was no more free RAM.
Anyone had this problem, or experience with QWebEngineView.
I know its Chormium, but it seems to me as if it wasnt working correctly.
Any suggestions how to correct this?
Edited 14/08/2015 14:12
here is the code(note that most of it is commented):
#include "mainwindow.h"
#include <QtWebEngineWidgets/QtWebEngineWidgets>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QScopedPointer>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
view = new QWebEngineView();
manager = new QNetworkAccessManager();
settings = new QSettings(":/settings.ini",QSettings::IniFormat);
// connect(view,SIGNAL(loadFinished(bool)),this,SLOT(CheckPage()));
// connect(manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(connection(QNetworkReply*)));
// errorOpen=false;
settings->beginGroup("URL");
myUrl = settings->value("curUrl").toString();
settings->endGroup();
// view->load(myUrl);
view->load(QUrl("http://google.com"));
view->showFullScreen();
settings->deleteLater();
}
MainWindow::~MainWindow()
{
// delete view;
// delete manager;
}
I can't reproduce under qt5-mac #5.4.2_1 from macports on OS X 10.9:
//main.cpp
#include <QtWebEngineWidgets>
#include <QApplication>
int main(int argc, char ** argv)
{
QApplication a(argc, argv);
QWebEngineView view;
view.load(QUrl("http://google.com"));
view.showFullScreen();
return a.exec();
}
# chromium-32008560.pro
QT += webenginewidgets
TARGET = chromium-32008560
TEMPLATE = app
SOURCES += main.cpp

use QCamera in Qt console application

I want to use the camera in a headless (console) qt application (at least for unit testing).
But I facing a problem with Qt. As soon I use my code in a console application, the camera won't work - the readyForCaptureChanged event of QCameraImageCapture will not be called.
If I use exactly the same code in a gui application, the event gets triggered and I can capture images.
The common code I use is that:
camera = new QCamera(cameras.at(config->cameraNumber()));
imageCapture = new QCameraImageCapture(camera);
connect(imageCapture, SIGNAL(readyForCaptureChanged(bool)), this, SLOT(readyForCapture(bool)));
camera->start(); // to start the viewfinder
// ——
void ImageCapture::readyForCapture(bool b) {
qDebug() << "ready for capture "<<b;
}
when I call this code in the gui application directly in the constructor of my MainWindow, it works (event will be triggered).
When I call this code in my qt console application, it does not work (event will not be triggered).
Can anybody help me? Thanks
** UPDATE 29. August - full code **
Console Application:
main.cpp
#include <QCoreApplication>
#include <QTest>
#include <QTimer>
#include <QDebug>
#include <runoneventloop.h>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
RunOnEventLoop * run = new RunOnEventLoop(&a);
QTimer::singleShot(0, run, SLOT(run()));
return a.exec();
}
RunOnEventLoop.cpp
#include "runoneventloop.h"
RunOnEventLoop::RunOnEventLoop(QObject *parent) :
QObject(parent)
{
}
void RunOnEventLoop::run() {
qDebug() << "hier run";
camera = new QCamera(0);
imageCapture = new QCameraImageCapture(camera);
connect(imageCapture, SIGNAL(readyForCaptureChanged(bool)), this, SLOT(readyForCapture(bool)));
camera->start(); // to start the viewfinder
}
void RunOnEventLoop::readyForCapture(bool b) {
qDebug() << "ready of capture "<<b;
}
RunOnEventLoop.h
#ifndef RUNONEVENTLOOP_H
#define RUNONEVENTLOOP_H
#include <QObject>
#include <QDebug>
#include <QCamera>
#include <QCameraImageCapture>
class RunOnEventLoop : public QObject
{
Q_OBJECT
public:
explicit RunOnEventLoop(QObject *parent = 0);
private:
QCamera* camera;
QCameraImageCapture* imageCapture;
signals:
public slots:
void run();
void readyForCapture(bool);
};
#endif // RUNONEVENTLOOP_H
GUI Application
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
qDebug() << "hier";
camera = new QCamera(0);
imageCapture = new QCameraImageCapture(camera);
connect(imageCapture, SIGNAL(readyForCaptureChanged(bool)), this, SLOT(readyForCapture(bool)));
camera->start(); // to start the viewfinder
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::readyForCapture(bool b) {
qDebug() << "ready of capture "<<b;
}
again, it's the same code. Console App does not call the readyForCapture method, while the gui application calls it.
you can download the archive here: DOWNLOAD
If would be nice if you could provide something more of your console-based Qt application... the code you presented, how is it called by your main code?
Anyway, just guessing, if no events are raised at all maybe it is because you are not running any event loop... are you sure that your code at some point call exec() on your QCoreApplication object? Are you sure that the owner of the object from which you call connect() is the thread of QCoreApplication?

Resources