vtkCaptionWidget interferes with Qt C++ Application quit

I am using vtkCaptionWidget to annotate the 2D image loaded in qvtkwidget. However once the caption widget is placed on the image QApplication::exit(0) doesn’t work. Even if the window is closed by calling close() function, application runs in the background.

This is my code for caption written in a clickcallback function

auto* iren = static_cast<vtkRenderWindowInteractor*>(caller);

    vtkSmartPointer<vtkCoordinate> coordinate = vtkSmartPointer<vtkCoordinate>::New();
    coordinate->SetCoordinateSystemToDisplay();
    coordinate->SetValue(iren->GetEventPosition()[0],iren->GetEventPosition()[1],0);

    double* world = coordinate->GetComputedWorldValue(iren->GetRenderWindow()->GetRenderers()->GetFirstRenderer());
    double pos[3] = {world[0], world[1], 0};

    std::string str = annotText.toStdString();
    const char* cText = str.c_str();

    vtkTextProperty *tprop = vtkTextProperty:: New();
    tprop->SetFontFamilyToArial();
    tprop->SetFontSize(14);
    tprop->BoldOn();
    tprop->ShadowOn();
    tprop->ItalicOn();
    tprop->SetColor(1, 1, 1);

    vtkNew<vtkCaptionRepresentation> captionRepresentation;
    captionRepresentation->GetCaptionActor2D()->GetTextActor()->SetTextScaleMode(1);
    captionRepresentation->GetCaptionActor2D()->SetCaptionTextProperty(tprop);
    captionRepresentation->GetCaptionActor2D()->SetCaption(cText);
    captionRepresentation->GetCaptionActor2D()->BorderOn();
    captionRepresentation->GetCaptionActor2D()->ThreeDimensionalLeaderOff();
    captionRepresentation->GetCaptionActor2D()->SetMaximumLeaderGlyphSize(10);
    //captionRepresentation->GetCaptionActor2D()->GetPositionCoordinate()->SetCoordinateSystemToViewport();
    captionRepresentation->SetPosition(0.7,0.3);
    captionRepresentation->SetPosition2(0.1,0.03);
    captionRepresentation->SetAnchorPosition(pos);

    vtkNew<vtkCaptionWidget> captionWidget;
    captionWidget->SetInteractor(iren);
    captionWidget->SetRepresentation(captionRepresentation);
    captionWidget->On();
    iren->Start();

This is the code in quit button click

    QApplication::exit(0);
    ui->~MainWindow();

What could be causing this. This doesn’t arise on placing any other widgets like distance or angle widget.

Hello,

Is there any reason to explicitly call QApplication::exit()? Once the application’s last QWidget gets destroyed, the UI’s event loop (QApplication::exec()) returns. If it is the last call in your program, the program finishes. You don’t need to call QApplication::exit() explicitly. Also, you’re not supposed to call a destructor like that. It either gets called by delete or when a stack or static object goes out of scope.

take care,

Paulo

You can try calling the MainWindow::close() slot from the button click to finish your program.

Hello… I have tried calling close(). The window shuts down. However the next time i try to build the application, previous instance is seen as crashed - which means it was running in background and didn’t have a normal exit.

This issue occurs only when we place the caption widget. No problem whatsoever otherwise. Was wondering why.

Do you have other Qt applications other than Qt Creator and your own?

Apologies for the late reply. No other applications other than Qt creator and mine are on the device. Could you say what implications are there if another one exists

Ill-written Qt applications may leave the Qt dynamic libraries in memory. I’ve seen such issue before.

Pelase, take a look at this: resources - Correct way to quit a Qt program? - Stack Overflow

And, again, don’t call the window’s destructor like you did. BTW, never explictly call any destructor.

1 Like

This hasn’t been resolved yet. Can’t figure out why placing a widget is affecting the exit of application. Searching for any possible background processes

Hello,

I believe it’s time to use a debugger. Do you have Qt and VTK compiled in debug mode?

best,

PC

This might be a clue… I’m not using QT but Windows Forms, but this still this seems related. Also note I was using VTK 8.1 at the time; haven’t been able to test on a newer version yet.

When I recently added a vtkCaptionWidget to my scene, I suddenly started getting crashes on exiting my application when destroying the RenderWindowInteractor and RenderWindow. I don’t remember all the details but having a vtkCaptionWidget introduced into the mix somehow resulted in one object calling a method on the other after it was already deleted (I believe it was during a call to vtkCaptionWidget::SetEnabled(0) that occurred during the destruction sequence).

In my case I fixed by manually breaking the relationship between the RenderWindow and the RenderWindowInteractor before I started deleting everything:

void Viewport::RenderWindowControl::OnHandleDestroyed(System::EventArgs^ e)
{
	if (m_Renderer != nullptr)
	{
		m_Renderer->SetRenderWindow(nullptr);
	}

    m_RenderWindow->SetInteractor(nullptr); // <--- this is necessary to avoid a crash if vtkCaptionWidget is present

	if (m_RenderWindowInteractor != nullptr)
	{
		m_RenderWindowInteractor->Delete();
		m_RenderWindowInteractor = nullptr;
	}

	if (m_RenderWindow != nullptr)
	{
		m_RenderWindow->Delete();
		m_RenderWindow = nullptr;
	}

	if (m_Renderer != nullptr)
	{
		m_Renderer->Delete();
		m_Renderer = nullptr;
	}

	System::Windows::Forms::UserControl::OnHandleDestroyed(e);
}

I’m not familiar with the Qt shutdown sequence, but if you’re hitting a similar access violation as I was, then maybe it’s throwing a wrench into the shutdown process?

Anyway, good luck!

Its is compiled in release mode

Thank you so much for the response. Yes I am experiencing something similar to what you have described. Though couldn’t pinpoint what function call is active after shutdown. Will give your method a try.

Hello,

I know that Qt objects are managed internally if you give them a parent, chances are that’s the case for VTK objects. I don’t explicitly call their destructors, unless I want to remove a vtkActor from the scene. Maybe you’re experiencing what is termed a “double free”.

take care,

PC

An update to this…

I’ve since began using other widgets (vtkDistanceWidget, vtkAngleWidget) in addition to vtkCaptionWidget and the line I added above seems to cause other issues on application shutdown with those widget types involved. Therefore, I had to remove that line, and after much trial and error I’ve found the best thing to do on application shutdown is to simply call the Delete() method on all the widgets before deleting the RenderWindowInteractor, RenderWindow and Renderer. This seems to work fine for all widget types I’ve tried - no crashes.

2 Likes