鼠標控制模式用於三維空間可視化導航,通過鼠標的按鍵及少數鍵盤按鍵的組合,可以實現對三維視圖的平移、縮放、選擇等操作。
一、選擇導航模式
由於之前使用過Blender,其鼠標的操作方式比較好用,因此這裏使用Blender導航。Blender導航參照Blender的操作。以前需要SHIFT配合鼠標才能完成視圖平移. 在2016年Blender增加了一個功能改變了這一情況。要平移視圖,現在可以同時按下鼠標左鍵和鼠標右鍵並在視圖中拖動。
在三維界面頭文件中加入模式枚舉,及添加鼠標操作相關成員:
//c3dwidget.h
class C3DWidget : public QWidget
{
......
protected:
//!三維場景轉換模式
enum CurrentAction3d
{
CurAction3d_Nothing,
CurAction3d_DynamicPanning, //平移
CurAction3d_DynamicZooming, //縮放
CurAction3d_DynamicRotation //旋轉
};
protected:
//!覆寫鍵盤按鍵按下事件
void keyPressEvent(QKeyEvent *event);
//!覆寫鍵盤按鍵釋放事件
void keyReleaseEvent(QKeyEvent *event);
//!覆寫鼠標按鍵按下事件
void mousePressEvent(QMouseEvent *event);
//!覆寫鼠標按鍵釋放事件
void mouseReleaseEvent(QMouseEvent *event);
//!覆寫鼠標移動事件
void mouseMoveEvent(QMouseEvent *event);
//!覆寫鼠標滾輪事件
void wheelEvent(QWheelEvent *event);
private:
Standard_Integer m_x_max; //!記錄鼠標平移座標X
Standard_Integer m_y_max; //!記錄鼠標平移座標Y
CurrentAction3d m_current_mode; //!三維場景轉換模式
bool m_shift_key_pressed; //!記錄Shift鍵是否被按下
......
};
二、平移
平移的方式有兩種,通過if判斷當前操作是否爲平移方式的其中一種。其中一種需要加上SHIFT按鍵,則通過m_shift_key_pressed 變量判斷SHIFT鍵是否被按下。
void C3DWidget::mousePressEvent(QMouseEvent *event)
{
if( ((event->buttons() & Qt::MidButton) && (QApplication::keyboardModifiers()==Qt::ShiftModifier) ) //平移方式1
||((event->buttons()&Qt::LeftButton)&&(event->buttons()&Qt::RightButton)))//平移方式2
{
m_current_mode = CurAction3d_DynamicPanning;
m_x_max = event->pos().x(); //記錄起始X位置
m_y_max = event->pos().y(); //記錄起始Y位置
}
......
}
void C3DWidget::mouseReleaseEvent(QMouseEvent *)
{
m_current_mode = CurAction3d_Nothing;
}
void C3DWidget::mouseMoveEvent(QMouseEvent *event)
{
switch (m_current_mode)
{
case CurAction3d_DynamicPanning:
//執行平移
m_view->Pan(event->pos().x() - m_x_max, m_y_max - event->pos().y());
m_x_max = event->pos().x();
m_y_max = event->pos().y();
break;
......
}
}
三、縮放
縮放通過V3d_View類的Zoom方法實現,Zoom方法的設計是通過相鄰兩次鼠標位置判斷縮小或放大,以及縮放的程度。前兩個參數爲第一次鼠標的位置,後兩個參數爲第二次鼠標的位置。而滾動鼠標滾輪會Qt的wheelEvent事件,向上滾動和向下滾動event->angleDelta().y()會返回或正或負的數值,將此值模擬第二次鼠標的位置,實現三維界面縮放功能。
void C3DWidget::wheelEvent(QWheelEvent *event)
{
m_view->Zoom(0, 0, event->angleDelta().y(), 0); //執行縮放
}
5月9日更新:原來的程序只在固定點縮放,作以下更改後,縮放跟隨鼠標的位置進行。
void C3DWidget::wheelEvent(QWheelEvent *event)
{
m_view->StartZoomAtPoint(event->pos().x(),event->pos().y());
m_view->ZoomAtPoint(0, 0, event->angleDelta().y(), 0); //執行縮放
}
四、旋轉
鼠標的中鍵按下時,通過V3d_View類的StartRotation方法記錄起始位置。鼠標發生移動後,使用Rotation方法實現三維界面旋轉。
void C3DWidget::mousePressEvent(QMouseEvent *event)
{
if(......)//平移
{......}
else if(event->buttons() & Qt::MidButton) //旋轉
{
m_current_mode = CurAction3d_DynamicRotation;
m_view->StartRotation(event->pos().x(), event->pos().y());
}
......
}
void C3DWidget::mouseMoveEvent(QMouseEvent *event)
{
switch (m_current_mode)
{
......
case CurAction3d_DynamicRotation:
//執行旋轉
m_view->Rotation(event->pos().x(), event->pos().y());
break;
......
}
}