2014-03-29 30 views
1

我正在將Qlabel放入QGridLayout中,以便將它們很好地排列在派生自QWidget的類中。然而,當我嘗試訪問的座標,它總是返回(0,0)如何訪問QGridLayout中的小部件座標

這裏是我的代碼:

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裏面的座標,每個磚塊都放在裏面。 我試着用QGridLayout的cellRect,從QWidget繼承的MapToParent(),強制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(); 
} 
+0

你好,謝謝你編輯我的文章(我不熟悉這篇文章的語法)和你的快速回答。我正在嘗試做一個磚頭破碎機遊戲,我需要磚塊的座標以檢測與球的碰撞。以下是我現在使用的http:// i60。tinypic.com/n70ih2.jpg – user3476114

回答

0

小部件位置和大小由佈局確定,並從事件循環有時電話打電話後計算窗口小部件上的show(),以及之前的某個時間該窗口變得可見。

既然你想實現一個磚斷路器的遊戲,有兩種做法:

  1. 使用圖形視圖/場景系統。

  2. 使用小部件,就像你想要做的那樣。

你的基於工具的方法是極好的證明,要解決你的問題,可以通過自然不檢查磚位置都解決了。

您將更新計時器事件中的球位置或使用動畫系統。無論哪種情況,球控件都會收到一個新的位置moveEvent。在那裏,您可以輕鬆地計算出球形矩形與每個磚形部件矩形的交點。由於他們是同一父母的孩子,他們將處於相同的座標系統中。那時候,所有的職位都是最新的。在檢測到碰撞後,您可以反映球的方向,並且字面意思是磚塊小部件。您也可以開始播放「撞擊」音效。

根據其行爲特徵,使用QObject屬性系統標記不同的磚構件相當容易。所有這些都可以在不需要子基類小部件的情況下完成,例如可以是QFrame

+0

我在qt文檔中看到確實給出錯誤的座標,直到您調用show()。我有一個Qt計時器用於更新我的render_area,並試圖讓我的磚的pos()在循環內沒有運氣(QPoint(0,0)) – user3476114

+0

我在第一篇文章中添加了循環。感謝您爲我指出方向,這真的很有幫助。 – user3476114

+0

感謝您指點我的方向,這真的很有幫助。根據我的理解,我可以得到繪製球體的矩形,並檢查這個矩形是否與磚塊矩形相交。還有一些我不退出得到:我應該在每次計時器更新時檢查交叉路口嗎?如果是這樣,這個檢查以某種方式壓倒了系統?另外,我的球是用QPainter'drawEllipse'繪製的,有沒有辦法讓繪製的矩形(也許用'childrenRect')或者我應該在render_area類中實現它作爲屬性? – user3476114