Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Использование слотов объектов собственных классов, Крестики-нолики проблема 
:(
    Опции темы
olegg95
Дата 3.5.2013, 20:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 10.10.2012

Репутация: нет
Всего: нет



   Решил реализовать поле для крестиков-ноликов в Qt.   Делаю его при помощи кнопок. Крестики и нолики будут отображаться символами(буковка o или x). Поле игры, состоящее из кнопок создал при помощи дизайнера (3 на 3). Назвал кнопки: kletka1, kletka2….. .
    
    Кнопки будут только отображать состояние элементов двумерного массива объектов класса    Kletka, созданного мной в конструкторе главной формы.  Класс Kletka содержит поля:
 int value(0-пустая клетка, 1-нолик, 2-крестик )  и QPushButton * p – указатель кнопку,  соответствующую данной клетке игрового поля.    

    Для изменения состояния соответствующей кнопки(вместе с изменением значения поля value) пытаюсь использовать соответствующие слоты void Set_value() и void Set_Button_value(), созданные мной внутри класса Kletka.

    А теперь проблема! При попытке вызвать какой-либо слот для элемента массива клеток начинаются всякие ошибки и ничего не получается.
   Подскажите пожалуйста, как решить проблему и как правильно использовать слоты элементов собственных классов?  

mainwindow.h
Код

//класс, реализующий клетку поля для крестиков-ноликов;
class Kletka
{
public:
int value;
QPushButton * p;
//конструктор по умолчанию
Kletka()
{
    value=0;
    p=nullptr;
}
//слот для изменения значения value;
//Это тест. Проверка работоспособности. Поэтому присвоиваю единицу просто пока.  
void Set_value()
{
    value=1;
}

//слот для отображения значения клетки на кнопке
void Set_Button_value()
   {
    if (value==1){p->setText("0");}
    else if (value==2){p->setText("x");}
    else {p->setText(" ");}
   }
};

mainwindow.cpp
   

mainwindow.cpp 

Код

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    Kletka k[3][3];
    k[0][0].p=(ui->kletka1);
    connect(ui->kletka1,SIGNAL(clicked()),k[0][0],SLOT(Set_value()));// ТУТ НАЧИНАЮТСЯ ПРОБЛЕМЫ!!!

}


         
  Помогите пожалуйста! Очень нужно разобраться с этим для написания курсовой.  

 

Это сообщение отредактировал(а) olegg95 - 3.5.2013, 20:28
PM MAIL   Вверх
math64
Дата 4.5.2013, 15:51 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 23
Всего: 72



Слоты должны быть в секции public slots: или private slots:
У тебя Set_value() и Set_Button_value() не слоты, а обычные методы.

Добавлено через 4 минуты и 58 секунд
2. Kletka k[3][3] создается на стеке. После выхода из конструктора эти объекты будут автоматически уничтожены.
Нужно поле Kletka* m_kletka[3][3]; в MainWindow. В конструкторе в цикле нужно создавать клетки по new.
Удалять в деструкторе или задать родителем клеток главное окно.


PM   Вверх
olegg95
Дата 4.5.2013, 17:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 10.10.2012

Репутация: нет
Всего: нет



 Спасибо! Но я не могу создавать  клетки по new в конструкторе, потому что для их создания я использую дизайнер форм. Как тогда?   
PM MAIL   Вверх
math64
Дата 5.5.2013, 07:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 23
Всего: 72



Вызывашь setupUi() а после него досоздаёшь то, что не можешь создать дизайнером. Можно даже удалять объекты созданные дизайнером. Я, например, часто удаляю центральный виджет и заменяю на свой, добавляю комбо-боксы в панель инструментов - дизайнер позволяет добавлять только действия, панели в строку состояния - дизайнер туда ничего не позволяет добавлять, добавляю док-панели - их удобнее создавать в отдельном классе, а дизайнер не позволяет группировать их в закладки, созадю таймеры, модели для таблиц и т.д. Необходимые поля добавляются в секцию private обычно в конце объявления MainWindow в mainwindow.h вручную.
PM   Вверх
olegg95
Дата 5.5.2013, 12:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 10.10.2012

Репутация: нет
Всего: нет



 Странно. Но при попытке создать хоть какой-нибудь слот внутри собственного класса выдаёт ошибки:

Код

class Kletka
{
 private:
  int value;

private slots:
  void set_Button_value()
  {
      value=1;
  }
};

    

Присоединённый файл ( Кол-во скачиваний: 1 )
Присоединённый файл  qterror.jpg 23,16 Kb
PM MAIL   Вверх
math64
Дата 5.5.2013, 14:01 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 23
Всего: 72



