Qt Creator Disable push button when precessed - qt

I'm new using Qt and I'm having some troubles with it.
I'm doing a simple terminal application and I need to disable the buttons for a few seconds after they are selected.
I'm doing something like this:
void MainWindow::on_readcard_clicked(){
this->setEnabled(false);
//Send Command
QString commandString = "";
commandString.append('1');
commandString.append("\n");
QByteArray commandArray = commandString.toLocal8Bit();
serial->write(commandArray);
//Read Card
QByteArray data = serial->readLine(12);
QString dataString = 0;
dataString.append(data);
ui->cardnumber->setText(dataString);
dataString.clear();
data.clear();
QByteArray saldo = serial->readAll();
QString saldoString = 0;
saldoString.append(saldo);
ui->balance->setText(saldoString);
saldoString.clear();
saldo.clear();
this->setEnabled(true);}
I need this because if someone press the button twice before it finished processing the first tap I will get a "crazy" array with lots of trash.
I also tried use "waitForBytesWritten" and "waitForReadyRead" but it hasn't blocked the connection until everything was processed.
Regards

Try with QTimer::SingleShot() :
this->setEnabled(false);
QTimer::singleShot(2000, this, SLOT(enableMyButton()));
// you code
void enableMyButton()
{
this->setEnabled(true);
}
It'll enable the button 2secs after the call

Related

Project hangs on QProcess::start when starting QtAssistant

I am using QProcess::start to launch Qt Assistant with my custom help project file. It works fine until i load project(not help project file) to my programm. Programm generates images from specific data using custom library. Even when all processes ends and i see generated images and nothing else happens, when i trying to launch Qt Assistant, my programm hangs at QProcess:start function when trying to start process. The code is:
show() function(public):
if (!run())
return false;
QByteArray ba("setSource ");
ba.append("qthelp://insyn_help/doc/");
proc->write(ba + page.toLocal8Bit() + '\n');
return true;
run() function(private):
if (!proc)
proc = new QProcess();
if (proc->state() == QProcess::Running)
return true;
QString app = QString(QT_BIN_DIR) + QDir::separator() + QString("assistant");
QString path = QString(PREFIX) + QString(HELP_INSTALL_PATH) + QString("/help_project.qhc");
QStringList args;
args << QLatin1String("-collectionFile")
<< QLatin1String(path.toLatin1())
<< QLatin1String("-enableRemoteControl");
QFileInfo help_project(path);
if (help_project.exists()) {
proc->start(app,args);
if (!proc->waitForStarted()) {
m_exitCode = 1;
emit closed();
return false;
}
}
This code is a part of AssistantLauncher class which was registered using qmlRegisterType and added to main.qml as a member of application window. My programm doesn't touch it anywhere (except calling a method show()). It is separate object (except it is a part of appWindow). The question is why does the process can not start only after my programm did some work? And why QProcess::start even dont have timeout.
UPD: I moved proc->start(app,args); to the child process, which i getting by using fork() and now my programm hangs on pid_t child = fork(). So the problem is that new process can not be created.
The answer is to do not use fork() because it is dangerous in big projects. More at http://www.evanjones.ca/fork-is-dangerous.html . posix_spawn also hangs my project. Now i decided to fork() new process at the beginning and send commands to it through the pipe.

Qt: Use QAudioRecorder to return buffer

I want to use QAudioRecorder to record an audio and save as a file and display the filepath to the user. I had tried using the the example from Qt but there's no feed on the buffer value when I tested it on Android. It works on my Desktop though. Below are part of my codes:
AudioRecord::AudioRecord(QWidget *parent)
{
audioRecorder = new QAudioRecorder(this);
probe = new QAudioProbe;
connect(probe, SIGNAL(audioBufferProbed(QAudioBuffer)),
this, SLOT(processBuffer(QAudioBuffer)));
probe->setSource(audioRecorder);
}
void AudioRecord::processBuffer(const QAudioBuffer& buffer)
{
qDebug()<<"Testing Successful";
}
The processBuffer function does not seems to be called. What should I do to get the buffer value work? Is there any other way around?
Thanks!

Properly using Qt QProcess

