how to notify that the maxlength is overflowing - c++

Is there a way to connect a signal before executing a default handler? I'm looking for a way to execute my function prior to QLineEdit::textChanged signal to execute notification about maximum length limit.
GTK+ has connect_before(), connect() and connect_after(). Is there something similar in Qt?

You can use the keyPressEvent method to issue the custom signal.
#include <QtWidgets>
class LineEdit: public QLineEdit
{
Q_OBJECT
public:
using QLineEdit::QLineEdit;
signals:
void maxLengthSignal();
protected:
void keyPressEvent(QKeyEvent *event) override{
if(!event->text().isEmpty() && maxLength() == text().length())
emit maxLengthSignal();
QLineEdit::keyPressEvent(event);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
LineEdit w;
QObject::connect(&w, &QLineEdit::textEdited, [](const QString & text){
qDebug()<< text;
});
QObject::connect(&w, &LineEdit::maxLengthSignal, [](){
qDebug()<< "maxLength signal";
});
w.setMaxLength(10);
w.show();
return a.exec();
}
#include "main.moc"

Related

QT Serialport GUI and worker thread

First things first, I'm a newbie in QT so don't blame me. I know that many similar questions have been in the forum, but I couldn't solve my problem.
Problem description. I want to have a GUI application that receives and parses data and update some qt widget. Formerly I did them all in the Mainwindow thread, but since it hangs, I tried to make it multi-threaded. But it still hangs when I try to update GUI data as fast as 10 ms.
Now, this is what I have tried.
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
class Parser : public QThread , public QRunnable
{
Q_OBJECT
public:
explicit Parser(QThread *parent = nullptr);
~Parser();
signals:
void data1Available(unsigned char*);
void data2Available(unsigned char*);
void finished();
// QRunnable interface
public:
void run();
public slots:
void parse();
};
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect( &SerialPort, SIGNAL(readyRead()), this, SLOT(ReadData()) );
QThread* thread = new QThread;
thread->setObjectName("Parser Thread");
qInfo()<<"Parser Thread";
Parser* parser= new Parser();
parser->moveToThread(thread);
QObject::connect(thread,&QThread::started,parser,&Parser::run);
QObject::connect(parser,&Parser::finished,parser,&Parser::deleteLater);
QObject::connect(parser,&Parser::finished,thread,&QThread::quit);
QObject::connect(thread,&QThread::finished,thread,&QThread::deleteLater);
QObject::connect(parser,SIGNAL(data1Available(unsigned char *)),this,SLOT(on_data1Available(unsigned char *)));
QObject::connect(parser,SIGNAL(data2Available(unsigned char *)),this,SLOT(on_data2Available(unsigned char *)));
thread->start();
}
void MainWindow::ReadData()
{
QByteArray Data = SerialPort.readAll();
for (unsigned char i=0;i<Data.length();i++)
circBuff.append(Data[i]);
}
void MainWindow::on_data1Available(unsigned char* tempData)
{
ui->label1->setNum(tempData[5]);
}
void MainWindow::on_data2Available(unsigned char* tempData)
{
ui->label2->setNum(tempData[7]);
}
void Parser::run()
{
qInfo()<<this<<Q_FUNC_INFO<<QThread::currentThread();
QScopedPointer<QEventLoop> loop (new QEventLoop);
QScopedPointer<QTimer> timer (new QTimer);
timer->setInterval(5);
connect(timer.data(),&QTimer::timeout,this,&Parser::parse);
connect(this,&Parser::finished,loop.data(),&QEventLoop::quit);
timer->start();
loop->exec();
qInfo()<<this<<"Finished... "<<QThread::currentThread();
}
void Parser::parse()
{
unsigned char tempData[16];
while (1)
{
while (circBuff.size()>=16)
{
if ( )
{
if ()
emit data1Available(tempData);
else
emit data2Available(tempData);
}
}
}
emit finished();
}

How to end graphic GUI and do console function(QT)?

I am completely new to QT and I want to prepare one window and take some input from the user then with this input run one console and show output in the console. I have tried to write code after exec but it seems it is not possible:
int main(int argc, char *argv[])
{
int retmain = 0;
QApplication a(argc, argv);
MainWindow w;
w.show();
cout<<"pos500"<<endl;
retmain = a.exec();
cout<<"pos50"<<endl;
//doing something
return retmain;
}
I don't know why but after a.exec(); nothing happens.
So I searched on the internet and found below topic in stackoverflow:
How to call function after window is shown?
But I want to end the graphic window and then do my process.
You need to call QCoreApplication::exit() to make exec return control to you.
After this function has been called, the application leaves the main event loop and returns from the call to exec(). The exec() function returns returnCode. If the event loop is not running, this function does nothing.
A simple example would be:
//mainwindow.h
//////////////////////////////////////////////////
#pragma once
#include <QtWidgets/QMainWindow>
#include <QtCore/QCoreApplication>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
void closeEvent(QCloseEvent *event);
~MainWindow();
};
//mainwindow.cpp
//////////////////////////////////////////////////
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
}
void MainWindow::closeEvent(QCloseEvent *event)
{
QCoreApplication::exit(0);
QMainWindow::closeEvent(event);
}
MainWindow::~MainWindow(){}
//main.cpp
//////////////////////////////////////////////////
#include "mainwindow.h"
#include <QApplication>
#include <iostream>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
a.exec();
std::cout << "test" << std::endl;
return 0;
}

Centrally track opened and closed windows in Qt

