我正在尝试在没有GUI阻塞的QPrinter
设备上渲染QWidget
:
我的打印方法看起来像这样:
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是重新进入的,但GUI类,尤其是Qwidget和 它的所有子类都不是重新进入的。它们只能从 主线程。如前所述,qcoreapplication :: exec()也必须是 从该线程调用。
以及:
实际上,在其他线程中使用GUI类的不可能 比主线程可以通过放置可以轻松地处理 在单独的工作线程中耗时的操作并显示 当工作线程为时,主线程中的屏幕上的结果 完成
我已经修改了Mandelbrot示例,但是在我的情况下,屏幕上没有显示任何内容。我的小部件应渲染(耗时的操作),并发送到打印机。
那么,您是否有任何考虑我的情况?
如果小部件的paintEvent
不执行太多计算,那么将小部件渲染到QPicture
会非常快。QPicture
只是所有画家电话的记录。然后,您可以在并发工作中在打印机上重播它们。
另外,您可以确保不从主线程(通过保持不可见且没有父母)使用小部件,然后可以从任何线程调用render
。