Qt Pushbutton must process the signal after a delay - c++

I am using a push button which records incoming microphone sound signal. Usually, the signal arrives a little late after pressing the record button and my recorded output contains zero until 10 ms(after which i receive an actual output). I am using the following QTimer function to set the delay but there is the ouput is the same,
QTimer->singleShot(0.010, this, SLOT(onStartRecordPushButton))
Are there any other methods to crop the signal for the first 10 ms or start recording only when a non zero signal arrive? Thanks

QTimer::singleShot takes milliseconds as an argument, not seconds.
Your call should probably look like this:
QTimer->singleShot(10, this, SLOT(onStartRecordPushButton))

Related

Adding a timer to a qt application

I'm attempting to build a program which takes any text file and turns it into a typing test. It has a timer that will display to the screen.
However, I can't figure out how to display the timer while actually running my game instructions. The timer works and displays the elapsed time but displaying the timer is the only thing it will do.
Can anyone give me some pointers of things that might be helpful for solving this problem?
QTimer has a signal timeout() which will be emitted after your interval time is elapsed. A QTimer unless specified as a singleshot runs again and again.
Let's assume you wish to do something every second, you can start a timer with interval 1000 (in msec). You can then connect its timeout signal to a slot. There you can specify how to go about doing stuff.
It's fine to run multiple timers at the same time. Also, for your initial implementation (for displaying the timer); you might want to take a look at QElapsedTimer.
Edit:
I found this example. It might provide you something to look at.
QTimer emits timeout() signal in every time interval specified by you unless it's a 'single-shot' timer.
If you want to display the elapsed time, connect the timeout() signal of your timer object to your slot which will display the time elapsed. Your slot will contain your logic to display whatever you want.

SendMessage WM_COPYDATA between two processes [duplicate]

Basically exactly what the title says. I would like to update the text that a button contains every 1 second when the user presses that particular button. I have noted that when the program doesn't have focus it works alright and the text refreshes correctly but when I am hovering over the program or when I am trying to click on it's menu Windows inform me that the program is unresponsive and asks me if I want it terminated. When the loop finishes the program returns to its normal state. Also any action I might have done (like moving it around or closing it) while it was Sleep()-ing is executed after the loop. Here is a bit of code:
case ID_BUTTON_START:
// Code executed when pressing Start Button.
char startButtonText[30]; // Storing next loop text
for (int i=5; i>0; i--)
{
sprintf(startButtonText, "Starting in ... %d", i);
SendMessage(hwndButtonStart, WM_SETTEXT, 0, (LPARAM)(startButtonText));
Sleep(1000);
}
Is this normal? If not what's causing this?
The WndProc does not process messages asynchronously within an application which means all messages are expected to be handled quickly and a return value delivered immediately. You must not Sleep in the UI thread since it will block other UI events from being processed. Any heavy work or synchronous requests/jobs which are likely to take a long time should be performed in worker threads. There are at least three viable options:
Create a new (worker thread) for the task.
If the task is likely to be done often, use a thread pool instead.
Set and subscribe to timer events.
I think the call to Sleep() might be keeping you from returning from the WndProc, so your application is not processing the incomming events for 5 secs. I suggest you try to subscribe to 5 timer events in 1s, 2s,..., 5s. Like when the timer message is recieved the button text must change. I don't know a way how to do that off the top of my head.

How to show a QMessageBox completely before the next function call

I want to use a QMessageBox to announce a short waiting interval to the user.
QMessageBox* box(new QMessageBox(QMessageBox::Information,"Parser","Processing " + mFileName));
box->setStandardButtons(QMessageBox::NoButton);
box->setWindowModality(Qt::WindowModal);
box->show();
QApplication::processEvents();
parser.analyseFile(mFileName);
box->hide();
box->deleteLater();
QApplication::processEvents();
The function only takes few seconds.
The box gets displayed but neither the icon nor the text is shown in time before the function finishes. Why does QApplication::processEvents(); not prevent the program from continuation before the box is completely shown.
Is it possible to achieve the desired behaviour without resorting to threads.
Doing the processing in a separate thread would be preferable, since that would leave the GUI thread free to do things like handle mouse events, window resizes, etc, while the task is being completed; that way the GUI won't "freeze up" temporarily.
If you don't want to spawn a thread, however, you can call processEvents() periodically from within your analyseFile() function and that will give you roughly the same behavior. Try to call it at least every 50mS to avoid sluggish GUI response.
A second possibility might be to add a slot somewhere:
void MyClass :: ParseFile()
{
parser.analyseFile(mFileName);
box->hide();
box->deleteLater();
}
... and then invoke that asynchronously like this:
QTimer::singleShot(0, this, SLOT(ParseFile()));
... that might give the windowing system enough time to finish displaying the QMessageBox before ParseFile() executes, or it might not (in which case you could try to increase the delay argument from 0 to, say, 100 milliseconds instead). That's a little hacky, but it could work.

