我对某些代码有点困难。我对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做什么,并将它们全部黑客攻击,希望能够使它工作。你可以分享的任何更深刻的理解都会受到欢迎。
感谢您的时间。
答案 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*>
,以便手动删除或保留按钮缓存。
使信号映射器映射到列表中的index
或QWidget*
。对于示例,我将使用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);