如何从另一个函数更改 QGraphicsScene?

Posted

技术标签:

【中文标题】如何从另一个函数更改 QGraphicsScene?【英文标题】:How do you change a QGraphicsScene from another function? 【发布时间】:2015-12-29 18:02:10 【问题描述】:

我的程序有一个名为SimulatorGV 的QGraphicsView 和一个名为Simulation 的QGraphicsScene。在主函数中,我绘制了一些矩形和椭圆。我也希望能够在另一个函数中绘制相同的场景。

本质上,如何从另一个函数向场景添加形状? (当用户界面上的按钮被按下时调用)


到目前为止,我已经尝试将 QGraphicsView 传递给其他函数?下面是主要的ui函数(不相关的语句删掉):


    ui->setupUi(this);
    Simulation = new QGraphicsScene(this);


        ui->SimulatorGV->setScene(Simulation);

        Simulation->addRect(0,415,20,50,noPen,greyBrush); 
        Simulation->addRect(425,230,10,420,noPen,goldBrush); 
        Simulation->addEllipse(80,90,700,700,greyPen,noBrush); 
        Simulation->addRect(72,215,90,450,noPen,blackBrush); 



在头文件中,我在私有槽中声明了这个函数:

void DrawingSimulation(QGraphicsView *SimulationGV);

应该改为这样吗?

void DrawingSimulation(QGraphicsScene *Simulation);

我像这样在另一个函数中调用了该函数:

DrawingSimulation(ui->SimulatorGV);

应该改为这样吗?

DrawingSimulation(ui->SimulatorGV->Simulation);

还是?

DrawingSimulation(ui->Simulation);

这是我希望能够在场景中绘制的函数:

void RASP::DrawingSimulation(QGraphicsView *SimulationGV)

    for (int i = 0; i < DisplayAlphaParticleNumber; i++)
    
        if (ParticleLocation[i*6+3] != 0 || ParticleLocation[i*6+6] != 0) 
        
            ui->SimulatorGV->setScene(Simulation);
            Simulation->addEllipse(ParticleLocation[i*6+3],ParticleLocation[i*6+4],10,10);
        
    

SimulatorGV 是我的 ui 表单中 QGraphicsView 的名称。 RASP 是项目的名称。 ParticleLocation[i*6+3] 是 x 坐标,[i*6+4] 是 y 坐标。

我将 QGraphicsView 传递给变量而不是 QGraphicsScene Simulation 是否正确?

我正确通过了吗?

在 DrawingSimulation 函数中我是否正确添加了椭圆?

编辑: 本质上,如何从另一个函数向场景添加形状? (当按下用户界面上的按钮时调用)

当一个按钮被按下时,这个函数被调用:

    void RASP::on_Button1_clicked()
    
    //some values set
    //some other functions called then the main one that leads to the drawingsimulation   

     mainfunction();
    

然后在mainfunction():里面

void RASP::mainfunction()

     DrawingSimulation(); //is called

现在我想在RASP::RASP() (MyClass::MyClass) 中的原始场景上绘制的函数DrawingSimulation() 被调用。


我之前的尝试是通过按钮设置一个布尔函数,然后是 addEllipse:

MyClass::MyClass()

ui->setupUi(this);
        Simulation = new QGraphicsScene(this);


            ui->SimulatorGV->setScene(Simulation);

            Simulation->addRect(0,415,20,50,noPen,greyBrush); 
            Simulation->addRect(425,230,10,420,noPen,goldBrush); 
            Simulation->addEllipse(80,90,700,700,greyPen,noBrush); 
            Simulation->addRect(72,215,90,450,noPen,blackBrush); 

if (SimulationRun == true)

for (int i = 0; i < DisplayAlphaParticleNumber; i++)
        
            if (ParticleLocation[i*6+3] != 0 || ParticleLocation[i*6+6] != 0) 
            
                ui->SimulatorGV->setScene(Simulation);
                Simulation->addEllipse(ParticleLocation[i*6+3],ParticleLocation[i*6+4],10,10);
            
        


然后在按钮中点击函数设置 SimulationRun = 为真。

【问题讨论】:

