在GUI线程

时间:2016-11-27 08:11:02

标签: c++ qt qt5 qwidget qthread

我在没有GUI阻止的QWidget设备上尝试render QPrinter

我的打印方法如下:

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类是不可能的   比主线程更容易通过put来解决   在单独的工作线程中进行耗时的操作并显示   当工作线程在主线程中的屏幕上的结果   完成

我修改了Mandelbrot Example,但在我的案例中屏幕上没有显示任何内容。我的Widget应该被渲染(耗时的操作)并被发送到打印机。

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

1 个答案:

答案 0 :(得分:1)

如果窗口小部件paintEvent没有做太多计算,那么将窗口小部件渲染到QPicture非常快。 QPicture只是所有画家电话的记录。然后,您可以在并发作业中在打印机上重放它们。

或者,您可以确保不使用主线程中的窗口小部件(通过保持不可见而没有父窗口),然后从任何线程调用render都可以。