I need some virtual function/signal/event in a QApplication that centrally informs about any opened and closed window in the application (providing a pointer to the window object; including QMainWindow, QDialog, QWidget based windows).
This should work without manually registering all window instances and without manually manipulating each instance (e.g. by installing event filters or connections on each window object).
Also it should not be necessary to sub-class the tracked windows from some interface class or similar.
So, what is the best way in Qt to track all opened and closed windows in an application?
You must overwrite the notify method of QApplication(or QGuiApplication):
#include <QtWidgets>
class Application: public QApplication
{
public:
using QApplication::QApplication;
bool notify(QObject *receiver, QEvent *e) override
{
if(receiver->isWindowType()){
if(e->type() == QEvent::Show){
qDebug()<< receiver << "show";
}
else if (e->type() == QEvent::Close) {
qDebug()<< receiver << "close";
}
}
return QApplication::notify(receiver, e);
}
};
int main(int argc, char *argv[])
{
Application a(argc, argv);
QMainWindow m;
QDialog d;
QWidget w;
m.show();
d.show();
w.show();
return a.exec();
}
Update:
#include <QtWidgets>
class Application: public QApplication
{
public:
using QApplication::QApplication;
bool notify(QObject *receiver, QEvent *e) override
{
if(receiver->isWidgetType()){
QWidget *w = qobject_cast<QWidget *>(receiver);
if(w->isWindow()){
if(e->type() == QEvent::Show){
qDebug()<< w << "show";
}
else if (e->type() == QEvent::Close) {
qDebug()<< w << "close";
}
}
}
return QApplication::notify(receiver, e);
}
};

creating QApplication in a different thread

I'm trying to create QApplication in a different thread, but found 2 main problems:
1- I can't interact with GUI
2- some warnings:
WARNING: QApplication was not created in the main() thread.
QObject::startTimer: timers cannot be started from another thread //happens when resizing widget
QObject::killTimer: timers cannot be stopped from another thread
here is the full code: (it may has some memory leaks but for testing purposes it fails)
//main.cpp
#include <QCoreApplication>
#include "cthread.h"
int main(int argc, char *argv[])
{
CThread *MyThread = new CThread;
MyThread->start();
QCoreApplication a(argc, argv);
return a.exec();
}
//CThread.h
#ifndef CTHREAD_H
#define CTHREAD_H
#include <QThread>
#include "theqtworld.h"
class CThread : public QThread
{
Q_OBJECT
public:
CThread();
void run( void );
private:
TheQtWorld *mWorld;
};
#endif // CTHREAD_H
//CThread.cpp
#include "cthread.h"
#include <iostream>
CThread::CThread():mWorld(NULL)
{
}
void CThread::run()
{
std::cout << "thread started" << std::endl;
if(!mWorld)
mWorld = new TheQtWorld();
mWorld->OpenWorld();//now it will init all Qt Stuff inside
// if(mWorld) delete mWorld;
// emit this->exit();
}
//theqtworld.h
#ifndef THEQTWORLD_H
#define THEQTWORLD_H
#include <QObject>
#include "mainwindow.h"
#include <QApplication>
class TheQtWorld : public QObject
{
Q_OBJECT
public:
explicit TheQtWorld(QObject *parent = 0);
int OpenWorld(void);
signals:
public slots:
};
#endif // THEQTWORLD_H
//theqtworld.cpp
#include "theqtworld.h"
TheQtWorld::TheQtWorld(QObject *parent) :
QObject(parent)
{
}
int TheQtWorld::OpenWorld()
{
static int arg = 0;
static char *b[2];
b[0] = "a";
QApplication *a = new QApplication(arg, b);
a->setParent(this);
MainWindow w;
w.show();
return a->exec();
}
I would answer my own question after understanding how to overcome this problem
first the problem was to integrate Qt GUI as a plugin into another Application, so the main issue was the Event loop collision between Qt Events and any other Application Events
my first thoughts was to separate both, so QApplication will stay at a different thread, but this was a totally wrong approach and here is what I have noticed:
1- Qt GUI Must stay in the main() thread so there is no other place for QApplication
2- to avoid the blocking QApplication::exec() , embed QApplication::processEvents() into the other Application Event loop
here is a working code:
//main.cpp
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication mApp(argc, argv);
MainWindow w;
w.show();
//just for testing and holding the program so it doesn't end
for(int i = 0; i < 100000000; ++i)
{
mApp.processEvents();
}
return 0;
}
edit:thanks to pavel-strakhov for his great suggestion.

How handle keyboard events in QCoreApplication?

I would like to handle keyboard events in command line application based on QCoreApplication class.
Following http://doc.qt.nokia.com/4.7/eventsandfilters.html I tried to reimplementing QCoreApplication::event(), but my code not works:
#include <QCoreApplication>
#include <QtGui/QKeyEvent>
class CoreApp : public QCoreApplication
{
Q_OBJECT
public:
explicit CoreApp(int & argc, char ** argv);
bool event(QEvent *event);
};
CoreApp::CoreApp(int & argc, char ** argv) :
QCoreApplication(argc,argv)
{
}
bool CoreApp::event(QEvent *event)
{
if (event->type() == QEvent::KeyPress) {
QKeyEvent *ke = static_cast<QKeyEvent *>(event);
if (ke->key() == Qt::Key_Q) {
qDebug("Quit?");
//qApp->quit();
return true;
}
}
return QCoreApplication::event(event);
}
int main(int argc, char *argv[])
{
CoreApp a(argc, argv);
return a.exec();
}
I've checked http://doc.qt.nokia.com/qq/qq11-events.html and didn't find solution.
How to handle these events properly?