动态添加小部件到gridLayout Qt

时间:2015-03-10 23:40:52

标签: qt

我对某些代码有点困难。我对Qt来说非常新,所以我完全有可能对我遇到的问题一无所知。

基本上,我阻止了一个程序,以便我以后可以添加它的细节。我希望能够创建一个按钮网格,当按下其中一个按钮时,另一个形状将替换它。

我可以制作我的按钮网格,让它可以滚动,并按下按钮将其称为网格上的位置。但是,当我尝试使用这些坐标向网格添加另一个按钮时,Qt崩溃了。

到目前为止,这是我的代码:

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <cmath>
#include <QLabel>
#include <QMainWindow>
#include <QVBoxLayout>
#include <QGridLayout>
#include <QApplication>
#include <QPushButton>
#include <QScrollArea>
#include <QDebug>
#include <QString>
#include <QSignalMapper>
#include <QStringList>
#include <QLayoutItem>



MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
 {
    ui->setupUi(this);
    populateViewGrid(); //I wanted to see if I could add in a scrollbar 
                        //from outside the main window. Could this be causing 
                        // the issue?
 }

void MainWindow::populateViewGrid()
{
QScrollArea*scrollArea = new QScrollArea(this);
QWidget*central = new QWidget(this);
QGridLayout*gridLayout = new QGridLayout(central);
QSignalMapper *signalMapper = new QSignalMapper(central);
for (int i = 0; i < 3; i++)
{
    for (int j = 0; j < 3; j++) 
    {
        QString position= QString("%1,%2").arg(i).arg(j);
        QPushButton* button = new QPushButton("addTrack",central);
        gridLayout->addWidget(button, i, j);
        connect(button, SIGNAL(clicked()),signalMapper, SLOT(map()));
        signalMapper->setMapping(button, position);
    }
}

connect(signalMapper, SIGNAL(mapped(QString)),this, SLOT(addTrack(QString )));

central->setLayout(gridLayout);   

scrollArea->setWidget(central);
setCentralWidget(scrollArea);
}



void MainWindow::addTrack(QString position)
{

QStringList query = position.split(",");
int x;
x=query.at(0).toInt();
        int y;
        y=query.at(1).toInt()    ;

QPushButton *Ifthisworks=new QPushButton(this);

//This first line is where is crashes. I know this due to having the code
//laced with qDebugs. From all of my google searches and such, it seems that 
// something simple should be wrong and I can't find it. 

QLayoutItem * existingitem = gridLayout->itemAtPosition(x, y);


if(existingitem) {
    gridLayout->removeItem(existingitem);
    delete existingitem;
}
// before I included the above to remove the button from the grid point, the 
//program would crash here. 

gridLayout->addWidget(Ifthisworks, x, y);

}



MainWindow::~MainWindow()
{
    delete ui;
}

的main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <cmath>
#include <QLabel>
#include <QMainWindow>
#include <QVBoxLayout>
#include <QGridLayout>
#include <QApplication>
#include <QPushButton>
#include <QMainWindow>
#include <QScrollArea>
#include <QSignalMapper>
#include <QHash>
//unrelated question, do I need the above in my code? I know not all of them 
//used, but do I need includes in this file as well?

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void populateViewGrid();
QGridLayout *gridLayout;

public slots:

void addTrack(QString);
private:
    QScrollArea*scrollArea;
    QWidget * central;
    QPushButton *Ifthisworks;
    QSignalMapper *signalMapper;
    QPushButton *clockViews;

    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

如果你能帮助我理解如何不让Qt崩溃并添加一个按钮,那就太棒了=)

所以有些背景真的很快,因为你正在看我的代码而且正在摸不着头脑。我是一名机械工程师,本应该是一名电气或计算机工程师,对编码有足够的了解,可以让自己陷入这种混乱状态。在大多数情况下,我搜索了我想要Qt做什么,并将它们全部黑客攻击,希望能够使它工作。你可以分享的任何更深刻的理解都会受到欢迎。

感谢您的时间。

2 个答案:

答案 0 :(得分:2)

您正在gridLayout方法中初始化名为MainWindow::populateViewGrid()的本地变量:

QGridLayout*gridLayout = new QGridLayout(central);

然后在您的MainWindow::addTrack(QString position)方法中,您尝试访问名为gridLayout的成员变量,该变量从未初始化。

要解决此问题,只需初始化成员变量,而不是在MainWindow::populateViewGrid()方法中创建局部变量:

gridLayout = new QGridLayout(central);

你和其他成员变量也犯了同样的错误。以同样的方式修复它们。

答案 1 :(得分:0)

我会选择不同的实现方式。

将gridlayout,signalmapper,...移动为类成员。我个人也喜欢保留我的小部件列表QList<QPushButton*>,以便手动删除或保留按钮缓存。

使信号映射器映射到列表中的indexQWidget*。对于示例,我将使用QWidget*指针。

QPushButton *newButton = new QPushButton("The new Thing");
QPushButton *oldButton = static_cast<QPushButton*>(widgetPointer);
gridLayout->replaceWidget(oldButton ,newButton);
buttonList->takeAt(buttonList->indexOf(oldButton))->deleteLater()); //if you keep a list..
buttonList->insert(buttonList->indexOf(oldButton),newButton);