Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Don';我不懂Qt-ampersand&;按位AND操作:if(ev->;按钮()&Qt::RightButton)_C++_Qt - Fatal编程技术网

C++ Don';我不懂Qt-ampersand&;按位AND操作:if(ev->;按钮()&Qt::RightButton)

C++ Don';我不懂Qt-ampersand&;按位AND操作:if(ev->;按钮()&Qt::RightButton),c++,qt,C++,Qt,我有以下代码: void OpenGLRenderer::mouseMoveEvent(QMouseEvent *ev) { //... if(ev->buttons() & Qt::RightButton) { if(ev->modifiers() & Qt::ShiftModifier) { // ... } else {

我有以下代码:

void OpenGLRenderer::mouseMoveEvent(QMouseEvent *ev)
{
    //...

    if(ev->buttons() & Qt::RightButton)
    {
        if(ev->modifiers() & Qt::ShiftModifier)
        {
            // ...
        }
        else
        {
            // ...
        }
    }
}

我不明白符号
比较是如何工作的。
是否有点像
操作?语句
ev->buttons()&Qt::RightButton
如何工作?

在返回语句
ev->buttons()
/
ev->modifiers()
Qt::RightButton
/
后面有一个数值

为了理解事物是如何工作的,您需要熟悉
enum
s,以及真正简洁的
QFlags
,它允许您轻松组合多个数值(标志)以创建一个复杂的数值

让我们看一下鼠标按钮:

Qt::NoButton    0x00000000  The button state does not refer to any button (see QMouseEvent::button()).
Qt::LeftButton  0x00000001  The left button is pressed, or an event refers to the left button. (The left button may be the right button on left-handed mice.)
Qt::RightButton 0x00000002  The right button.
Qt::MidButton   0x00000004  The middle button.
Qt::MiddleButton    MidButton   The middle button.
Qt::XButton1    0x00000008  The first X button.
Qt::XButton2    0x00000010  The second X button.
您可能会注意到,这些值不是连续的,并且缺少一些值。例如,3、5、6等在哪里。?假设您想要处理同时按下左右按钮的情况

在这些数字(十六进制)后面是简单的二进制数(0和1)。如果我们对0x01和0x02应用逻辑OR,则得到0x03:

0x01 | 0x02 = 0x03
如果我们把这些数字看作0和1,我们就有了

0x01 (hex) = 01 (bin)
0x02 (hex) = 10 (bin)
0x03 (hex) = 11 (bin)
正如您所看到的,由于逻辑OR,我们将0x01中的1和0x02中的1组合为一个11,即0x03

现在让我们把事情颠倒过来,取0x03,看看如果
ev->buttons()
返回它会发生什么。如果该函数返回此结果,我们知道0x01(左)和0x02(右)当前都被按下。为什么?因为枚举中的值没有其他组合创建0x03!如果我们添加逻辑AND运算符,我们可以将
If
条件重写如下(仅使用数值)

但是
0x03&0x02
的结果是什么?这是
0x02
,这是因为在二进制级别上

     11
AND  10
-------
     10
因为1和1是1(第一列),但1和0是0(第二列)。如果我们把它翻译成一句话,我们就有了“如果右键当前按下了,那么做…”

让我们做一个更复杂的例子,按下右键、左键和中键(0x01、0x02和0x04)

如果我们想要一个
If
语句,它的主体只有在按下右键和中键时才被输入,我们需要做一些计算(同样;)。首先,我们需要得到一个值,该值告诉我们两个必需的按钮都已按下:

   010 (right button)
OR 100 (middle button)
------
   110 (bin) = 0x06 (hex) (yet another of the missing values in the enumeration above!)
接下来,我们需要将该组合放在
ev->buttons()
的return语句中,在本例中,该语句返回0x07(以上三个按钮全部按下):

如果我们把它放在
If
条件下

if (ev->buttons() & (Qt::MidButton | Qt::RightButton)
{
  // do something
}
显然,如果
ev->buttons()
返回类似
Qt::RightButton | Qt::XButton1
(无论XButton是什么):D)我们的
if
条件将失败。为什么?因为

   0010 (Qt::RightButton)
OR 1000 (Qt::XButton1)
-------
   1010
结合对
Qt::MidButton | Qt::RightButton
的检查

    1010 (Qt::RightButton | Qt::XButton1)
AND 0110 (Qt::RightButton | Qt::MidButton)
--------
    0010 (Qt::RightButton)
上面的内容可能有点奇怪,但它告诉我们,按下的右键是连接这两个按钮的唯一东西,X键和中间键显然不匹配,因此我们的
if
条件将失败

现在,如果你想在这两种情况下都检查正确的按钮,你就可以开始了

    1010 (Qt::RightButton | Qt::XButton1)
AND 0010 (Qt::RightButton)
--------
    0010 (Qt::RightButton)
以及

    0110 (Qt::RightButton | Qt::MidButton)
AND 0010 (Qt::RightButton)
--------
    0010 (Qt::RightButton)
另一方面,如果
ev->buttons()
仅返回
Qt::MidButton
,但您使用AND操作符检查
Qt::RightButton
,则会得到

    0100 (Qt::MidButton)
AND 0010 (Qt::RightButton)
--------
    0000
在C/C++的逻辑中,0的数值与布尔值
false
相同,因此不会输入
if
的主体


您也可以将相同的逻辑应用到Qt中的所有标志。

感谢您的详细介绍@用户3405291希望不是太多D
    1010 (Qt::RightButton | Qt::XButton1)
AND 0010 (Qt::RightButton)
--------
    0010 (Qt::RightButton)
    0110 (Qt::RightButton | Qt::MidButton)
AND 0010 (Qt::RightButton)
--------
    0010 (Qt::RightButton)
    0100 (Qt::MidButton)
AND 0010 (Qt::RightButton)
--------
    0000