我有一个窗口,其中包含要导出到.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]
答案 0 :(得分:0)
当我尝试将QWidget绘制到QImage时,有什么可能出错的吗?
是的。渲染过载的documentation使画家明确指出画家必须活动,这意味着它只应在绘画事件中使用。
考虑使用带有QPaintDevice的其他重载。