[英]How to replace QPushButton with QLabel in CentralWidget in Qt?
I am trying to learn and build a small minesweeper gui app. 我正在尝试学习并构建一个小型扫雷gui应用程序。
Here is how this looks like: 这是这样的:
The next thing I want to do is after clicking one button, then the button will be set to hide()
and a QLabel
will appear in the same place. 我要做的下一件事是单击一个按钮后,该按钮将设置为
hide()
并且QLabel
将出现在同一位置。
My code is like this: 我的代码是这样的:
.h 。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 的.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);
}
}
}
}
When I ran this and clicked one of the buttons, the app just force quit( The program has unexpectedly finished.
) 当我运行它并单击其中一个按钮时,该应用程序只是强制退出(
The program has unexpectedly finished.
)
So how can I solve this problem and replace QPushButton
with QLabel
after clicking? 那么,如何解决此问题并在单击后用
QLabel
替换QPushButton
?
Thanks. 谢谢。
The Problem why your code leads to a crash was correctly pointed out by @GM - lbl[81] = new QLabel(centralWidget);
@GM正确指出了代码为何导致崩溃的问题-lbl
lbl[81] = new QLabel(centralWidget);
will create only 1 label, and place it in the 81st array field. 将仅创建1个标签,并将其放置在第81个数组字段中。 That are 2 errors at once:
一次有2个错误:
0, 1, ..., 79, 80
. 0, 1, ..., 79, 80
。 The last element is 80, because you start counting at 0. So placing something at position 81 is not possible Sample code: 样例代码:
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));
}
The second line gives each label a custom name. 第二行为每个标签指定一个自定义名称。 See
QString::arg
for details. 有关详细信息,请参见
QString::arg
。
One more tip: Avoid C-arrays, unless you need high performace/low memory (which is not the case for your example). 另一个提示:避免使用C数组,除非您需要高性能/低内存(在您的示例中不是这种情况)。 Instead try to use one of the Qt container classes, eg
QList
or QVector
. 而是尝试使用Qt容器类之一,例如
QList
或QVector
。 (You can use std::vector
etc. as well, but when working with Qt, I would recommend to use the Qt containers) (您也可以使用
std::vector
等,但是当使用Qt时,我建议使用Qt容器)
For your case, I would recommend QVector, as it performs best with fixed-sized arrays. 对于您的情况,我建议使用QVector,因为它在固定大小的数组上表现最佳。 With both of these changes, update your code to:
通过这两个更改,将代码更新为:
class MainWindow : public QMainWindow
{
//...
private:
Ui::MainWindow *ui;
QWidget *centralWidget;
QGridLayout *centralLayout;
QVector<QPushButton> btn;
QPushButton *btnSender;
QVector<QLabel> lbl;
QString clickedBtnName;
};
In your cpp file, update the part where you create the arrays: 在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;
//...
}
And the rest stays the same, as these classes allow you to keep the standard array access syntax you know. 其余部分保持不变,因为这些类使您可以保留已知的标准数组访问语法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.