Qt 方向盘实现

实现效果如下:

实现方法:
在标记的四个区域放置四个Label,不是用的Qt自带的QLabel,由于QLabel没有click信号,在QLabel基础上自己实现click信号。

先来看Label实现:
class Label : public QLabel
{
    Q_OBJECT
public :
     explicit Label(QWidget * parent = 0);
 
protected :
     void mousePressEvent(QMouseEvent *ev);
     void mouseReleaseEvent(QMouseEvent *ev);
 
signals :
     void clicked();
 
private :
     bool hasPressed;
};
 
Label : :Label(QWidget *parent)
     :QLabel(parent)
{
    hasPressed = false;
}
 
void Label : :mousePressEvent(QMouseEvent *ev)
{
     if(ev - >button() == Qt : :LeftButton)
        hasPressed = true;
}
 
void Label : :mouseReleaseEvent(QMouseEvent *ev)
{
     if(hasPressed && ev - >button() == Qt : :LeftButton)
    {
        hasPressed = false;
        emit clicked();
    }
}
主要是重载了mousePressEvent和mouseReleaseEvent两个函数,用emit click信号,即当鼠标左键按下并释放后,emit click信号。
 
下面来看方向盘的实现。
class QCompass : public QWidget
{
    Q_OBJECT
public:
    enum Direction { Up, Down, Left, Right };
    explicit QCompass(QWidget *parent = 0);
 
protected:
    void paintEvent(QPaintEvent *);
 
signals:
    void click(Direction);
 
private slots:
    void labelClicked();
 
private:
    Label* up;
    Label* down;
    Label* left;
    Label* right;
 
};
 
QCompass : :QCompass(QWidget *parent) :
    QWidget(parent)
{
    setMinimumSize( 80, 80);
    setMaximumSize( 80, 80);
    setFixedSize(width(), height());
    setAttribute(Qt : :WA_TranslucentBackground, true);
 
    up = new Label( this);
    down = new Label( this);
    left = new Label( this);
    right = new Label( this);
 
    connect(up, SIGNAL(clicked()), this, SLOT(labelClicked()));
 
    QGridLayout * mainLayout = new QGridLayout;
    mainLayout - >addWidget(up, 0, 1);
    mainLayout - >addWidget(down, 2, 1);
    mainLayout - >addWidget(left, 1, 0);
    mainLayout - >addWidget(right, 1, 2);
    mainLayout - >setMargin( 0);
    mainLayout - >setSpacing( 0);
     this - >setLayout(mainLayout);
}
 
void QCompass : :labelClicked()
{
    Label * label = static_cast <Label * >(sender());
     if(label == up)
        emit click(Up);
     else if(label == down)
        emit click(Down);
     else if(label == left)
        emit click(Left);
     else if(label == right)
        emit click(Right);
}
 
void QCompass : :paintEvent(QPaintEvent *)
{
    QPainter p( this);
    p.save();
    p.drawPixmap( 0, 0, QPixmap( ":/images/compass.png"));
    p.restore();
}
使用了QGridLayout,把主窗体分3*3的九宫格,将四个方向Label放在图中标记的位置。
还有就是点击四个方向Label需要emit click信号,参数为它们代表的方向。
最后就是重载paintEvent函数,为了实现边缘透明的效果。
 
实例代码:点击下载

你可能感兴趣的:(Qt)