Нужен макрос Q_OBJECT сразу после { в новой строке.

Добавлено через 54 секунды
И наследование от QObject/
PM   Вверх
olegg95
Дата 5.5.2013, 15:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 10.10.2012

Репутация: нет
Всего: нет



 Объясните пожалуйста, где именно setupUi() вызвать нужно, если я элементы класса Kletka в массиве создаю?    

 Кнопкам, написанным вручную, изменять параметры и позиционировать сложно очень. Может удобней будет вместо Kletka[i][j]=new Kletka, присвоить каждому элементу p(Указатель на QPushButton) маассива вручную соответствующую кнопку, построенную с помощью дизайнера? Как вы считаете?      
  Я вообще, честно говоря, не понимаю как с такими кнопками работать. Каждой из них координаты расположения отдельно задавать что ли?     

Это сообщение отредактировал(а) olegg95 - 5.5.2013, 15:45
PM MAIL   Вверх
math64
Дата 5.5.2013, 18:31 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 23
Всего: 72



Почти как ты делал, но создаёшь не на стеке, а в поле класса:
Код

class MainWindow : public QMainWindow {
Q_OBJECT
public:
   MainWindow(QWidget *parent) :
     QMainWindow(parent),
     ui(new Ui::MainWindow)
  {
     ui->setupUi(this);
     m_kletka[0][0] = new Kletka(this, 0, 0,  ui->kletka1);   
     m_kletka[0][1] = new Kletka(this, 0, 1,  ui->kletka2);   
     m_kletka[0][2] = new Kletka(this, 0, 2,  ui->kletka3);   
     m_kletka[1][0] = new Kletka(this, 1, 0,  ui->kletka4);   
     m_kletka[1][1] = new Kletka(this, 1, 1,  ui->kletka5);   
     m_kletka[1][2] = new Kletka(this, 1, 2,  ui->kletka6);   
     m_kletka[2][0] = new Kletka(this, 2, 0,  ui->kletka7);   
     m_kletka[2][1] = new Kletka(this, 2, 1,  ui->kletka8);   
     m_kletka[2][2] = new Kletka(this, 2, 2,  ui->kletka9);   
   }
private:
  Kletka* m_kletka[3][3];
};

PM   Вверх
olegg95
Дата 5.5.2013, 20:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 10.10.2012

Репутация: нет
Всего: нет



  m_kletka[0][0] = new Kletka(this, 0, 0,  ui->kletka1);   
  Я так понял, this делает элемнт наследником главной формы, ui->kletka1 - указывается кнопка на главной форме которая должна принять роль этой самой new Kletka. Объясните пожалуйста, что означает второй и третий параметр в скобках. 
  ошибка: C2661: Kletka::Kletka: нет перегруженной функции, принимающей 4 аргумента   
Что я не правильно сделал?   
PM MAIL   Вверх
al0
Дата 5.5.2013, 21:09 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











В дизайнере кликаете правой кнопкой мыши на кнопку вашей клетки. В открывшемся списке выбираете "Перейти к слоту..." Откроется список выбора слота. Выбираете нужный - clicked(), clicked(bool) или другой и получаете рабочий код.

Этот ответ добавлен с нового Винграда - http://vingrad.com
  Вверх
math64
Дата 5.5.2013, 22:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 23
Всего: 72



al0 - не получится так. Во время дизайна нет объектов Kletka. Правда, можно унаследовать класс Kletka от QButton.
Olegg95 - я полагаю, Kletka должна знать свои координаты и их можно передать в конструктор. Также там передаётся QButton, с которой нужно сделать connect.
PM   Вверх
olegg95
Дата 6.5.2013, 15:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 10.10.2012

Репутация: нет
Всего: нет



  Это всё в конструкторе сделать да?
А как указать сигнал, генерирующийся при изменении текста кнопки? 
PM MAIL   Вверх
Jeka178RUS
Дата 6.5.2013, 15:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 85
Регистрация: 3.9.2012

Репутация: нет
Всего: нет



Создается впечатление что Вам сначала стоит как следует почитать про систему сигналов и слотов, так вопросы озвучиваемые Вами мягко говоря глупые.

Для подачи сигнала используется emit для соединение сигнала со слотом connect

http://habrahabr.ru/post/50812/
http://www.developer.nokia.com/Community/W...D0%B2_%D0%B2_Qt

Так например QPushButton не имеет сигнала о изменении текста (что логично, текст кнопки не её целевая функция), а вот QLineEdit как раз имеет. Если Вы хотите научить кнопку сообщать о изменении текста на ней, то вам необходимо наследоваться и реализовывать этот функционал самостоятельно, однако выглядеть это будет странно.

Куда проще и логичнее наследоваться от QWidget и переопределив paintEvent и mouseClickevent реализовать игровое поле. А таком случае зная положение курсора в момент нажатия мыши легко определить на какой "клетке" (зная размеры игрового поля и  размеры игровой сетки) был клик. Хранить внутри матрицу значений для игровой сетки и используя эти данные рисовать необходимые символы в paintEvent.

Это сообщение отредактировал(а) Jeka178RUS - 6.5.2013, 15:31
PM MAIL   Вверх
math64
Дата 6.5.2013, 17:05 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 23
Всего: 72



На самом деле проще использовать таблицу - у неё всё нужное уже есть, нужно реализовать модель таблицы.
Для отрисовки ячейки таблицы можно использовать делегат, но в данном случае можно всё реализовать в модели, там есть большое разнообразие ролей.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.0801 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.