QIidget上的QWidget :: render()

时间:2016-01-27 13:51:35

标签: c++ qt assert qwidget qimage

我有一个窗口,其中包含要导出到.png文件的内容。我正在使用它的渲染功能在QImage上呈现它:

QLOG("Image export mode");
const QString refpath = seq_->item(0)->path(0);
QImage refimg(refpath);
const QSize imgsize = refimg.size();
QLOG("image size: " << imgsize);
Q_ASSERT(mapwin_);
mapwin_->resize(imgsize);
// the window doesn't seem to fit the image well the first time around, so do it
// once and disregard the result - no idea why this happens.
mapwin_->showImage(refimg);
QImage winimage(mapwin_->size(), QImage::Format_ARGB32);
emit mapFit();
QPainter painter(&winimage);
emit renderWindow(&painter);

emit message("Exporting images");
emit startProgress(itemIndices_.size());

// iterate over indices of selected images in sequence
for (int i = 0; i < itemIndices_.size(); ++i)
{
    const int itemidx = itemIndices_.at(i);
    Q_ASSERT(itemidx >= 0);
    const SeqItem *item = seq_->item(itemidx);
    Q_ASSERT(item->mapExists());
    QLOG("Item " << i << " (" << itemidx << "): '" << item->filename(0) << "'");
    QLOGINC;

    // iterate over selected displacement components
    for (int ci = 0; ci < cci::VAL_COUNT; ++ci)
    {
        const cci::ValueID id = cci::VAL_ID[ci];
        if (!dcomp_.active(id)) continue;
        const QString label = ValueIDWrapper(id).shortName();
        QLOG("Active value: " << label);

        mapwin_->setValueID(id);
        emit mapIndexUpdate(itemidx);
        emit mapFit();
        emit renderWindow(&painter);

        const QString exportpath = dirPath_ + "/" + item->filename(0).remove(".bmp", Qt::CaseSensitive) + "_" + label + ".png";
        winimage.save(exportpath);
    }

    emit makeProgress();
    QLOGDEC;
}

我通过向gui线程(emit renderwindow)发出信号来完成以下操作:

void MapWindow::renderOn(QPainter *image)
{
    render(image, QPoint(), QRegion(), QWidget::DrawChildren);
}

不幸的是,当我运行此代码时,我会在发出信号后得到QT ASSERT:[错误窗口] [1]。当我尝试将QWidget绘制到QImage时会出现什么问题吗?

ASSERT上的整个callstack(有了这些信息,我推断它是renderOn方法的问题,因为它是异常之前的最后一个):

