Qt 多线程和定时器问题

时间:2021-11-02 23:18:42
主线程加载缓冲界面,用到定时器;子线程加载数据,耗时3秒。但出现问题是,要么不加载数据,缓冲界面立即出来,一切正常,而加载数据的话,缓冲界面消失,界面停在那里,3秒后加载后的界面出来。

我网上看了一下,说定时器优先级低,是因为优先级低,所以就被子线程干掉了???求解!!

7 个解决方案

#1


等下  你确定你用了多线程?    貌似你只是用了定时器吧   定时器不会并发运行的    如果有两个定时器,  定时器一在运行的话 定时器二就算时间到了也是无法运行的。  定时器和多线程貌似是两码事。

你的做法的问题在于:当你加载数据时 运行你所说的子线程,此时你所说的主线程也是出于等待状体的,主线程一停下来 界面当然就卡了 所以想让主界面不卡就必须要用多线程 而不是定时器。  

#2


1  检查子线程,看线程内部是不是写得有问题,导致事实上是在同一个线程里运行?
2  虽然定时器优先级较低,但一般也不致于被其它线程强占cpu而定时器不工作,请确认你的加载缓冲界面和子线程之间的代码顺序和逻辑关系。
3  按你的实现思路写一个小例子来试,如果还是不行,发上来大家帮看一下。

#3


引用 1 楼  的回复:
等下  你确定你用了多线程?    貌似你只是用了定时器吧   定时器不会并发运行的    如果有两个定时器,  定时器一在运行的话 定时器二就算时间到了也是无法运行的。  定时器和多线程貌似是两码事。

你的做法的问题在于:当你加载数据时 运行你所说的子线程,此时你所说的主线程也是出于等待状体的,主线程一停下来 界面当然就卡了 所以想让主界面不卡就必须要用多线程 而不是定时器。


我还是要说明一下的好,我确实是使用了多线程,不知道你从哪里得出我只用了定时器。主线程和子线程并发执行,所以你所说的主线程处于等待状态的理由是什么??

#4


引用 2 楼  的回复:
1  检查子线程,看线程内部是不是写得有问题,导致事实上是在同一个线程里运行?
2  虽然定时器优先级较低,但一般也不致于被其它线程强占cpu而定时器不工作,请确认你的加载缓冲界面和子线程之间的代码顺序和逻辑关系。
3  按你的实现思路写一个小例子来试,如果还是不行,发上来大家帮看一下。

好的,我把代码贴上来,请大神帮我看看,谢谢了!
因为子线程显示UI 会有各种问题,所以我主线程显示缓冲的页面,子线程加载数据,数据加载结束后,主线程缓冲界面消失,显示加载完成的数据。

下面是代码:
   主线程{

   buffer = new loadingBuffer(whiteBackground);// 这个buffer就是缓冲界面,whiteBackground为父Item;

   buffer->bufferStart(); //缓冲界面的定时器开始;
   
   if(load_thread != NULL)
   {
         load_thread->quit();
         delete load_thread;
   }
 
   load_thread = new loadingThread(filename);//load_thread 为定义的多线程类的指针
              connect(load_thread,SIGNAL(documentloaded(PDFModel*)),this,SLOT(slot_kill_buffer(PDFM  odel*)));//加载完成就把缓冲界面kill掉。
 
   load_thread->start();//调用run函数,开始加载。

}


子线程{
    
void loadingThread::run()
{

     thread_model = new PDFModel();
          connect(thread_model,SIGNAL(documentLoaded()),this,SLOT(slot_document_opened()));

     thread_model->load(QString("%1/%2").arg(filepath).arg(pdfName));
 
     exec();
}
void loadingThread::slot_document_opened()
{
     emit documentloaded(thread_model);
}

}

接受到子线程发出的信号后,主线程{

void pdfCategory::slot_kill_buffer(PDFModel *model)
{
     buffer->bufferStop();    //stop缓冲界面
 
     if(m_pdf!=NULL)
     {
         delete m_pdf;
     }

     m_pdf = new PDFScreen(model);           //一下三行就是显示加载完成的数据,是一个pdf文件
     m_pdf->setParentItem(whiteBackground);
     m_pdf->createUi();
 }

}

 希望各位高人都来看看,谢谢了!

#5


void   loadingThread::run() 


          thread_model   =   new   PDFModel(); 
                    connect(thread_model,SIGNAL(documentLoaded()),this,SLOT(slot_document_opened())); 

          thread_model-> load(QString( "%1/%2 ").arg(filepath).arg(pdfName)); 
  
          exec(); 本人水平有限,没看出来这个exec()有什么用途? 

#6


引用 5 楼  的回复:
void   loadingThread::run() 


          thread_model   =   new   PDFModel(); 
                    connect(thread_model,SIGNAL(documentLoaded()),this,SLOT(slot_document_opened())); 

        ……

exec就是进入当前线程的消息循环

#7


引用 6 楼  的回复:
引用 5 楼  的回复:

