Qt扫雷开发中自定义My_PushButton类如何访问窗体gridLayout_2布局
你最新的写法错误核心是:MainWindow m;是新建了一个全新的、未初始化的MainWindow对象,和你当前正在运行的游戏主窗口完全是两个独立实例,调用它的getPointer拿到的ui指针也没有绑定到你可见的界面元素,当然不会有任何效果。
以下是两种可直接落地的实现方案:
方案一:使用Qt信号槽解耦(推荐)
符合Qt的设计思想,完全避免子控件直接操作父窗口UI的高耦合问题,不会出现野指针错误。
步骤1:修改My_PushButton类,添加自定义信号
class My_PushButton: public QPushButton{ Q_OBJECT public: int val; //存储相邻地雷数,值为9代表地雷 My_PushButton(int val = 0): QPushButton(), val(val){ setFixedSize(25,25); setStyleSheet("background-color: rgb(146, 36, 255)"); } // 新增信号声明 signals: void bombTriggered(); // 踩中地雷时触发的信号 protected: void mousePressEvent(QMouseEvent *event) override{ if(event->button() == Qt::RightButton){ this->setIcon(QIcon(R"(C:\Qt\pictures/flag.png)")); }else{ if(val == 9){ this->setIcon(QIcon(R"(C:\Qt\pictures/bomb.png)")); emit bombTriggered(); // 发送踩雷信号 return; } // 原有正常点击逻辑 } QPushButton::mousePressEvent(event); // 保留父类默认事件逻辑 } };
步骤2:在MainWindow中绑定信号和槽
你在MainWindow里循环创建My_PushButton并添加到gridLayout_2的时候,给每个按钮绑定信号到主窗口的处理逻辑:
// 假设你创建按钮的代码类似这样 My_PushButton *btn = new My_PushButton(val); ui->gridLayout_2->addWidget(btn, row, col); // 新增这行绑定信号 connect(btn, &My_PushButton::bombTriggered, this, [=](){ ui->gridLayout_2->setEnabled(false); // 主窗口直接操作自己的UI,完全合法 });
踩雷时会直接触发lambda里的逻辑,只会禁用gridLayout_2,不在这个布局里的重启按钮完全不受影响。
方案二:直接获取当前主窗口指针操作
如果你不想改动信号槽逻辑,也可以正确获取当前运行的主窗口实例指针,不要自己新建实例:
首先确认已包含MainWindow的头文件,然后在My_PushButton的mousePressEvent里这么写:
if(val == 9){ this->setIcon(QIcon(R"(C:\Qt\pictures/bomb.png)")); // 获取当前控件所在的顶层主窗口实例 MainWindow *currentMainWin = qobject_cast<MainWindow*>(this->window()); if(currentMainWin){ // 判空避免野指针 currentMainWin->getPointer()->gridLayout_2->setEnabled(false); } return; }
这种方法要确保My_PushButton的父层级最终归属MainWindow,否则qobject_cast会返回空指针。
内容的提问来源于stack exchange,提问作者Gremeat
相关产品推荐
相关产品推荐

