Microsoft Visual Studio中使用QWT的直方图和立即关闭的Qt插件

时间:2014-01-14 17:18:34

标签: c++ visual-studio-2010 qt opencv qwt

我正在为我的GUI使用Qt add for Visual Studio C ++。

在我的GUI上,我有一个名为plotButton的按钮,它会在单击时绘制图像的直方图。我的绘图选项是通过使用QWT。

然而,它似乎没有绘制任何东西,几乎立即关闭。尝试睡眠(),但它似乎也没有工作。问题可能出在我的代码上吗? 这是我的参考代码:

void qt5test1 ::on_plotButton_clicked()
{
    //Convert to grayscale
    cv::cvtColor(image, image, CV_BGR2GRAY);


    int histSize[1] = {256}; // number of bins
    float hranges[2] = {0.0, 255.0}; // min andax pixel value
    const float* ranges[1] = {hranges};
    int channels[1] = {0}; // only 1 channel used

    cv::MatND hist;
    // Compute histogram
    calcHist(&image, 1, channels, cv::Mat(), hist, 1, histSize, ranges);

    double minVal, maxVal;
    cv::minMaxLoc(hist, &minVal, &maxVal);//Locate max and min values

    QwtPlot plot; //Create plot widget
    plot.setTitle( "Plot Demo" ); //Name the plot
    plot.setCanvasBackground( Qt::black ); //Set the Background colour
    plot.setAxisScale( QwtPlot::yLeft, minVal, maxVal ); //Scale the y-axis
    plot.setAxisScale(QwtPlot::xBottom,0,255); //Scale the x-axis
    plot.insertLegend(new QwtLegend()); //Insert a legend

    QwtPlotCurve *curve = new QwtPlotCurve(); // Create a curve
    curve->setTitle("Count"); //Name the curve
    curve->setPen( Qt::white, 2);//Set colour and thickness for drawing the curve 
    //Use Antialiasing to improve plot render quality
    curve->setRenderHint( QwtPlotItem::RenderAntialiased, true );
    /*Insert the points that should be plotted on the graph in a 
    Vector of QPoints or a QPolgonF */
    QPolygonF points;
    for( int h = 0; h < histSize[0]; ++h) {
        float bin_value = hist.at<float>(h);
        points << QPointF((float)h, bin_value);
    }

    curve->setSamples( points ); //pass points to be drawn on the curve
    curve->attach( &plot ); // Attach curve to the plot 
    plot.resize( 600, 400 ); //Resize the plot
    plot.replot();
    plot.show(); //Show plot
    Sleep(100);
}

加载图像后单击此按钮,会出现一个窗口并立即消失。在输出窗口下,可以找到这些行。

First-chance exception at 0x75d54b32 (KernelBase.dll) in qt5test1.exe: Microsoft C++ exception: cv::Exception at memory location 0x0044939c..
Unhandled exception at 0x75d54b32 (KernelBase.dll) in qt5test1.exe: Microsoft C++ exception: cv::Exception at memory location 0x0044939c..

有人知道我的代码有什么问题吗?谢谢。请再次注意该程序是构建的,并在Microsoft Visual Studio C ++中编写。感谢。

3 个答案:

答案 0 :(得分:2)

问题是你在这里构建一个堆栈对象:

QwtPlot plot; //Create plot widget

确实,您试图在方法结束时显示绘图,但是当您对它们使用exec()时,show()方法不会像QDialog类那样阻塞事件循环。 / p>

它会被处理,但无论如何你都会在通话后离开范围。

有几种方法可以解决这个问题,但我会努力寻找Qt父/子层次结构,在使用指针时会自动删除。

1)Qt父/子关系

QwtPlot *plot = new QwtPlot(this);
                            ^^^^

2)使“情节”成为班级成员

plot.show();

并在类构造函数中构造它。

3)使用智能指针

QSharedPointer<QwtPlot> plot = QSharedPointer<QwtPlot>(new QwtPlot());

这取决于你的课程的进一步背景,所以尝试理解这些方法,并采取你的方式。

答案 1 :(得分:1)

应使用plot创建

new。现在您在堆栈上创建它,因此当on_plotButton_clicked函数完成时它将立即被删除。 Sleep不应该在这里使用,你不会从中获得任何好处。

QwtPlot* plot = new QwtPlot();
plot->setTitle( "Plot Demo" ); //Name the plot
//...
plot->show(); //Show plot

答案 2 :(得分:1)

问题可能是您的QwtPlot只是一个局部变量,即使因为睡眠也在主线程中,您将无法在函数返回之前及时绘制它。然后当它完成睡眠时它会破坏你当地的QwtPlot对象然后返回,所以如果你像那样眨眼就可以运气好。

要使其正常工作,您必须这样称呼它:

QwtPlot* plot = new QwtPlot(this);

其中是将托管您的情节(如果有)的父窗口。这样你的小部件将保持活着状态,直到你关闭它或它的父节点在程序执行结束时销毁它。