如何防止GUI挂起,同时允许在Qt中执行第二项操作和第一项操作

时间:2018-07-23 07:07:39

标签: c++ qt user-interface

在这里,我正在详细解释我的问题陈述以及我到目前为止所做的努力

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。 StopPrinting_Pressed:

 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)程序执行流程:当按下“ StartPrinting”按钮时,将执行我的问题中显示的查询,该查询将从数据库中获取数据并执行同时打印。

D)面临的问题-

1.GUI在打印时被挂起,因此StopPrinting按钮没有响应。

  1. Qtimer在打印时未调用“ StopNow函数”(尽管我已经在正确的位置调用了它)enter image description here

1 个答案:

答案 0 :(得分:2)

Qt事件循环涵盖了计时器和按钮的处理-在遍历该SQL查询时,该事件循环被阻止。您有两种选择:

1)定期在您的while循环中调度事件。 这很简单

qApp->processEvents();

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

2)在单独的线程上进行打印。 这涉及更多代码,但要点是,您将创建一个SqlPrinter插槽和一个startPrinting插槽的stopPrinting对象。然后,您创建一个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