印刷QWidget的(渲染)GUI线程之外

问题描述:

我想render一个QWidget一个QPrinter设备上没有GUI阻塞:印刷QWidget的(渲染)GUI线程之外

我的打印方法是这样的:

void MyClass::print() { 
    QPrinter *printer = new QPrinter(QPrinter::HighResolution); 
    printer->setPageSize(QPrinter::A5); 
    printer->setPageOrientation(QPageLayout::Portrait); 
    printer->setColorMode(QPrinter::Color); 
    QPrintDialog *dialog = new QPrintDialog(printer); 

    if (dialog->exec() == QDialog::Accepted) { 
     MyWidget *_widget = new MyWidget(/* args */); 

     QPainter *painter = new QPainter; 
     painter->begin(printer); 
     double xscale = printer->pageRect().width()/double(_widget ->width()); 
     double yscale = printer->pageRect().height()/double(_widget ->height()); 
     double scale = qMin(xscale, yscale); 
     _widget ->setMinimumWidth((printer->pageRect().width()/scale)); 
     _widget ->setMinimumHeight(printer->pageRect().height()/scale); 
     painter->translate(printer->paperRect().x() + printer->pageRect().width()/2, printer->paperRect().y() + printer->pageRect().height()/2); 
     painter->scale(scale, scale); 
     painter->translate(-_widget ->width()/2, -_widget ->height()/2); 
     _widget ->render(painter); 
     painter->end(); 
    } 
    emit done(); 
} 

有了这个功能我有大约1-2秒块的状态,所以我想用QThread对于这个问题,但Qt的Doc说:

尽管QObject的是reentran t,GUI类,特别是QWidget和它的所有子类都不可重入。它们只能从 主线程使用。如前所述,QCoreApplication :: exec()也必须是从该线程调用的 。

而且也:

在实践中,其他线程 比主线程使用GUI类的不可能很容易被周围通过把 耗时的操作在一个单独的工作线程工作,显示 屏幕上的结果,当工作线程是 完成

我修改Mandelbrot Example但t时的主线程这里没有什么可以在我的情况下显示在屏幕上。我的Widget应该呈现(耗时操作)并发送到打印机。

那么你对我的情况有什么想法吗?

+3

1)它在哪里准确地阻止? 2)永远不能从非GUI线程触摸QWidget。 – peppe

+0

@ peppe.1。从我们点击QPrintDialog打印按钮直到它被发送到打印机的位置。在网络打印机上,它大约需要1秒,MyWidget也不复杂 – IMAN4K

+2

一种选择是修改'_widget'它不直接绘制,而是绘制成“QImage”,然后显示该图像。然后,您可以从该插槽中检索该图像,并将副本发送给打印图像的线程。 另一个选择是移动窗口部件的绘图代码到一个带有'QPainter'的类中,然后打印线程可以实例化该类的一个新对象,并使用它就像窗口部件一样。 –

如果小部件的paintEvent没有做太多计算,那么将小部件渲染到QPicture的速度会非常快。 A QPicture只是所有画家要求的记录。然后,您可以在并行作业中的打印机上重播它们。

或者,您可以确保窗口小部件不会从主线程中使用(通过隐藏并且没有父窗口),然后可以从任何线程中调用render

+0

对不起,太迟的回复。这里是基于'QPicture'的建议:http://pastebin.com/xGrj4Ykd但是打印结果很小&混乱:(创建'QPrinter'对象是主要问题,并且阻止了我的GUI是否有其他解决方法? – IMAN4K

+0

您可以完全控制结果的缩放比例,按照您希望的方式缩放它:) –