如何在QGridLayout中访问小部件坐标

时间:2014-03-29 16:34:00

标签: c++ qt coordinates qgridlayout

我正在将Qlabels放在QGridLayout中,以便在从QWidget派生的类中很好地排列它们。但是,当我尝试访问坐标时,它总是返回(0,0)

这是我的代码:

class brick : public QWidget
{
Q_OBJECT
public:
    explicit brick(QWidget *parent);
    ...
private:
    QLabel* label;
    QPixmap* brickPic;
}

brick::brick(QWidget *parent) :
QWidget(parent)
{
rect=new QRect();
label=new QLabel;
brickPic=new QPixmap(100,15);
brickPic->fill(QColor(255,0,0));
label->setPixmap(*brickPic);
}

class Grid : public QWidget
{    
QOBJECT
public:
    void fill_grid(QWidget* parent);
    ...
private:
    QGridLayout* grid;
}
void Grid::fill_grid(QWidget* parent)
{
for (int i=0;i<10;i++)
{
    for (int j=0;j<12;j++)
    {
        brick* fillingBrick=new brick(parent);
        grid->addWidget(fillingBrick->getLabel(),j,i);
        qDebug()<<fillingBrick->parentWidget();
        brickVector.push_back(fillingBrick);
    }
}
}

这些将在我之前在QWidget派生的以下类中说明:

class render_area : public QWidget
{
Q_OBJECT
public:
    render_area(QWidget *parent = 0);
    Grid* getGrid() const;
    ...
private:
    Grid* grid;
    QRect* bar;
    ...
}

render_area::render_area(QWidget *parent)
:QWidget(parent)
{
    setFocusPolicy(Qt::StrongFocus);
    setBackgroundRole(QPalette::Base);
    setAutoFillBackground(true);

    bar=new QRect(width()/2,height()+50,150,10);
    grid=new Grid(this);
    grid->fill_grid(this);
    std::cout<<"Grid filled !"<<std::endl;

    qDebug()<<grid->getBrick(5)->pos();
    ...
}

qDebug()<<fillingBrick->parentWidget()返回render_area这是好的,qDebug()<<grid->getBrick(5)->pos()返回QPoint(0,0)但不是。{/ p>

我想知道如何让pos()x()y()返回render_area内的每个砖块放置的坐标。 我尝试使用来自QGridLayout的cellRectMapToParent()继承自QWidget,强制render_areashow();但到目前为止没有运气。

编辑:这是我正在谈论的循环:

void render_area::update_timer()
{
int x1,x2,y1,y2;
bar->getCoords(&x1,&y1,&x2,&y2);

if(is_fixed==false)
{
    //gestion du sol
    if(yc+diametre>height())
    {
        timer.stop();
        QDialog* gameOver=new QDialog;
        gameOver->setLayout(new QGridLayout);
        gameOver->layout()->addWidget(new QPushButton("Ok"));
        gameOver->setGeometry(500,500,300,150);
        gameOver->show();
    }

    if(xc>x1 && xc<x1+150)
    {
        if(yc+diametre>y1)
        {
            vyc=-vyc;
        }
    }
    //plafond
    for (int i=0;i<12;i++)
    {
        for(int j=0;j<10;j++)
        {
            grid->getBrick(i,j)->setRect(grid->getGrid()->cellRect(i,j));
        }
    }

    for(int i=0;i<widgets.size();i++)
    {
            if(widgets.at(i)->getRect()->intersects(ballRectangle))
            {
                std::cout<<i<<std::endl;
                widgets.at(i)->getPixmap()->fill(QColor(255,255,255));
                widgets.at(i)->getLabel()->setPixmap(*(widgets.at(i)->getPixmap()));
                delete widgets.at(i);
                vyc=-vyc;
            }
            //qDebug()<<grid->getBrick(i,j)->getRect();
    }
    //bord droit
    if(xc+diametre>width())
    {
            vxc=-vxc;
    }

    //bord gauche
    if(xc<0)
    {
            vxc=-vxc;
    }

    //integration (Euler explicite)
    xc=xc+dt*vxc;
    yc=yc+dt*vyc;

}
repaint();
}

1 个答案:

答案 0 :(得分:0)

窗口小部件的位置和大小由布局确定,并且在在窗口小部件上调用show()之后某个时间的事件循环调用中计算,有时之前 / em>该窗口变得可见。

由于你想实现一个破砖游戏,有两种方法:

  1. 使用图形视图/场景系统。

  2. 使用小部件,就像您想要的那样。

  3. 基于窗口小部件的方法非常适合证明您的问题的解决方案可以通过而不是检查砖块位置来自然解决。

    您将在计时器事件中更新球位置,或使用动画系统。在任何一种情况下,球部件都将获得具有新位置的moveEvent。在那里,您可以轻松地计算球矩形与每个砖小部件矩形的交点。由于他们是同一父母的孩子,他们将处于相同的坐标系中。那时,所有职位都是最新的。在检测到碰撞后,您将反映球的方向,并逐字地delete砖小部件。你也可以开始播放&#34;击中&#34;声音效果。

    使用QObject属性系统根据其行为特征标记不同的砖小部件相当容易。所有这一切都可以在不必子类化基础窗口小部件的情况下完成,例如,可以是QFrame