QT does not respond using a while loop - c++

I've searched around without luck to get the answer to this question.
I'm doing a UART communication, I want to read data continuously if I have the button pressed or in the "down" position. The problem is that I'm using a while loop to do it. When I try to stop reading and release the button, the program freezes and does not respond. Any help will be appreciated it. Part of the code is below.
void MainWindow::on_pushButton_3_toggled(bool checked)
{
while(checked)
{
QByteArray datas = Serial_port.readAll();
ui->textEdit->setText((QString)datas);
qDebug()<<"Im here";
msleep(100);
qDebug()<<datas;
qDebug()<<checked;
}
qDebug()<<checked;
}

You're blocking the event loop, therefore, Qt can't process events. You could try calling QApplication::processEvents() during your loop, and that should make the UI responsive again.

why you need a loop to exec this code? are you using function connect() to made your click event correct? whem you click u start your loop and you don't have a end of this loop, you don't need this loop, you readall from serial port and put it in QBytearray when it finally readall the function read the next line and next at until end of function!
but if your need to continue using the loop try to made a checkbox in your ui, to get true or false and put a if in in loop to stop your loop
if(ui->cb->isChecked())
checked = true;
else
checked=false;

Related

How do use BLE scan_stop

im doing a program that allow my beacon and DK board to start scanning and stop scanning using BLE. I am able to start scanning, but i didn't know how to stop scanning. Can anyone advise me with this? The code provided is my scan_start. Thank you!
static void scan_start(void)
{
uint32_t err_code;
err_code = sd_ble_gap_scan_start(&m_scan_params);
APP_ERROR_CHECK(err_code);
err_code = bsp_indication_set(BSP_INDICATE_SCANNING);
APP_ERROR_CHECK(err_code);
}
Stopping scan_start depends on where you use this function. For example if you use scan_start in main function(before for loop), after a while, if there is no connection, it will enter sleep mode and stop scanning.
Otherwise if you want to control start_scanning time, you can define app_timer function. For example, you can define a timer or button handler that starts scanning when the button is pressed.
If you still can not find the answer you're looking for, there is another suggestion. You can use the stop_scanning function in the file "ble_gap.h" to stop scanning. Function like this;
SVCALL(SD_BLE_GAP_SCAN_STOP, uint32_t, sd_ble_gap_scan_stop(void));
You can use like this;
(void) sd_ble_gap_scan_stop();
If there is any mistake please correct it. I hope that will be useful...

How to fully/correctly exit a Qt program from the main form?

