c++ - QEvent:: MouseButtonPress 和 QEvent:: MouseMove 以一种奇怪的方式影响 QGraphicsScene
问题描述
我有一个应用程序,我想在图形视图中获取鼠标的位置,并使用它来绘制一对阈值标记来调整同一图形视图中的渐变比例。
graphicsView_gradbar 小部件为 162x22 像素,边框为 1 像素,为灰度图留下 160x20 像素。
我将事件过滤器安装到此视图,然后使用事件处理程序选择相对于此视图的鼠标坐标。
如果我将返回值设置为我认为在处理事件后应该设置的值,则鼠标单击和鼠标移动将得到正确处理,但图形视图未正确显示 - 右侧为空白且边框不正确画。但是在这个区域点击会拾起鼠标正确移动,并将应用程序中绘制的光标移动到正确绘制的图形视图部分。单击视图的正确绘制部分仅响应鼠标单击,而不是单击并按住鼠标时的移动。
如果我将返回值设置为“false”,则渐变条会正确绘制,但它只响应鼠标点击,而不是在点击并按住鼠标时响应鼠标移动。
主窗口功能设置一切。GradbarRefresh 函数在发生新的鼠标点击或移动时重绘渐变条。eventFilter 处理事件并为渐变条中绘制的阈值(红线)生成新坐标。
我只是无法弄清楚为什么图形视图会像这样损坏。
这是标题:- `
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtDebug>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsPixmapItem>
#include <QEvent>
#include <QMouseEvent>
#include <QGraphicsSceneMouseEvent>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
QGraphicsScene *scene_gradbar;
bool eventFilter(QObject *obj, QEvent *event);
private slots:
void GradbarRefresh(int status);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
```
这是main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
这是来源:-
#include "mainwindow.h"
#include "ui_mainwindow.h"
int gradfull_lower; // Full range 255 steps (slider is 160)
int gradfull_upper; // Full range 255 steps (slider is 160)
int grad_lower; // Gradation lower threshold
int grad_upper; // Gradation upper threshold
QGraphicsPixmapItem *histgradbarItem; // Gradation bar pixmap
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
{
ui->setupUi(this);
scene_gradbar = new QGraphicsScene(this);
ui->graphicsView_gradbar->setScene(scene_gradbar);
ui->graphicsView_gradbar->installEventFilter(this); // Install the event filter to this graphics view will send mouse events
// to the filter with the coordinates of this graphicsview item relative mouse position
// ui->graphicsView_gradbar->setMouseTracking(true);
// Initialise gradation range
grad_lower = 0;
grad_upper = 159;
// Set the full histogram ranges from the gradbar values
gradfull_lower = (grad_lower + 1) * 255 / 160;
gradfull_upper = (grad_upper +1) * 255/ 160;
// Initialise the gradation bar
GradbarRefresh(0);
}
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::GradbarRefresh(int status)
{
unsigned char gradationbar[12800]; // Storage for the gradation bar graphic (160x20 pixels, x4 bytes per pixel)
quint8 gradbarval[3]; // For future pseudo red, green or blue scale option may need to set colour
int width;
int height;
int index;
int grad_range;
// Make the gradation bar under the histogram
height = 0;
index = 0;
// Calculate the range of levels
grad_range = grad_upper - grad_lower + 1;
// Greyscale (still RGBA)
// Must be able to do this with one pass of height then some memcopy function for the 19 other rows
do {
width = 0;
do {
if (width < grad_lower ) {
gradbarval[0] = 255; // White if less than the offset
gradbarval[1] = 255;
}
else {
gradbarval[0] = 255 - ((width - grad_lower) * 255 )/ (grad_range); // Calculate the greyscale (0-159 grad_bar range scaled to 0-255 greyscale range)
gradbarval[1] = gradbarval[0]; // For now greyscale and not pseudo colour
}
if (width > (grad_upper)) {
gradbarval[0] = 0; // Black if beyond the gradbar upper level
gradbarval[1] = 0;
}
if ((width == grad_lower) || (width == grad_upper)) { // Set to red if on one of the thresholds
gradbarval[0] = 255;
gradbarval[1] = 0;
}
gradationbar[index] = gradbarval[0]; // Red
index += 1;
gradationbar[index] = gradbarval[1]; // Green
index += 1;
gradationbar[index] = gradbarval[1]; // Blue
index += 1;
gradationbar[index] = 255; // A
index += 1;
width += 1;
} while (width < 160);
height += 1;
} while (height < 20);
// First time pass (status 0) add a pixmap, thereafter (status 1) update the first pixmap
if (status == 0){
histgradbarItem = scene_gradbar->addPixmap(QPixmap::fromImage(QImage(gradationbar, 160, 20, QImage::Format_RGBA8888)));
histgradbarItem->setPos(0 , 0);
} else {
histgradbarItem->setPixmap(QPixmap::fromImage(QImage(gradationbar, 160, 20, QImage::Format_RGBA8888)));
scene_gradbar->update();
}
}
The event filter code that handles the mouse click and movement:-
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
int xPos, yPos; // x and y coordinates of the mouse when pressed
int grad_midpos; // Position half way betweent he markers
char labeltext[10]; // Temp text storage for writing to labels
QMouseEvent* mEvent = (QMouseEvent*)event;
// Look for mouse press in the gradation bar, then get x value and move lower/upper range accordingly
if (obj == ui->graphicsView_gradbar){ // Only need this if more than one event filter has been installed
if ((event->type() == QEvent::MouseButtonPress) || (event->type() == QEvent::MouseMove)){ // Check if it's a mouse press or mouse move
QPoint point = mEvent->pos();
xPos = point.x(); // Values 1-162 as it gives coordinates inluding the frame around the scale drawn within it.
yPos = point.y(); // The y-coord is interesting to see if it returns a value outside of the gradbar (only applies to MouseMove)
sprintf(labeltext, "%03i", xPos); // Write x-coordinate to the label
ui->label_xvalue->setText(labeltext);
sprintf(labeltext, "%03i", yPos); // Write x-coordinate to the label
ui->label_yvalue->setText(labeltext);
qDebug() << "Mouse Press x" << xPos; // Output to debug for good measure
qDebug() << "Mouse Press y" << xPos;
if ((xPos < 2) || (xPos > 161)) { // If on the box frame or outside, return
return true;
}
xPos = xPos - 2; // Convert to a coordinate in the scene, range 0-159 (160 picels)
// Calculate the gradbar middle
grad_midpos = grad_lower + ((grad_upper-grad_lower)/2);
// Check to see which to grab and move
if (xPos < (grad_midpos - 1) ) { // If less than half mid position reassign to lower threshold - keep a 2 pix gap in the middle
grad_lower = xPos;
} else if (xPos > grad_midpos){ // If at or beyond the mid position reassign to the upper threshold
grad_upper = xPos;
}
// Refresh the gradation bar
GradbarRefresh(1);
return true; // This event has been dealt with so stop handling it
} // ******************* NOTE **********
// Set BOTH theser return values to false and the histogram is drawn properly but only
// responds to mouse clicks, not the mouse move
return true; // Finished handling this event
}
return false; // Returning false means events are still handled. If set to true, no more events are
// Handled and the histogram won't draw properly
}
这是表格:-
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QGraphicsView" name="graphicsView_gradbar">
<property name="geometry">
<rect>
<x>230</x>
<y>200</y>
<width>162</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QGraphicsView" name="graphicsView_histogram">
<property name="geometry">
<rect>
<x>230</x>
<y>120</y>
<width>162</width>
<height>83</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label_xtext">
<property name="geometry">
<rect>
<x>230</x>
<y>230</y>
<width>49</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>x-coord</string>
</property>
</widget>
<widget class="QLabel" name="label_ytext">
<property name="geometry">
<rect>
<x>230</x>
<y>260</y>
<width>49</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>y-coord</string>
</property>
</widget>
<widget class="QLabel" name="label_xvalue">
<property name="geometry">
<rect>
<x>280</x>
<y>230</y>
<width>49</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>x-value</string>
</property>
</widget>
<widget class="QLabel" name="label_yvalue">
<property name="geometry">
<rect>
<x>280</x>
<y>260</y>
<width>49</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>y-value</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
解决方案
推荐阅读
- reactjs - 具有高阶组件的通用组件
- angular - 无法禁用角度 cli 警告
- python-3.x - Python 3 Web Scrape & Beautiful Soup - 隐藏信息
- visual-studio - 在 TFS 构建定义中未触发 Visual Studio 项目的构建后事件
- javascript - Tesseract.js 挂在控制台中
- git - 如何在 android studio 版本控制中找到 Git?
- java - 在 MAC 上创建本地服务器
- spring - 如何访问 hbs(handlebars) 文件中的 redirectAttributes.addFalshAttributed 值
- css - 我们可以在microsoft bot框架中自定义卡片中按钮的设计吗
- c++ - 从键盘读取整数的 C++ 函数