I'm considering to use QProcess to call a command line app (gpio) multiple times. Every time user clicks a button then a command is issued.
And the app output will be monitored and redirected to screeen. The code looks like the following.
void Gpio::command(QString argument)
{
// if(process)
// delete process;
process = new QProcess(this);
connect(process, SIGNAL(started()), this, SLOT(onStart()));
connect(process, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(onFinish(int,QProcess::ExitStatus)));
connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(readGpio()));
QString program("gpio");
QStringList list = argument.split(" ");
process->start(program, list);
}
Question: Should I delete process? Doing so I got:
QProcess: Destroyed while process is still running.
Monitoring exitCode and exitStatus I see they are always 0.
This question concerns more about the proper use of QProcess while "QProcess and shell : Destroyed while process is still running" focus on the specific error.
as you don't want to run multiple processes concurrently (as per the comments), you don't need to create / delete the QProcess multiple times.
gpio.h
QProcess* m_gpioProcess;
gpio.cpp file
Gpio::Gpio(.....),
.....(),
m_gpioProcess(new QProcess(this))
{
m_gpioProcess->setProgram("gpio");
connect(m_gpioProcess, SIGNAL(started()), this, SLOT(onStart()));
connect(m_gpioProcess, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(onFinish(int,QProcess::ExitStatus)));
connect(m_gpioProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readGpio()));
}
void Gpio::command(const QString& args)
{
if (m_gpioProcess->state() != QProcess::NotRunning) {
qDebug() << "Process already running, ignoring the request";
return;
}
m_gpioProcess->setArguments(args.split(" "));
m_gpioProcess->start();
if (m_gpioProcess->waitForStarted()) {
qDebug() << "Process started with arguments:" << m_gpioProcess->arguments();
}
}
if you want to prevent user clicking the button multiple times, consider enabling / disabling the button as per m_gpioProcess state.
for Qt 4.8, just remove this line
m_gpioProcess->setProgram("gpio");
and this line
m_gpioProcess->setArguments(args.split(" "));
and change this line
m_gpioProcess->start();
to
m_gpioProcess->start("gpio", args.split(" "));
Well, It seems I was forgetting process->waitForFinished(); after the call to start. This seems to solve the problem.
add following code maybe helpful:
process->close();

how to update QTableWidget item?

There is a thread running! it receives data from internet two times per second, then I set the data in qtablewidget?
How can I make the QTableWidget update itself ?
Now I must click the interface if I want to update the display!
DWORD WINAPI MyThreadProc1(LPVOID lpParameter){
int data=receive();
w.setVal(data);
return 0;
}
void TradeSystem::setValue(int num){
QTableWidgetItem *item = new QTableWidgetItem(QString::number(num,10,1));
item->setBackgroundColor(QColor(0,60,10));
ui.tableWidget_3->item(0,0)->setText(QString::number(num,10,0));
}
i guess this problem falls in the category 'i want to change gui from another thread' -> don't do it.
when setValue(int) is a slot, you can do the following:
DWORD WINAPI MyThreadProc1(LPVOID lpParameter)
{
(void)lpParameter;
int data = receive();
QMetaObject::invokeMethod(w, "setValue", Q_ARG(int, data));
}
You should get used to signals in QT , its easy to use and can make your life easier .
DWORD WINAPI MyThreadProc1(LPVOID lpParameter){
int data=receive();
emit data_recieved(data);
return 0;
}
void TradeSystem::setValue(int num){
QTableWidgetItem *item = new QTableWidgetItem(QString::number(num,10,1));
item->setBackgroundColor(QColor(0,60,10));
ui.tableWidget_3->item(0,0)->setText(QString::number(num,10,0));
}
and before you activate MyThreadProc1 , connect the signal and handler :
connect(this,SLOT(setValue(int)),MyThreadProc1,SIGNAL(data_recieved(int)));
that way , you can connect basically every widget in qt with a signal/slot .
either in different Form,Threads .
This is helpful also Docs.

Video not playing on startup

I am trying to play a video in Qt using OpenCV. I am using the following code.
CvCapture *capture;
IplImge *frame;
cv::Mat source_image;
cv::Mat dest_image;
QTimer *imageTimer;
void MainWindow::onButtonClick()
{
capture = cvCaptureFromFile("/mp.mp4");
while(capture)
{
frame = cvQueryFrame((capture);
source_image = frame;
cv::resize(source_image,source_image,cv::Size(420,180),0,0);
cv::cvtColor(source_image,source_image,CV_BGR2RGB);
QImage qimg = QImage((const unsigned char*) source_image.data,source_image.cols,source_imge.rows,QImage::Format_RGB888);
label->setPixmap(QPixmap::fromImage(qimg));
label->resize(label->pixmap()->size());
qapp->processEvents();
}
}
When I try to play it on button click it is working fine. However when I write the same code in MainWindow constructor it gets finished unexpectedly. I want that the video should be displayed on screen start up and not when I click a button. What should I do for the same?
Thank You :)

Resources