如何用Qt中的CentralWidget中的QLabel替换QPushButton?

时间:2017-11-11 08:38:46

标签: c++ qt

我正在尝试学习并构建一个小型扫雷应用程序。
以下是这样的:
enter image description here

我要做的下一件事是点击一个按钮后,按钮将设置为<h3>Name</h3> <ul class="testClass" style="padding-left:0px; margin-bottom:0px;"> <li> <input type="text" autocomplete="off" name="name" id="myText"> </li> </ul> <ul class="dropDown" style="margin-top:2px;"> <li class="rowClass" style="width:400px"> <label> <input type="checkbox" id="chkAll" value="0"> Select All </label> <input type="button" value="Go" style="float:right;"> </li> <ul style="max-height:200px; overflow-y:scroll;"> <li class="rowClass" style="max-width:400px; min-width:400px;"> <label> <input type="checkbox" name="allClass" class="checkBoxClass"> Test </label> </li> <li class="rowClass" style="max-width:400px; min-width:400px;"> <label> <input type="checkbox" name="allClass" class="checkBoxClass"> Test1 </label> </li> <li class="rowClass" style="max-width:400px; min-width:400px;"> <label> <input type="checkbox" name="allClass" class="checkBoxClass"> Test2 </label> </li> <li class="rowClass" style="max-width:400px; min-width:400px;"> <label> <input type="checkbox" name="allClass" class="checkBoxClass"> Test3 </label> </li> <li class="rowClass" style="max-width:400px; min-width:400px;"> <label> <input type="checkbox" name="allClass" class="checkBoxClass"> Test4 </label> </li> <li class="rowClass" style="max-width:400px; min-width:400px;"> <label> <input type="checkbox" name="allClass" class="checkBoxClass"> Test5 </label> </li> <li class="rowClass" style="max-width:400px; min-width:400px;"> <label> <input type="checkbox" name="allClass" class="checkBoxClass"> Test6 </label> </li> <li class="rowClass" style="max-width:400px; min-width:400px;"> <label> <input type="checkbox" name="allClass" class="checkBoxClass"> Test7 </label> </li> <li class="rowClass" style="max-width:400px; min-width:400px;"> <label> <input type="checkbox" name="allClass" class="checkBoxClass"> Test8 </label> </li> </ul> </ul>hide()将出现在同一个地方。

我的代码是这样的:
.H

QLabel

的.cpp

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();
};

当我跑步并单击其中一个按钮时,该应用程序只是强制退出(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
感谢。

1 个答案:

答案 0 :(得分:1)

@ G.M正确地指出了代码导致崩溃的原因。 - lbl[81] = new QLabel(centralWidget);只会创建一个标签,并将其放在第81个数组字段中。这是两个错误:

  1. 如果您的数组长度为81个元素,则编号为0, 1, ..., 79, 80。最后一个元素是80,因为你从0开始计数。所以在81位置放置一些东西是不可能的
  2. 要实际创建81个新标签,您必须在循环中创建它们:
  3. 示例代码:

    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容器类,例如QListQVector。 (您也可以使用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;
        //...
    }
    

    其余的保持不变,因为这些类允许您保持您知道的标准数组访问语法。