QWidget *form = QApplication::activeWindow();
form->blockSignals(true);
or
form->setDisabled(true);
In this case, the window is blocked, and with it the pushButton
button, which is needed to restart in case of defeat. Ui::MainWindow *ui;
ui->gridLayout_2->setEnabled(false);
With this approach, I get the "Segmentation Fault" error, although the pointer is not empty in theory. class My_PushButton: public QPushButton{
Q_OBJECT
public:
//Ui::MainWindow *ui;
//QWidget *form = QApplication::activeWindow(); //A pointer to the active window (widget) in order to further access form elements through it
int val; //A variable that will store either the number of mines in the neighborhood, or the mine itself
My_PushButton(int val = 0): QPushButton(), val(val){
setFixedHeight(25);
setFixedWidth(25);
setIconSize(QSize(25, 24));
setStyleSheet("background-color: rgb(146, 36, 255)");
}
private slots:
void mousePressEvent(QMouseEvent *event){
if(event->button() == Qt::RightButton){
this->setIcon(QIcon(R"(C:\Qt\pictures/flag.png)"));
}
else{
if(val == 0) this->setStyleSheet("background-color: rgb(234, 223, 246)"), this->setIcon(QIcon());
if(val == 1) this->setStyleSheet("background-color: rgb(209, 173, 245)"), this->setIcon(QIcon()), this->setText("1");
if(val == 2) this->setStyleSheet("background-color: rgb(209, 173, 245)"), this->setIcon(QIcon()), this->setText("2");
if(val == 3) this->setStyleSheet("background-color: rgb(209, 173, 245)"), this->setIcon(QIcon()), this->setText("3");
if(val == 4) this->setStyleSheet("background-color: rgb(209, 173, 245)"), this->setIcon(QIcon()), this->setText("4");
if(val == 5) this->setStyleSheet("background-color: rgb(209, 173, 245)"), this->setIcon(QIcon()), this->setText("5");
if(val == 6) this->setStyleSheet("background-color: rgb(209, 173, 245)"), this->setIcon(QIcon()), this->setText("6");
if(val == 7) this->setStyleSheet("background-color: rgb(209, 173, 245)"), this->setIcon(QIcon()), this->setText("7");
if(val == 8) this->setStyleSheet("background-color: rgb(209, 173, 245)"), this->setIcon(QIcon()), this->setText("8");
if(val == 9){
this->setStyleSheet("background-color: rgb(209, 173, 245)"), this->setIcon(QIcon(R"(C:\Qt\pictures/bomb.png)"));
//form->blockSignals(true);
//form->setDisabled(true);
//ui->gridLayout_2->setEnabled(true);
}
}
}
signals:
void rightClicked();
void leftClicked();
protected:
void mouseReleaseEvent(QMouseEvent* event){
if(event->button() == Qt::RightButton){
emit rightClicked();
}
else{
emit leftClicked();
}
}
};
#include "./ui_mainwindow.h"
#include "mainwindow.h"
#include <iostream>
#include <QTextBrowser>
#include <QPushButton>
#include <QVariant>
#include <time.h>
#include <QLayout>
#include <QMouseEvent>
#include <QObject>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
class My_PushButton: public QPushButton{
Q_OBJECT
public:
//Ui::MainWindow *ui;
//QWidget *form = QApplication::activeWindow(); //A pointer to the active window (widget) in order to further access form elements through it
int val; //A variable that will store either the number of mines in the neighborhood, or the mine itself
My_PushButton(int val = 0): QPushButton(), val(val){
setFixedHeight(25);
setFixedWidth(25);
setIconSize(QSize(25, 24));
setStyleSheet("background-color: rgb(146, 36, 255)");
}
private slots:
void mousePressEvent(QMouseEvent *event){
if(event->button() == Qt::RightButton){
this->setIcon(QIcon(R"(C:\Qt\pictures/flag.png)"));
}
else{
if(val == 0) this->setStyleSheet("background-color: rgb(234, 223, 246)"), this->setIcon(QIcon());
if(val == 1) this->setStyleSheet("background-color: rgb(209, 173, 245)"), this->setIcon(QIcon()), this->setText("1");
if(val == 2) this->setStyleSheet("background-color: rgb(209, 173, 245)"), this->setIcon(QIcon()), this->setText("2");
if(val == 3) this->setStyleSheet("background-color: rgb(209, 173, 245)"), this->setIcon(QIcon()), this->setText("3");
if(val == 4) this->setStyleSheet("background-color: rgb(209, 173, 245)"), this->setIcon(QIcon()), this->setText("4");
if(val == 5) this->setStyleSheet("background-color: rgb(209, 173, 245)"), this->setIcon(QIcon()), this->setText("5");
if(val == 6) this->setStyleSheet("background-color: rgb(209, 173, 245)"), this->setIcon(QIcon()), this->setText("6");
if(val == 7) this->setStyleSheet("background-color: rgb(209, 173, 245)"), this->setIcon(QIcon()), this->setText("7");
if(val == 8) this->setStyleSheet("background-color: rgb(209, 173, 245)"), this->setIcon(QIcon()), this->setText("8");
if(val == 9){
this->setStyleSheet("background-color: rgb(209, 173, 245)"), this->setIcon(QIcon(R"(C:\Qt\pictures/bomb.png)"));
//form->blockSignals(true);
//form->setDisabled(true);
//ui->gridLayout_2->setEnabled(true);
}
}
}
signals:
void rightClicked();
void leftClicked();
protected:
void mouseReleaseEvent(QMouseEvent* event){
if(event->button() == Qt::RightButton){
emit rightClicked();
}
else{
emit leftClicked();
}
}
};
#include "mainwindow.moc"
void MainWindow::on_action_triggered()
{
QTextBrowser *tb = new QTextBrowser(); //Create a window with game rules
tb->setFixedSize(610, 150);
tb->setText("Use the left click button on the mouse to select a space on the grid.\n"
"If you hit a bomb, you lose.\n"
"The numbers on the board represent how many bombs are adjacent to a square.\n"
"For example, if a square has a \"3\" on it, then there are 3 bombs next to that square.\n"
"The bombs could be above, below, right and (or) left, or diagonal to the square.\n"
"Avoid all the bombs and expose all the empty spaces to win Minesweeper.\n"
"You can right click a square with the mouse to place a flag where you think a bomb is. This allows you to avoid that spot.");
tb->setEnabled(true);
tb->setVisible(true);
}
My_PushButton** my_rand(int size){
/*************************************************************
* The following values will be used to customize the cells: *
* 0 - empty cell; *
* 1 - cell showing the number of mines around it = 1; *
* 2 - cell showing the number of mines around it = 2; *
* 3 - cell showing the number of mines around it = 3; *
* 4 - cell showing the number of mines around it = 4; *
* 5 - cell showing the number of mines around it = 5; *
* 6 - cell,showing the number of mines around it = 6; *
* 7 - cell showing the number of mines around it = 7; *
* 8 - cell showing the number of mines around it = 8; *
* 9 - mine cell; *
*************************************************************/
srand(time(NULL));
int counter = 0, numines = (rand() % ((size * size) / 2)) + 1, x = 0, y = 0; //numines - number of mines, x & y - coordinates for placing a mine
My_PushButton **but; //Create a 2D array and fill it with 0
but = new My_PushButton*[size];
for(int i = 0; i < size; ++i){
but[i] = new My_PushButton[size];
}
while(numines > 0){ //Placing mines
x = rand() % size, y = rand() % size;
if(but[x][y].val != 9){
but[x][y].val = 9;
numines --;
}
}
//Checking neighbors for mines
for(int i = 1; i < size - 1; ++i){ //Checking an area without borders
for(int j = 1; j < size - 1; ++j){
if(but[i][j].val != 9){
if(but[i - 1][j - 1].val == 9) ++counter;
if(but[i - 1][j].val == 9) ++counter;
if(but[i - 1][j + 1].val == 9) ++counter;
if(but[i][j - 1].val == 9) ++counter;
if(but[i][j + 1].val == 9) ++counter;
if(but[i + 1][j - 1].val == 9) ++counter;
if(but[i + 1][j].val == 9) ++counter;
if(but[i + 1][j + 1].val == 9) ++counter;
}
if(counter > 0) but[i][j].val = counter;
counter = 0;
}
}
for (unsigned int i = 0; i < size; ++i) { //upper border
for (unsigned int j = 0; j < size; ++j) {
if (but[i][j].val != 9) {
if (i == 0 && j == 0) {
if (but[i][j + 1].val == 9) ++counter;
if (but[i + 1][j].val == 9) ++counter;
if (but[i + 1][j + 1].val == 9) ++counter;
if (counter > 0) but[i][j].val = counter, counter = 0;
}
if (i == 0 && j == size - 1) {
if (but[i][j - 1].val == 9) ++counter;
if (but[i + 1][j].val == 9) ++counter;
if (but[i + 1][j - 1].val == 9) ++counter;
if (counter > 0) but[i][j].val = counter, counter = 0;
}
if (i == 0 && (j > 0 && j < size - 1)) {
if (but[i][j - 1].val == 9) ++counter;
if (but[i][j + 1].val == 9) ++counter;
if (but[i + 1][j - 1].val == 9) ++counter;
if (but[i + 1][j].val == 9) ++counter;
if (but[i + 1][j + 1].val == 9) ++counter;
if (counter > 0) but[i][j].val = counter, counter = 0;
}
if (i == size - 1 && j == 0) { //lower border
if (but[i - 1][j].val == 9) ++counter;
if (but[i - 1][j + 1].val == 9) ++counter;
if (but[i][j + 1].val == 9) ++counter;
if (counter > 0) but[i][j].val = counter, counter = 0;
}
if (i == size - 1 && j == size - 1) {
if (but[i - 1][j].val == 9) ++counter;
if (but[i - 1][j - 1].val == 9) ++counter;
if (but[i][j - 1].val == 9) ++counter;
if (counter > 0) but[i][j].val = counter, counter = 0;
}
if (i == size - 1 && (j > 0 && j < size - 1)) {
if (but[i][j - 1].val == 9) ++counter;
if (but[i - 1][j - 1].val == 9) ++counter;
if (but[i - 1][j].val == 9) ++counter;
if (but[i - 1][j + 1].val == 9) ++counter;
if (but[i][j + 1].val == 9) ++counter;
if (counter > 0) but[i][j].val = counter, counter = 0;
}
if (j == 0 && (i > 0 && i < size - 1)) { //left border
if (but[i - 1][j].val == 9) ++counter;
if (but[i - 1][j + 1].val == 9) ++counter;
if (but[i][j + 1].val == 9) ++counter;
if (but[i + 1][j].val == 9) ++counter;
if (but[i + 1][j + 1].val == 9) ++counter;
if (counter > 0) but[i][j].val = counter, counter = 0;
}
if (j == size - 1 && (i > 0 && i < size - 1)) { //right border
if (but[i - 1][j].val == 9) ++counter;
if (but[i - 1][j - 1].val == 9) ++counter;
if (but[i][j - 1].val == 9) ++counter;
if (but[i + 1][j - 1].val == 9) ++counter;
if (but[i + 1][j].val == 9) ++counter;
if (counter > 0) but[i][j].val = counter, counter = 0;
}
}
}
}
return but;
}
void MainWindow::on_pushButton_pressed()
{
QVariant index_but = ui->comboBox->currentIndex(); //Find out the value selected in the ComboBox
int a = index_but.toInt();
switch(a){
case 0: //number of buttons = 10
{
My_PushButton** but = my_rand(10);
for(int i = 0; i < 10; ++i){
for(int j = 0; j < 10; ++j){
ui->gridLayout_2->addWidget(&but[i][j], i, j);
}
}
ui->gridLayout_2->setSpacing(0);
ui->gridLayout_2->setSizeConstraint(QLayout::SetFixedSize);
/*for(int i = 0; i < 5; ++i){
delete [] but[i];
}
delete but;*/
break;
}
case 1: //number of buttons = 17
break;
case 2: //number of buttons = 25
break;
case 3: //self-entry
break;
default:
break;
}
}
Mainwindow.ui file:
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>650</width>
<height>800</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>649</width>
<height>770</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>1000</width>
<height>1000</height>
</size>
</property>
<property name="windowTitle">
<string>Minesweeper</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QWidget" name="horizontalLayoutWidget">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>157</width>
<height>41</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QComboBox" name="comboBox">
<property name="editable">
<bool>false</bool>
</property>
<property name="currentText">
<string>Level 1</string>
</property>
<item>
<property name="text">
<string>Level 1</string>
</property>
</item>
<item>
<property name="text">
<string>Level 2</string>
</property>
</item>
<item>
<property name="text">
<string>Level 3</string>
</property>
</item>
<item>
<property name="text">
<string>Self-entry</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Start</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="gridLayoutWidget">
<property name="geometry">
<rect>
<x>10</x>
<y>90</y>
<width>601</width>
<height>541</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_2"/>
</widget>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<widget class="QMenuBar" name="menubar">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>650</width>
<height>21</height>
</rect>
</property>
<widget class="QMenu" name="menuMinesweeper">
<property name="enabled">
<bool>true</bool>
</property>
<property name="title">
<string>Menu</string>
</property>
<addaction name="action"/>
<addaction name="separator"/>
<addaction name="actionNotes"/>
</widget>
<addaction name="menuMinesweeper"/>
</widget>
<action name="action">
<property name="text">
<string>Rules of the game</string>
</property>
</action>
<action name="actionNotes">
<property name="text">
<string>Notes</string>
</property>
</action>
</widget>
<resources/>
<connections/>
</ui>
Ui::MainWindow *getPointer(){ return ui; }
that returns a pointer to the form. In the My_PushButton
class, I added a pointer that takes a getter from MainWindow
-
MainWindow m;
Ui::MainWindow *form = m.getPointer();
, now I can refer to the desired form object - form->gridLayout_2->setEnabled(false);
, but the object does not need to be changed.
The getter, of course, has a public
access modifier.
It was possible to do as drescherjm said, but due to further obstacles I had to take a global pointer to the form and through it carry out the necessary manipulations with objects. Yes, I understand that this approach is not very desirable, but for myself (training) it will do. And just as Sergey Tatarincev (in post https://ru.stackoverflow.com/a/1330855/460029) said - this also works. Thanks to all.