void   loadingThread::run()
{

thread_model   =   new   PDFModel();
connect(thread_model,SIGNAL(documentLoaded()),this,SLOT(slot_document_opened()));

……

exec就是进入当前线程的消息循环


正解,问题是如果不加载数据,那么缓冲界面立即出来,如果用子线程加载数据,那么缓冲界面则不出来,不知道是什么原因。。很头疼!!!

#1


等下  你确定你用了多线程?    貌似你只是用了定时器吧   定时器不会并发运行的    如果有两个定时器,  定时器一在运行的话 定时器二就算时间到了也是无法运行的。  定时器和多线程貌似是两码事。

你的做法的问题在于:当你加载数据时 运行你所说的子线程,此时你所说的主线程也是出于等待状体的,主线程一停下来 界面当然就卡了 所以想让主界面不卡就必须要用多线程 而不是定时器。  

#2


1  检查子线程,看线程内部是不是写得有问题,导致事实上是在同一个线程里运行?
2  虽然定时器优先级较低,但一般也不致于被其它线程强占cpu而定时器不工作,请确认你的加载缓冲界面和子线程之间的代码顺序和逻辑关系。
3  按你的实现思路写一个小例子来试,如果还是不行,发上来大家帮看一下。

#3


引用 1 楼  的回复:
等下  你确定你用了多线程?    貌似你只是用了定时器吧   定时器不会并发运行的    如果有两个定时器,  定时器一在运行的话 定时器二就算时间到了也是无法运行的。  定时器和多线程貌似是两码事。

你的做法的问题在于:当你加载数据时 运行你所说的子线程,此时你所说的主线程也是出于等待状体的,主线程一停下来 界面当然就卡了 所以想让主界面不卡就必须要用多线程 而不是定时器。


我还是要说明一下的好,我确实是使用了多线程,不知道你从哪里得出我只用了定时器。主线程和子线程并发执行,所以你所说的主线程处于等待状态的理由是什么??

#4


引用 2 楼  的回复:
1  检查子线程,看线程内部是不是写得有问题,导致事实上是在同一个线程里运行?
2  虽然定时器优先级较低,但一般也不致于被其它线程强占cpu而定时器不工作,请确认你的加载缓冲界面和子线程之间的代码顺序和逻辑关系。
3  按你的实现思路写一个小例子来试,如果还是不行,发上来大家帮看一下。

好的,我把代码贴上来,请大神帮我看看,谢谢了!
因为子线程显示UI 会有各种问题,所以我主线程显示缓冲的页面,子线程加载数据,数据加载结束后,主线程缓冲界面消失,显示加载完成的数据。

下面是代码:
   主线程{

   buffer = new loadingBuffer(whiteBackground);// 这个buffer就是缓冲界面,whiteBackground为父Item;

   buffer->bufferStart(); //缓冲界面的定时器开始;
   
   if(load_thread != NULL)
   {
         load_thread->quit();
         delete load_thread;
   }
 
   load_thread = new loadingThread(filename);//load_thread 为定义的多线程类的指针
              connect(load_thread,SIGNAL(documentloaded(PDFModel*)),this,SLOT(slot_kill_buffer(PDFM  odel*)));//加载完成就把缓冲界面kill掉。
 
   load_thread->start();//调用run函数,开始加载。

}


子线程{
    
void loadingThread::run()
{

     thread_model = new PDFModel();
          connect(thread_model,SIGNAL(documentLoaded()),this,SLOT(slot_document_opened()));

     thread_model->load(QString("%1/%2").arg(filepath).arg(pdfName));
 
     exec();
}
void loadingThread::slot_document_opened()
{
     emit documentloaded(thread_model);
}

}

接受到子线程发出的信号后,主线程{

void pdfCategory::slot_kill_buffer(PDFModel *model)
{
     buffer->bufferStop();    //stop缓冲界面
 
     if(m_pdf!=NULL)
     {
         delete m_pdf;
     }

     m_pdf = new PDFScreen(model);           //一下三行就是显示加载完成的数据,是一个pdf文件
     m_pdf->setParentItem(whiteBackground);
     m_pdf->createUi();
 }

}

 希望各位高人都来看看,谢谢了!

#5


void   loadingThread::run() 


          thread_model   =   new   PDFModel(); 
                    connect(thread_model,SIGNAL(documentLoaded()),this,SLOT(slot_document_opened())); 

          thread_model-> load(QString( "%1/%2 ").arg(filepath).arg(pdfName)); 
  
          exec(); 本人水平有限,没看出来这个exec()有什么用途? 

#6


引用 5 楼  的回复:
void   loadingThread::run() 


          thread_model   =   new   PDFModel(); 
                    connect(thread_model,SIGNAL(documentLoaded()),this,SLOT(slot_document_opened())); 

        ……

exec就是进入当前线程的消息循环

#7


引用 6 楼  的回复:
引用 5 楼  的回复:

void   loadingThread::run()
{

thread_model   =   new   PDFModel();
connect(thread_model,SIGNAL(documentLoaded()),this,SLOT(slot_document_opened()));

……

exec就是进入当前线程的消息循环


正解,问题是如果不加载数据,那么缓冲界面立即出来,如果用子线程加载数据,那么缓冲界面则不出来,不知道是什么原因。。很头疼!!!