Qt5Cored.dll!qt_message_fatal(QtMsgType __formal, const QMessageLogContext & context, const QString & message) Line 1571    C++
Qt5Cored.dll!QMessageLogger::fatal(const char * msg, ...) Line 781  C++
Qt5Cored.dll!qt_assert(const char * assertion, const char * file, int line) Line 2967   C++
Qt5Widgetsd.dll!QGraphicsSceneBspTreeIndexPrivate::estimateItems(const QRectF & rect, Qt::SortOrder order, bool onlyTopLevelItems) Line 379 C++
Qt5Widgetsd.dll!QGraphicsSceneBspTreeIndex::estimateTopLevelItems(const QRectF & rect, Qt::SortOrder order) Line 535    C++
Qt5Widgetsd.dll!QGraphicsScenePrivate::drawItems(QPainter * painter, const QTransform * const viewTransform, QRegion * exposedRegion, QWidget * widget) Line 4689   C++
Qt5Widgetsd.dll!QGraphicsView::paintEvent(QPaintEvent * event) Line 3540    C++
Qt5Widgetsd.dll!QWidget::event(QEvent * event) Line 8831    C++
Qt5Widgetsd.dll!QFrame::event(QEvent * e) Line 540  C++
Qt5Widgetsd.dll!QAbstractScrollArea::viewportEvent(QEvent * e) Line 1200    C++
Qt5Widgetsd.dll!QGraphicsView::viewportEvent(QEvent * event) Line 2963  C++
Qt5Widgetsd.dll!QAbstractScrollAreaPrivate::viewportEvent(QEvent * event) Line 102  C++
Qt5Widgetsd.dll!QAbstractScrollAreaFilter::eventFilter(QObject * o, QEvent * e) Line 118    C++
Qt5Cored.dll!QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject * receiver, QEvent * event) Line 1072   C++
Qt5Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 3712    C++
Qt5Widgetsd.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3681  C++
Qt5Cored.dll!QCoreApplication::notifyInternal(QObject * receiver, QEvent * event) Line 965  C++
>Qt5Cored.dll!QCoreApplication::sendSpontaneousEvent(QObject * receiver, QEvent * event) Line 227   C++
Qt5Widgetsd.dll!QWidgetPrivate::sendPaintEvent(const QRegion & toBePainted) Line 5628   C++
Qt5Widgetsd.dll!QWidgetPrivate::drawWidget(QPaintDevice * pdev, const QRegion & rgn, const QPoint & offset, int flags, QPainter * sharedPainter, QWidgetBackingStore * backingStore) Line 5569  C++
Qt5Widgetsd.dll!QWidgetPrivate::paintSiblingsRecursive(QPaintDevice * pdev, const QList<QObject *> & siblings, int index, const QRegion & rgn, const QPoint & offset, int flags, QPainter * sharedPainter, QWidgetBackingStore * backingStore) Line 5761    C++
Qt5Widgetsd.dll!QWidgetPrivate::drawWidget(QPaintDevice * pdev, const QRegion & rgn, const QPoint & offset, int flags, QPainter * sharedPainter, QWidgetBackingStore * backingStore) Line 5619  C++
Qt5Widgetsd.dll!QWidgetPrivate::paintSiblingsRecursive(QPaintDevice * pdev, const QList<QObject *> & siblings, int index, const QRegion & rgn, const QPoint & offset, int flags, QPainter * sharedPainter, QWidgetBackingStore * backingStore) Line 5761    C++
Qt5Widgetsd.dll!QWidgetPrivate::paintSiblingsRecursive(QPaintDevice * pdev, const QList<QObject *> & siblings, int index, const QRegion & rgn, const QPoint & offset, int flags, QPainter * sharedPainter, QWidgetBackingStore * backingStore) Line 5748    C++
Qt5Widgetsd.dll!QWidgetPrivate::paintSiblingsRecursive(QPaintDevice * pdev, const QList<QObject *> & siblings, int index, const QRegion & rgn, const QPoint & offset, int flags, QPainter * sharedPainter, QWidgetBackingStore * backingStore) Line 5748    C++
Qt5Widgetsd.dll!QWidgetPrivate::paintSiblingsRecursive(QPaintDevice * pdev, const QList<QObject *> & siblings, int index, const QRegion & rgn, const QPoint & offset, int flags, QPainter * sharedPainter, QWidgetBackingStore * backingStore) Line 5748    C++
Qt5Widgetsd.dll!QWidgetPrivate::drawWidget(QPaintDevice * pdev, const QRegion & rgn, const QPoint & offset, int flags, QPainter * sharedPainter, QWidgetBackingStore * backingStore) Line 5619  C++
Qt5Widgetsd.dll!QWidgetPrivate::paintSiblingsRecursive(QPaintDevice * pdev, const QList<QObject *> & siblings, int index, const QRegion & rgn, const QPoint & offset, int flags, QPainter * sharedPainter, QWidgetBackingStore * backingStore) Line 5761    C++
Qt5Widgetsd.dll!QWidgetPrivate::drawWidget(QPaintDevice * pdev, const QRegion & rgn, const QPoint & offset, int flags, QPainter * sharedPainter, QWidgetBackingStore * backingStore) Line 5619  C++
Qt5Widgetsd.dll!QWidgetPrivate::render(QPaintDevice * target, const QPoint & targetOffset, const QRegion & sourceRegion, QFlags<enum QWidget::RenderFlag> renderFlags) Line 5705    C++
Qt5Widgetsd.dll!QWidget::render(QPainter * painter, const QPoint & targetOffset, const QRegion & sourceRegion, QFlags<enum QWidget::RenderFlag> renderFlags) Line 5145  C++
Qt5Widgetsd.dll!QWidget::render(QPaintDevice * target, const QPoint & targetOffset, const QRegion & sourceRegion, QFlags<enum QWidget::RenderFlag> renderFlags) Line 5068   C++
ccigui.exe!MapWindow::renderOn(QImage * image) Line 453 C++
ccigui.exe!MapWindow::qt_static_metacall(QObject * _o, QMetaObject::Call _c, int _id, void * * _a) Line 475 C++
Qt5Cored.dll!QMetaCallEvent::placeMetaCall(QObject * object) Line 487   C++
Qt5Cored.dll!QObject::event(QEvent * e) Line 1239   C++
Qt5Widgetsd.dll!QWidget::event(QEvent * event) Line 9105    C++
Qt5Widgetsd.dll!QMdiSubWindow::event(QEvent * event) Line 2917  C++
Qt5Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 3716    C++
Qt5Widgetsd.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3681  C++
Qt5Cored.dll!QCoreApplication::notifyInternal(QObject * receiver, QEvent * event) Line 965  C++
Qt5Cored.dll!QCoreApplication::sendEvent(QObject * receiver, QEvent * event) Line 224   C++
Qt5Cored.dll!QCoreApplicationPrivate::sendPostedEvents(QObject * receiver, int event_type, QThreadData * data) Line 1593    C++
Qt5Cored.dll!QEventDispatcherWin32::sendPostedEvents() Line 1242    C++
qwindowsd.dll!QWindowsGuiEventDispatcher::sendPostedEvents() Line 84    C++
Qt5Cored.dll!qt_internal_proc(HWND__ * hwnd, unsigned int message, unsigned __int64 wp, __int64 lp) Line 416    C++
[External Code] 
Qt5Cored.dll!QEventDispatcherWin32::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 818    C++
qwindowsd.dll!QWindowsGuiEventDispatcher::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 74   C++
Qt5Cored.dll!QEventLoop::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 129   C++
Qt5Cored.dll!QEventLoop::exec(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 204    C++
Qt5Widgetsd.dll!QDialog::exec() Line 542    C++
ccigui.exe!Corr2DProject::handle_exportShow(int type, int seqidx) Line 387  C++
ccigui.exe!CCIGui::slot_anal_exportClicked() Line 1324  C++
ccigui.exe!CCIGui::qt_static_metacall(QObject * _o, QMetaObject::Call _c, int _id, void * * _a) Line 464    C++
Qt5Cored.dll!QMetaObject::activate(QObject * sender, int signalOffset, int local_signal_index, void * * argv) Line 3715 C++
Qt5Cored.dll!QMetaObject::activate(QObject * sender, const QMetaObject * m, int local_signal_index, void * * argv) Line 3579    C++
Qt5Widgetsd.dll!QAbstractButton::clicked(bool _t1) Line 304 C++
Qt5Widgetsd.dll!QAbstractButtonPrivate::emitClicked() Line 536  C++
Qt5Widgetsd.dll!QAbstractButtonPrivate::click() Line 528    C++
Qt5Widgetsd.dll!QAbstractButton::mouseReleaseEvent(QMouseEvent * e) Line 1133   C++
Qt5Widgetsd.dll!QWidget::event(QEvent * event) Line 8679    C++
Qt5Widgetsd.dll!QAbstractButton::event(QEvent * e) Line 1090    C++
Qt5Widgetsd.dll!QPushButton::event(QEvent * e) Line 674 C++
Qt5Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 3716    C++
Qt5Widgetsd.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3276  C++
Qt5Cored.dll!QCoreApplication::notifyInternal(QObject * receiver, QEvent * event) Line 965  C++
Qt5Cored.dll!QCoreApplication::sendSpontaneousEvent(QObject * receiver, QEvent * event) Line 227    C++
Qt5Widgetsd.dll!QApplicationPrivate::sendMouseEvent(QWidget * receiver, QMouseEvent * event, QWidget * alienWidget, QWidget * nativeWidget, QWidget * * buttonDown, QPointer<QWidget> & lastMouseReceiver, bool spontaneous) Line 2770  C++
Qt5Widgetsd.dll!QWidgetWindow::handleMouseEvent(QMouseEvent * event) Line 556   C++
Qt5Widgetsd.dll!QWidgetWindow::event(QEvent * event) Line 211   C++
Qt5Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 3716    C++
Qt5Widgetsd.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3160  C++
Qt5Cored.dll!QCoreApplication::notifyInternal(QObject * receiver, QEvent * event) Line 965  C++
Qt5Cored.dll!QCoreApplication::sendSpontaneousEvent(QObject * receiver, QEvent * event) Line 227    C++
Qt5Guid.dll!QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent * e) Line 1792  C++
Qt5Guid.dll!QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent * e) Line 1582    C++
Qt5Guid.dll!QWindowSystemInterface::sendWindowSystemEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 626   C++
qwindowsd.dll!QWindowsGuiEventDispatcher::sendPostedEvents() Line 85    C++
Qt5Cored.dll!qt_internal_proc(HWND__ * hwnd, unsigned int message, unsigned __int64 wp, __int64 lp) Line 416    C++
[External Code] 
Qt5Cored.dll!QEventDispatcherWin32::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 818    C++
qwindowsd.dll!QWindowsGuiEventDispatcher::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 74   C++
Qt5Cored.dll!QEventLoop::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 129   C++
Qt5Cored.dll!QEventLoop::exec(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 204    C++
Qt5Cored.dll!QCoreApplication::exec() Line 1229 C++
Qt5Guid.dll!QGuiApplication::exec() Line 1528   C++
Qt5Widgetsd.dll!QApplication::exec() Line 2977  C++
ccigui.exe!main(int argc, char * * argv) Line 41    C++
ccigui.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * __formal, int __formal) Line 113  C++
[External Code] 

1 个答案:

答案 0 :(得分:0)

  

当我尝试将QWidget绘制到QImage时,有什么可能出错的吗?

是的。渲染过载的documentation使画家明确指出画家必须活动,这意味着它只应在绘画事件中使用。

考虑使用带有QPaintDevice的其他重载。

相关问题