2

私は QGridLayout に Qlabels を配置して、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_areaqDebug()<<grid->getBrick(5)->pos()QPoint(0,0)

すべてのレンガが配置されている座標をどのように取得または返すことpos()ができるのだろうか。QWidgetから継承されたQGridLayoutから試してみましたが、これまでのところ運がありません。x()y()render_areacellRectMapToParent()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();
}
4

1 に答える 1

1

ウィジェットの位置とサイズはレイアウトによって決定され、ウィンドウ ウィジェットを呼び出した後、そのウィンドウが表示される前に、イベント ループからの呼び出しで計算されます。show()

ブロック崩しゲームを実装したいので、2 つの方法があります。

  1. グラフィック ビュー/シーン システムを使用します。

  2. あなたがやりたいように、ウィジェットを使用してください。

あなたのウィジェット ベースのアプローチは、レンガの位置をまったくチェックしなくても自然に問題を解決できることを示すのに優れています。

タイマー イベントでボールの位置を更新するか、アニメーション システムを使用します。いずれの場合も、ボール ウィジェットはmoveEvent新しい位置で を受け取ります。そこでは、ボールの四角形と各ブリック ウィジェットの四角形との交点を簡単に計算できます。それらは同じ親の子であるため、同じ座標系になります。その時点で、すべてのポジションが現在のものになります。衝突を検出すると、ボールの方向を反映し、文字通りdeleteレンガ ウィジェットを反映します。「ヒット」効果音の再生を開始することもできます。

QObjectプロパティ システムを使用して、動作特性に応じてさまざまなブリック ウィジェットをマークするのはかなり簡単です。これはすべて、ベース ウィジェットをサブクラス化する必要なく実行できますQFrame

于 2014-03-29T16:49:29.567 に答える