c++ - QT 鼠标移动事件是否在单独的线程中?以及如何解决与此相关的绘画应用程序问题

标签 c++ multithreading qt graphics overflow

我正在制作一个绘画程序,使用圆形画笔在 3D 网格上绘画。由于我指定要更改为画笔颜色的区域的方式,我相信 MouseMove 事件的触发速度比程序完成绘制的速度更快,因此它不仅仅是将圆圈更改为不同的颜色,而是溢出并结束绘制整个网格。

在 mouseMove 上调用以下方法:

void Mesh::setCircle(Face *face, int radius, Color color) {
    for (unsigned int i = 0; i < mouseOvers.size(); i++)
        faceList[mouseOvers[i]].mouseOver = false;
    mouseOvers.clear();

    ...
    // finds the faces on the mesh around the centerIndex on the circle (just the outline of the circle)
    // calls face->mouseOver = true; for each of those faces
    // adds the indices of the faces to mouseOvers
}

上面是用来给出画笔在网格上的轮廓,让用户知道他们要画什么。当用户单击鼠标按钮时,将调用以下内容:

void Mesh::getAdjacent(Face *face, vector<Face *> &adjacent) {
    for (unsigned int i = 0; i < mouseOvers.size(); i++)
        adjacent.push_back(&faceList[mouseOvers[i]]);

    int currentUp = face->listIndex;
    int currentDown = currentUp;
    helperGetAdjacent(currentUp, adjacent);

    while (!faceList[currentUp].mouseOver) {
        //up
        if (currentUp >= numCols) {
            currentUp -= numCols;
            helperGetAdjacent(currentUp, adjacent);
        }
        else
            break;
    }
    while (!faceList[currentDown].mouseOver) {
        //down
        if (currentDown < numCols * (numRows-1)) {
            currentDown += numCols;
            helperGetAdjacent(currentDown, adjacent);
        }
        else
            break;
    }
}

void Mesh::helperGetAdjacent(int trunk, vector<Face *> &adjacent) {
    int currentRight = trunk;
    int currentLeft = trunk;

    adjacent.push_back(&faceList[trunk]);

    while (!faceList[currentRight].mouseOver) {
        // check right
        if (currentRight % numCols != numCols - 1) {
            adjacent.push_back(&faceList[currentRight + 1]);
            currentRight++;
        }
        else
            break;
    }
    while (!faceList[currentLeft].mouseOver) {
        //check left
        if (currentLeft % numCols != 0) {
            adjacent.push_back(&faceList[currentLeft - 1]);
            currentLeft--;
        }    
        else
            break;
    }
}

上面代码的简短摘要,我在 faces 中使用 mouseOver 属性来确定何时停止将面添加到 adjacent(它在另一个函数中返回并着色)。

现在,这在用户只需单击鼠标时就起作用了。当用户在按住它的同时拖动它时,我只是再次调用 getAdjacent 函数。如果用户移动鼠标的速度足够慢,则会出现预期的行为(面部像刷子一样被鼠标着色),但如果用户拖动得更快(这并不是真的很快),整个网格都会被着色。

我怀疑是在另一个线程中调用了 mousemove 事件,导致 setCircle 函数在 getAdjacent 函数完成之前被调用。 Face 中的 mouseOver 成员更改为 false,getAdjacent 没有停在正确的位置。

我该如何解决这个问题?

非常感谢!

最佳答案

你的怀疑是不正确的...Qt 只使用一个线程(主线程)来处理它的 GUI 内容。所以你的问题在别的地方。它可能是你代码中的一个错误(我不会尝试调试这里的逻辑,因为我认为我不能做得很好),或者可能是 Qt 在可能的情况下组合 MouseMove 事件(以如果回调返回缓慢,请避免不断延长的事件队列),这可能不是您的代码所期望的。

关于c++ - QT 鼠标移动事件是否在单独的线程中?以及如何解决与此相关的绘画应用程序问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4481308/

相关文章:

Qt 5.11 : Touch input inverted in my application

c# - 异步/等待单线程/一些线程

Java - TCP - 多线程服务器 - 如何处理多个客户端连接?

c++ - MRPT Graph Slam 最小示例

c++ - LookAt(glm)返回错误的转换z值

multithreading - 我应该如何对多线程代码进行单元测试?

c++ - QMetaType::Type来自模板类型

c++ - Qt 中的切换开关

c++ - STL 容器中的内存释放

c++ - 非STL函数对象回调使用