这变得一团糟。我觉得你的问题实际上是知道如何在 C++ 中调用函数和传递参数....QGraphicsScene 类没有真正的具体问题。在尝试做复杂的事情之前,请先学习一些 C++ 基础知识。 @jpo38 我的主要问题是我没有使用信号和插槽。多亏了你的帖子,我想我可以用它来解决这个问题。我是一个对学校项目有点雄心勃勃的学生,但你的回答肯定很有帮助,非常感谢:)。 【参考方案1】:

让我们保持简单。

如果你有:

MyClass::MyClass() : ui(new Ui::MainWindow)

    ui->setupUi(this);
    Simulation = new QGraphicsScene(this);

    ui->SimulatorGV->setScene(Simulation);

    Simulation->addRect(0,415,20,50,noPen,greyBrush); 
    Simulation->addRect(425,230,10,420,noPen,goldBrush); 
    Simulation->addEllipse(80,90,700,700,greyPen,noBrush); 
    Simulation->addRect(72,215,90,450,noPen,blackBrush); 

如果这行得通,那么,这也行得通:

MyClass::MyClass() : ui(new Ui::MainWindow)

    ui->setupUi(this);
    Simulation = new QGraphicsScene(this); // supposing MyClass has a Simulation attribute of type QGraphicsScene

    ui->SimulatorGV->setScene(Simulation);

    addItems(); // calling function below


void MyClass::addItems()

    // declared "void addItems();" in header file
    addItems( Simulation ); // calling function below that could be static


void MyClass::addItems( QGraphicsScene* simu )

    // declared "static void addItems(QGraphicsScene* simu);" in header file
    simu->addRect(0,415,20,50,noPen,greyBrush); 
    simu->addRect(425,230,10,420,noPen,goldBrush); 
    simu->addEllipse(80,90,700,700,greyPen,noBrush); 
    simu->addRect(72,215,90,450,noPen,blackBrush); 

那么,如果这可行,您现在知道如何从“另一个函数”修改场景。

最后,你还应该有:

void MyClass::DrawingSimulation()

    // declared "void DrawingSimulation();" in header file
    DrawingSimulation( Simulation );


void MyClass::DrawingSimulation(QGraphicsScene *simu)

    // declared "void DrawingSimulation(QGraphicsScene *simu);" in header file
    for (int i = 0; i < DisplayAlphaParticleNumber; i++)
    
        if (ParticleLocation[i*6+3] != 0 || ParticleLocation[i*6+6] != 0) 
        
            simu->addEllipse(ParticleLocation[i*6+3],ParticleLocation[i*6+4],10,10);
        
    

注意DrawingSimulation()也可以是slot(在你的头文件中使用public slots:声明它。然后,如果你connect它到clicked()signal您的 GUI 的 QPushButton (例如),它将在单击按钮并添加椭圆时调用。

像这样:

MyClass::MyClass()

    ...

    connect( ui->pushButton, SIGNAL(clicked()), this, SLOT(DrawingSimulation()) );

【讨论】:

感谢您的回复 :D 你的方法更好。我的错误是在问题中没有提到按下我的用户界面中的按钮时会调用另一个函数(实际上它是由按下按钮时调用的另一个函数调用的)。我在最后的主要问题中添加了按下按钮的代码。您能解释一下按下按钮时如何调用“添加项目”功能吗?我也包括了我这样做的尝试。 更新了我的帖子,请看一下。 嘿,我一直在尝试实施您的上述建议(第二个代码块)并且有两个问题:ui = new ....; 是什么意思?以及如何在头文件中声明该函数?因为当您使用addItems() 时,当我声明为void addItems(QGraphicsScene *scene); 并说“未找到重载成员函数”或声明为void addItems(); 时,程序输出错误“函数不接受0 争论”或声明为“函数不接受1论据”。我已经尝试了您的示例,一个新项目只是为了对其进行测试,并将在编辑中包含完整的代码。谢谢:) addItems 函数都必须在头文件中声明。 ui = new ... 只是提到了ui 对象创建。更新了我的帖子以澄清所有这些。

以上是关于如何从另一个函数更改 QGraphicsScene?的主要内容,如果未能解决你的问题,请参考以下文章

Qt - QGraphicsScene 和 QGraphicsView 不更新更改?

Python 3从另一个函数更改函数中的变量

F# 函数在使用独立开关编译并从另一个项目引用时更改类型

如何从另一个小部件更改有状态小部件的变量?

如何从另一个 UIViewController 更改分段控件标题(设置)

如何检查是否从另一个类中检查了RadioButton?