2012-12-15 82 views
0

Qt Creator中,我有几个小部件的声明如下所示:从其课外访问小部件?

头文件:

class MapViewer : public QGraphicsView 
{ 
    Q_OBJECT 

public: 
    explicit MapViewer(QGraphicsScene *scene, QWidget *parent = 0); 
    ~MapViewer(); 

public slots: 
    void mousePressEvent(QMouseEvent *event); 

}; 

// Declaration for the map editor window. 
class MapEditor : public QMainWindow 
{ 
    Q_OBJECT 

public: 
    explicit MapEditor(QWidget *parent = 0); 
    ~MapEditor(); 

public: 
    QLayout *editorLayout; 
    QPushButton *btn; 
    QGraphicsScene *mapScene; 
    MapViewer *mapView; 

private: 
    Ui::MapEditor *ui; 
}; 

CPP文件:

MapEditor::MapEditor(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MapEditor) 
{ 

    ui->setupUi(this); 
    this->setWindowTitle("2DXY :: Map Editor"); 
    this->setGeometry(10,10,1170,750); 
    editorLayout = new QVBoxLayout; // Create a new layout 
    this->setLayout(editorLayout); // Set the widget's layout to our newly created layout. 

    mapScene = new QGraphicsScene(); // Create a new graphics scene to draw upon. 

    mapView = new MapViewer(mapScene,this); // Create a new graphics view to display our scene - set its parent to 'this' so that it doesn't open in a new window. 
    mapView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 
    mapView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 
    mapView->setGeometry(20,20,1178,546); // Width first, then height. 

AND:

void MapViewer::mousePressEvent(QMouseEvent *event) 
{ 
    // Show an empty message box, just to check that the event handler works! 
    QMessageBox *notification = new QMessageBox(); 
    notification->show(); 
    notification->exec(); 
    // Some how access the same QGraphicsScene and View (mapScene, mapView) as above, so 
    // I can update their contents on the open form/window. 

} 

而且正如你所看到的,我希望再次访问图形场景来更新它,然后重绘i吨(或其他)。但是我根本无法访问图形场景,尽管用不同的方式声明小部件需要几个小时的试验和错误。我知道监听器本身是可以工作的,因为如果它设置为打开一个新的消息框,或者输出到调试窗口,那么它就可以工作,这只是我不能访问我已经定义的小部件。

我觉得这个问题有一个(相对)简单的解决方案,而且我只是错过了一些明显的东西。

+0

只是让他们成员变量的类和提供getter方法... – cmannett85

+0

@ cmannett85 - 你能解释这个更详细/提供一个例子吗? (我对C++相当陌生!)谢谢! – BnMcG

+0

Bret Kuhns做得很好。不过,我必须强调,这不是学习C++的方法!与'普通'C++相比,Qt使用了一些不常见/不可用的范例,所以先学习语言,然后再学习框架。 – cmannett85

回答

0
void MapViewer::mousePressEvent(QMouseEvent *event) 
{ 
    // Show an empty message box, just to check that the event handler works! 
    QMessageBox *notification = new QMessageBox(); 
    notification->show(); 
    notification->exec(); 

    // To add something whenever the user clicks, you don't need the view, 
    // just the scene. 
    scene()->addItem(new MyItem()); 
} 

记住MapViewerQGraphicsView派生,并认为必须知道它属于现场 - 所以它有一个scene()方法返回它,你继承。

+0

啊,我明白了!这很好!非常感谢您的耐心和理解! – BnMcG

1

您将QGraphicsScene传递给您的MapRender对象的构造函数。你在构造函数中如何处理这个场景?理想情况下,您应该将其存储为MapRender的数据成员。例如:

class MapRender { 
public: 
    MapRender(QGraphicsScene* scene) 
     : scene_(scene) 
    { 
    } 

public slots: 
    void mousePressEvent(QMouseEvent *event); 

private: 
    QGraphicsScene* scene_; 
} 

现在,在您执行mousePressEvent,您可以访问到现场成员:

void MapRender::mousePressEvent(QMouseEvent *event) { 
    int CursorX = event->globalX(); 
    int CursorY = event->globalY(); 

    QGraphicsRectItem *clickedBox = new QGraphicsRectItem(40,40,32,32); 
    clickedBox->setBrush(QBrush(Qt::blue)); 

    scene_->addItem(clickedBox); 
} 

请记住,您最好应该把构造函数的实现在你的CPP文件,但我的例子在简明声明中就是这样做的。

+0

我现在可以从mousePressEvent处理程序访问QGraphicsScene,但是如何从MapEditor :: addWidget()方法访问它,例如,如何在它上面绘制? 'scene _-> addLine(...);' 谢谢, 本。 – BnMcG

+0

那么,你在'MapEditor :: addWidget()'中构建了这个场景,所以你可以通过'scene-> addLine(...);'(在你的例子中'new'之后)来正常访问它。将指向对象的指针传递给函数/构造函数不会使当前作用域内的指针无效。 –