我正在尝试学习并构建一个小型扫雷gui应用程序,这是这样的:
我要做的下一件事是单击一个按钮后,该按钮将设置为hide()
,并且QLabel
将出现在同一位置。
我的代码是这样的:
。H
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void setUI();
void clickedBtnInfo();
private:
Ui::MainWindow *ui;
QWidget *centralWidget;
QGridLayout *centralLayout;
QPushButton *btn[81];
QPushButton *btnSender;
QLabel *lbl[81];
QString clickedBtnName;
private slots:
void btnClicked();
};
.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
centralWidget = new QWidget(this);
setCentralWidget(centralWidget);
lbl[81] = new QLabel(centralWidget);
setUI();
for(int i = 0; i < 81; i++) {
connect(btn[i], SIGNAL(clicked(bool)), btn[i], SLOT(hide()));
connect(btn[i], SIGNAL(clicked(bool)), this, SLOT(btnClicked()));
}
centralWidget->setLayout(centralLayout);
}
void MainWindow::setUI()
{
...
centralLayout = new QGridLayout(centralWidget);
for(int i = 0; i < 9; i++) {
for(int j = 0; j < 9; j++) {
centralLayout->addWidget(btn[j + i * 9], 0 + i, j);
centralLayout->setSpacing(0);
}
}
...
}
void MainWindow::clickedBtnInfo()
{
btnSender = qobject_cast<QPushButton*>(sender());
clickedBtnName = btnSender->objectName();
}
void MainWindow::btnClicked()
{
clickedBtnInfo();
for(int i = 0; i < 9; i++) {
for(int j = 0; j < 9; j++) {
if(btn[j + i * 9]->objectName() == clickedBtnName) {
centralLayout->addWidget(lbl[j + i * 9], 0 + i, j);
centralLayout->setSpacing(0);
}
}
}
}
当我运行它并单击其中一个按钮时,该应用程序仅强制退出(
The program has unexpectedly finished.
)那么,如何解决此问题并在单击后用
QPushButton
替换QLabel
?谢谢。 最佳答案
@ G.M正确指出了代码为何导致崩溃的问题。 -lbl[81] = new QLabel(centralWidget);
仅创建1个标签,并将其放置在第81个数组字段中。一次有2个错误:
如果数组的长度为81个元素,则它们的编号为:0, 1, ..., 79, 80
。最后一个元素是80,因为您从0开始计数。因此无法将某些内容放置在位置81
要实际创建81个新标签,您必须循环创建它们:
样例代码:
for(int i = 0; i < 81; i++) { //goes from 0 to 80
lbl[i] = new QLabel(centralWidget);
lbl[i]->setObjectName(QStringLiteral("Label %1").arg(i));
}
第二行为每个标签指定一个自定义名称。有关详细信息,请参见
QString::arg
。另一个提示:避免使用C数组,除非您需要高性能/低内存(在您的示例中不是这种情况)。相反,请尝试使用Qt容器类之一,例如
QList
或QVector
。 (您也可以使用std::vector
等,但是在使用Qt时,我建议使用Qt容器)对于您的情况,我建议使用QVector,因为它在固定大小的数组上表现最佳。通过这两个更改,将代码更新为:
class MainWindow : public QMainWindow
{
//...
private:
Ui::MainWindow *ui;
QWidget *centralWidget;
QGridLayout *centralLayout;
QVector<QPushButton> btn;
QPushButton *btnSender;
QVector<QLabel> lbl;
QString clickedBtnName;
};
在cpp文件中,更新创建数组的部分:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
centralWidget = new QWidget(this);
setCentralWidget(centralWidget);
lbl.resize(81);
for(int i = 0; i < lbl.size(); i++) { //goes from 0 to 80
lbl[i] = new QLabel(centralWidget);
lbl[i]->setObjectName(QStringLiteral("Label %1").arg(i));
}
setUI();
//...
}
void MainWindow::setUI()
{
//keep your code, but remember to prepare the btn vector with:
btn.resize(81);
//then you can fill the vector just like you are used to:
btn[0] = ui->btn0;
//...
}
其余部分保持不变,因为这些类使您可以保留已知的标准数组访问语法。
关于c++ - 如何在Qt的CentralWidget中用QLabel替换QPushButton?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47236009/