I'm writing a Qt program (using Qt 5.4) that reads frames from a webcam based on a QTimer, not a separate thread (interval set to 20 ms, of course it takes much longer than 1/50 of a second to read a frame from the webcam and process it, I'd approximate the frame rate is perhaps 20 fps. Anyhow, the function which runs when the timer cycles is a slot and is as follows:
///////////////////////////////////////////////////////////////////////////////////////////////////
void frmMain::processFrameAndUpdateGUI() {
bool blnFrameReadSuccessfully = capWebcam.read(matOriginal); // get next frame from the webcam
if (!blnFrameReadSuccessfully || matOriginal.empty()) { // if we did not get a frame
QMessageBox::information(this, "", "unable to read from webcam \n\n exiting program\n");
QApplication::quit();
}
// process frame here . . .
The idea being if the webcam can be successfully read at the beginning of the program, but then cannot be (webcam stops working, user accidentally disconnects webcam, etc.) the program should show a message box to this effect and then close itself entirely.
With the above, if I unplug the webcam while the program is running for testing purposes, the message box appears as intended, but after choosing OK, a debug error screen appears. If I choose "Abort" the form is still there and will not respond. After attempting to close the form multiple times Windows asks "the program does not seem to be responding, would you like to close?" at which time I can close the form. Clearly this is not achieving the intended effect.
After various Googling I found the suggestion to modify as follows:
///////////////////////////////////////////////////////////////////////////////////////////////////
void frmMain::closeEvent(QCloseEvent *) {
QApplication::quit();
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void frmMain::processFrameAndUpdateGUI() {
bool blnFrameReadSuccessfully = capWebcam.read(matOriginal); // get next frame from the webcam
if (!blnFrameReadSuccessfully || matOriginal.empty()) { // if we did not get a frame
QMessageBox::information(this, "", "unable to read from webcam \n\n exiting program\n");
closeEvent(new QCloseEvent());
}
// process frame here . . .
When I first saw this code I was optimistic, however it gives me the same result as above (program hangs with the form still open). I'm using OpenCV 2.4.11 for my image processing and my program has 4 files:
frmmain.h (.h for the main form, which is a standard QMainWindow made with Qt Creator)
frmmain.cpp (.cpp for the main form, where the above code resides)
main.cpp (which I have not changed from how Qt Creator made it)
frmmain.ui (typical form with a small number of common widgets added via Qt Creator)
Yes, I realize that I could show an error message on one of the widgets that can show text, return from the function, and leave it to the user to close the program, but I'm looking for a more elegant solution. Can anybody offer further advice as to how to fully close a graphical Qt program? Please advise.
Two things that could possible solve your problem:
Before displaying the messagebox, stop the timer with the stop() method.
After the QApplication::quit(); exit the function with return; Your function might be running to the end one last time and accessing invalid objects.
For anybody else's reference Rafael Monteiro's answer was spot on. Here is the updated code (verified working):
///////////////////////////////////////////////////////////////////////////////////////////////////
void frmMain::closeEvent(QCloseEvent *) {
if(qtimer->isActive()) qtimer->stop(); // had to stop timer here !!!!!!!!
QApplication::quit();
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void frmMain::processFrameAndUpdateGUI() {
bool blnFrameReadSuccessfully = capWebcam.read(matOriginal); // get next frame from the webcam
if (!blnFrameReadSuccessfully || matOriginal.empty()) { // if we did not get a frame
QMessageBox::information(this, "", "unable to read from webcam \n\n exiting program\n");
closeEvent(new QCloseEvent());
return; // had to add return here !!!!!!!!!
}
// rest of function here . . .
I should mention I had to add both the return and stop the timer. Thanks Rafael!

Clear input command line?

I'm making an console application. It starts with a menu where if I press the key; 1. The menu changes into another menu screen. But note, without me pressing 'Enter'. This means that my 1 still remains, which is obviously bad when stepping down further in the menus.
How do I clear the input command line?
The function im using.
if(GetAsyncKeyState('1'))
{
IEventDataPtr gameState(GCC_NEW EvtData_Set_Game_State("PREGAMESTATE"));
em->VTriggerEvent(gameState);
//Enter line clearing code.
}
The function GetAsyncKeyState gives you "the current state of a key". So it will return true between the point when the keyboard driver has received the "key for 1 has been pressed" until the keyboard driver receives "key for 1 has been released".
I would seriously suggest that you use ReadConsoleInput instead if you want to get one keypress at a time.
The alternative is to use something like this:
while(GetAsyncKeyState('1'))
{
// Do nothing.
}
to wait for that key to be released.

Qt program freezes every time

I'm making a C++ GUI program in Qt using qtcreator its not complete yet but when ever I build and run to test the program it runs then if i click buttons that open a file or write something in a file, the button does that and then the program freezes. Why this happens, What I'm doing wrong or what's the issue.
It mainly freezes in theses two functions:
void MainWindow::on_kmpOpenButton_clicked()
{
QString kmplayerloc = "\"F:\\Program Files\\The KMPlayer\\KMPlayer.exe\"";
QProcess::execute(kmplayerloc);
}
void MainWindow::on_nbopenbutton_clicked()
{
// Remember tha if you have to insert " in a string \"....location of file or anything u want to put.......\"
QString netbeansloc = "\"F:\\Program Files\\NetBeans 7.4\\bin\\netbeans.exe\"";
QProcess::execute(netbeansloc);
}
From the documentation
Starts the program program [..] in a new
process, waits for it to finish, and then returns the exit code of the
process.
The calling thread freezes until the external process is finished. If you don't want this, use the method start or startDetached.

Break and rerun while loop c++ Windows

I'm a rookie programmer, so please be polite.
Well i'm trying to write a simple Terminal Backgammon game, just for fun, but i have a problem.
The entire game runs in a while loop which keeps re running as long as nobody moved all their bricks to the end of the board.
A simple integer controls whatever it is black or white who plays.
I wrote a function to check for any possible moves, cause i want to program to skip the turn in case absolutely no moves can be made.
Well, i want this function to run and in case it returns false(No possible moves) then i want the rest of the code to skip and change the turn to the next player. For example if the dice combination gives no possible moves for black, then i want the program to skip black and go to white.
So i sort of want to break the rest of the while loop, but keep it running.
It's a little complicated for me to explain the issue, but i hope you guys understand.
Thanks alot
- Martin
It sounds like you want to use continue:
while (someCondition)
{
doSomething();
if (someOtherCondition)
continue;
doSomethingElse();
}
In this example, if someOtherCondition is true, the continue statement will cause the program to jump back to the top of the loop rather than continuing to execute the following statements. If someOtherCondition is false, doSomethingElse() will get run as normal.
I think this is roughly what you want to know.
Hope it helps.
while( keepRunning )
{
bool noPossibleMoves = checkForPossibleMoves();
setup for each loop iteration
Do things here that are always necessary.
if( noPossibleMoves )
{
continue; // This will go to the top of the while loop
}
wait for user input etc...
...
...
}