Sleep() in Win32 makes program unresponsive

Basically exactly what the title says. I would like to update the text that a button contains every 1 second when the user presses that particular button. I have noted that when the program doesn't have focus it works alright and the text refreshes correctly but when I am hovering over the program or when I am trying to click on it's menu Windows inform me that the program is unresponsive and asks me if I want it terminated. When the loop finishes the program returns to its normal state. Also any action I might have done (like moving it around or closing it) while it was Sleep()-ing is executed after the loop. Here is a bit of code:
case ID_BUTTON_START:
// Code executed when pressing Start Button.
char startButtonText[30]; // Storing next loop text
for (int i=5; i>0; i--)
{
sprintf(startButtonText, "Starting in ... %d", i);
SendMessage(hwndButtonStart, WM_SETTEXT, 0, (LPARAM)(startButtonText));
Sleep(1000);
}
Is this normal? If not what's causing this?
The WndProc does not process messages asynchronously within an application which means all messages are expected to be handled quickly and a return value delivered immediately. You must not Sleep in the UI thread since it will block other UI events from being processed. Any heavy work or synchronous requests/jobs which are likely to take a long time should be performed in worker threads. There are at least three viable options:
Create a new (worker thread) for the task.
If the task is likely to be done often, use a thread pool instead.
Set and subscribe to timer events.
I think the call to Sleep() might be keeping you from returning from the WndProc, so your application is not processing the incomming events for 5 secs. I suggest you try to subscribe to 5 timer events in 1s, 2s,..., 5s. Like when the timer message is recieved the button text must change. I don't know a way how to do that off the top of my head.

QWidget update events but no visual update

Using Qt4.8 on a Mint Linux 12, I implemented a simple window containing a QTableView to show contents of a model. The model data is continually updated (log messages) and the dataChanged() signal is emitted on a regular basis (i.e. every 100ms).
The problem I see is stuttering visual updates on the table.
I installed an event filter on the window that counts updateRequest-type events, which should trigger a widget repaint (also on child widgets, i.e. the tableView). These come in with an average time of ~170ms between them and a standard deviation of ~90ms (which is rather large, I guess). However, the perceived visual update rate is only two or three times a second and I wonder why. It seems that not all updateRequest events trigger a widget repaint or that the window system swallows visual updates.
As a second test, I forced the window to update itself by calling repaint or update every 100ms. Using repaint, I saw a corresponding increase in updateRequest-type events and a decrease of the standard deviation of the gaps; with update, the number did not increase. However, there was only a moderate increase of perceived update rate in both cases.
Also: Is there a good method to measure how often a widget is actually really repainted without having to overload its paintEvent handler? Maybe something from QTest?
Update: I extended my event filter to also catch paintEvent-type events. There are only a one-digit number of those versus > 1000 updateRequest-type events.
You should instrument the event dispatcher's aboutToBlock() and awake() signals, and measure time between them using a QElapsedTimer. The instance of the event dispatcher for the current thread is returned by the static QAbstractEventDispatcher::instance().
If the event loop sleeps for a very small fraction of your time measurement window, it means there's too much stuff going on in the GUI thread. You can keep a count of how long the event loop slept, say, during the last second. If it's below 10%, you can expect slow updates and whatnot. Remember that update events are queued with Qt::LowEventPriority. They will be preempted by standard queued signals and almost all other events.
QApplication::compressEvent discards QEvent::UpdateRequest, if there is already one unprocessed. Thus even repaint(s) can return immediately without painting, if the event is discarded. You can check, if your updateRequest events are discarded by overwriting compressEvent.