如何防止GUI挂起,同时允许第二次操作与Qt中的第一次操作一起执行

How to prevent GUI from hanging while allowing 2nd operation to be performed alongwith 1st operation in Qt

本文关键字:操作 Qt 执行 一起 第一次 第二次 挂起 GUI 何防止      更新时间:2023-10-16

在这里,我详细解释了我的问题陈述以及迄今为止我在中所做的努力

A(问题说明:打印过程中,如果按下"停止打印"按钮,打印应在此时停止!

B(我的工作:

1.StartPrinitng_Pressed

void MainWindow :: on_StartPrinitng_Pressed()
{QSqlquery studentList;
studentList("SELECT Name, address FROM class  WHERE Roll No = some       variable")
while(studentList.next())
{       
Name=studentList.value(0).toString();   
address=studentList.value(1).toString();   
QTimer:: singleShot(1000,this,SLOT(StopNow()));   //calling stopNow function
if(StopPrintingNow==0)
{  //**   I am printing the fetched data (in a string)  by setting GPIO    pins  HIGH      **//  }

}
}

2.停止打印:

void MainWindow::on_StopPrinting_Pressed()
{StopPrintingNow=1;} 

3.StopNow函数声明:

void MainWindow::StopNow() 
{
if(StopPrintingNow==1)
{   //**  I have reset all serials ports; Break;   **// }
else if(StopPrintingNow==0)
{ QTimer::singleShot(1000,this,SLOT(on_startPrinting_pressed())); }
}

C(程序执行流程:当按下"开始打印"按钮时,我的问题中显示的查询将执行,从数据库中获取数据并执行同时打印。

D(面临的问题-

1.打印时GUI挂起,因此"停止打印"按钮没有响应。

  1. Qtimer在打印时没有调用"StopNow函数"(尽管我在正确的位置调用了它(在此处输入图像描述

计时器和按钮按下的处理都包含在Qt事件循环中——当您在SQL查询上循环时,它会被阻止。你有两个选择:

1( 定期在while循环中调度事件。这和一样简单

qApp->processEvents();

但是,您必须小心:由于用户交互(或计时器(而触发的任何事件都将被阻止,并且在事件完成之前,while循环不会运行。特别是在您的情况下,您可能会运行on_StartPrinitng_Pressed函数的第二个副本。

2( 在单独的线程上进行打印。这涉及到更多的代码,但其要点是创建一个具有startPrinting插槽和stopPrinting插槽的SqlPrinter对象。然后创建一个QThread,并将其所有者线程更改为该线程。插槽调用将跨线程边界进行,一切都会很好。

class SqlPrinter : public QObject {
Q_OBJECT
public:
SqlPrinter(QObject* parent = nullptr) : QObject(parent) {}
public slots:
void startPrinting();
void stopPrinting();
};

在您的主代码中,假设您有两个名为MainWindow_StartButtonMainWindow_StopButton:的按钮,然后执行类似的操作

QThread* printerThread = new QThread(qApp);
SqlPrinter* printer = new SqlPrinter;
printer->moveToThread(printerThread);
printerThread->start();
QObject::connect(MainWindow_StartButton, &QPushButton::clicked, printer, &SqlPrinter::StartPrinting);
QObject::connect(MainWindow_StopButton, &QPushButton::clicked, printer, &SqlPrinter::StopPrinting);

之后别忘了清理SqlPrinter