我正在将 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)
这不是。
我想知道如何获得 pos()
或 x()
和 y()
返回 render_area
中的坐标每 block 砖都放在里面。
我试过 cellRect
来自 QGridLayout,MapToParent()
继承自QWidget,强制render_area
至 show();
但到目前为止还没有运气。
编辑:这就是我所说的循环:
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();
}
最佳答案
小部件的位置和大小由布局决定,并且在您调用窗口小部件上的 show()
后的某个时间在事件循环调用中计算,有时在该窗口变得可见之前。
既然要实现打砖 block 游戏,有两种方法:
使用图形 View /场景系统。
随心所欲地使用小部件。
您的基于小部件的方法非常出色地证明了您的问题的解决方案可以通过不检查砖 block 位置自然地解决。
您将在计时器事件中或使用动画系统更新球的位置。在任何一种情况下,球小部件都会收到一个带有新位置的 moveEvent
。在那里,您可以轻松计算出球形矩形与每个积木小部件矩形的交点。因为他们是同一个 parent 的 child ,所以他们将在同一个坐标系中。届时,所有职位都将是最新的。检测到碰撞后,您会反射(reflect)球的方向,并从字面上删除
积木小部件。您还可以开始播放“命中”音效。
使用 QObject
属性系统根据行为特征标记不同的积木小部件相当容易。所有这些都可以在无需子类化基本小部件的情况下完成,例如,它可以是 QFrame
。
关于c++ - 如何访问 QGridLayout 中的小部件坐标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22733730/