【问题标题】:why cant I draw points on the Qt Widget at the first time I click the button为什么我第一次单击按钮时不能在 Qt Widget 上绘制点
【发布时间】:2016-05-05 05:35:07
【问题描述】:

我想在 Widget 上画一些点,所以我将 Widget 提升到类。并且点的信息(例如,位置、颜色、数量)需要从类外获取,所以我设置了一个槽来接收信息。在获取数量之前,我将其设置为零。

这是班级的cpp文件,

#include "glwidget.h"

GLWidget::GLWidget(QWidget *parent) :
    QGLWidget(parent)
{
    pointClouds = NULL; //[x y z]
    imageRGB = NULL;    //[R G B]
    oldx = -1, oldy = -1;
    c = (float)(CV_PI / 180); theta = 0,
    rho = 0; zoom = 1;
    height = 0; width = 0;

    connect(&timer, SIGNAL(timeout()), this, SLOT(updateGL()));
    timer.start(16);
}

void GLWidget::initializeGL()
{
    glClearColor((GLclampf)0, (GLclampf)0, \
                 (GLclampf)0, (GLclampf)1);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE\
                        | GLUT_RGBA);
}

void GLWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glLoadIdentity();
    gluLookAt(eyex, eyey, eyez, centerx, centery, centerz, 0, -1, 0);
    glScalef((GLfloat)zoom, (GLfloat)zoom, (GLfloat)zoom);
    glPointSize(1.0);
    glBegin(GL_POINTS);
        for (int i = 0; i < height*width*3; i+=3)
        {
            glColor3f(imageRGB[i], imageRGB[i + 1], imageRGB[i + 2]);
            glVertex3f(pointClouds[i], pointClouds[i + 1], 
pointClouds[i + 2]);
        }
    glEnd();
    glFlush();
}

void GLWidget::resizeGL(int w, int h)
{
    glViewport(0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60, (GLfloat)w / (GLfloat)h, 1.0, 500.0);
    glMatrixMode(GL_MODELVIEW);
}

void GLWidget::mousePressEvent(QMouseEvent *)
{

}

void GLWidget::mouseMoveEvent(QMouseEvent *)
{

}


void GLWidget::receiveMatandImage(cv::Mat xyz, cv::Size imageSize, \
                                  cv::Mat rviewLeft)
{
    width = imageSize.width; height = imageSize.height;
    pointClouds = new float[height*width*3];
    int number  = 0;
    for(int i = 0; i < height; i++)
    {
        for(int j = 0; j < width; j++)
        {
            cv::Vec3f points = xyz.at<cv::Vec3f>(i,j);
            pointClouds[3 * (i*width + j)] = points[0];     //x
            pointClouds[3 * (i*width + j) + 1] = points[1];     //y
            pointClouds[3 * (i*width + j) + 2] = points[2];     //z

            if (points[2] <= 9999 && points[2]>0)   //discard mismatched points
            {
                number += 1;
                centerx += points[0]; centery += points[1];
                centerz += points[2];
            }
        }
    }
    centerx /= number; centery /= number; centerz /= number;
    eyez0 = -10.0f; eyex0 = centerx; eyey0 = centery;
    r = centerz - eyez0; eyex = eyex0; eyey = eyey0;
    eyez = eyez0;

    /*save the RGB Info*/
    rviewLeft.convertTo(rviewLeft, CV_8UC3);
    imageRGB = new float[height*width * 3];
    for (int i = 0; i < height; i++)
    {
        const uchar* ptr = rviewLeft.ptr<uchar>(i);
        for (int j = 0; j < width * 3; j++)
        {
            int tempIdx = i*width * 3 + j;
            switch (tempIdx % 3)
            {
            case 0:
                imageRGB[tempIdx] = ptr[j + 2] / 255.0f;
                break;
            case 1:
                imageRGB[tempIdx] = ptr[j] / 255.0f;
                break;
            case 2:
                imageRGB[tempIdx] = ptr[j - 2] / 255.0f;
                break;
            default:
                break;
            }
        }
    }
}

void GLWidget::receiveMatandImage(cv::Mat xyz, cv::Size imageSize, \ cv::Mat rviewLeft)这一行是接收点信息的槽,对应的信号来自这部分,

void MainWindow::on_pushButton_4_clicked()
{
    t = time(0);
    localtime_s(&timeInfo, &t);
    asctime_s(timeNow,&timeInfo);
    len = strlen(timeNow);
    timeNow[len-1] = 0;

    ui->textBrowser->append(timeNow);
    ui->textBrowser->append("computing the points cloud...");
    cv::reprojectImageTo3D(disp, xyz, Q, true);
    ui->textBrowser->append("computing completed");

    connect(this, SIGNAL(sendMatandImage(cv::Mat,cv::Size,cv::Mat)), \
        ui->widget, SLOT(receiveMatandImage(cv::Mat,cv::Size,cv::Mat)));

    emit sendMatandImage(xyz, imageSize, rviewLeft);
}

问题是当我第一次单击按钮(按钮4)时,小部件中没有任何显示,但是当我第二次单击按钮时,点显示得很好。

当我第一次点击按钮时,

第二次点击按钮时,

Qt 愿景:5.1.1

【问题讨论】:

    标签: c++ qt opencv


    【解决方案1】:

    我不太确定,但可能是对QObject::connect() 的调用 当您调用 emit 时异步长且尚未完成。

    如果合适,尝试将QObject::connect() 放入构造函数中,如下所示:

    MainWindow::MainWindow(QWidget *parent) :
                QMainWindow(parent),
                ui(new Ui::MainWindow)
    {
      ui->setupUi(this);
    
      //...
    
      connect(this, SIGNAL(sendMatandImage(cv::Mat,cv::Size,cv::Mat)), \
              ui->widget, SLOT(receiveMatandImage(cv::Mat,cv::Size,cv::Mat)));
    }  
    

    假设在头文件中声明了信号函数。

    希望对你有帮助。

    【讨论】:

    • 我试过你说的,但似乎没有用。无论如何,非常感谢。
    猜你喜欢
    • 2021-11-03
    • 2021-08-09
    • 1970-01-01
    • 2021-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多