Russian Qt Forum

Qt => Вопросы новичков => Тема начата: Satansoft от Ноябрь 22, 2014, 17:29



Название: Некорректное выполнение
Отправлено: Satansoft от Ноябрь 22, 2014, 17:29
Доброго времени, необходимо создать приложение с GUI, реализующее следующую задачу:
20 детей едят из одной миски, в которой 100 слив, когда ребенок хочет кушать, он берёт из миски одну сливу, только если миска не пуста, если же пуста - зовёт маму, чтобы та наполнила её (соотвественно 100 слив), создать многопоточное приложение, реализующее задачу.

С GUI немного разобрался, но вот логика... реализовывал её средствами С++11 т.к так яснее создание тредов. Приложение вызывает по нажатии на кнопку функции из класса MainWindow, результат выполнения метода Dinner_a выводит в QListWidget. Основной проблемой является доступ к методам внутри класса и пересылкам их возвращаемых значений в вызов. понятно, что вызов из кнопки - колханство, но как связать вызов из main с нажатием кнопки не ясно.

mainwindow.h
Код:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#define M 100
#include <ui_mainwindow.h>
#include <QMainWindow>
#include <QListWidget>
#include <thread>
#include <QThread>
#include <mutex>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);

        int Cooking_a()
        {
            int food=M;

            return food;
        }

        int Dinner_a(int food)
        {
            std::mutex eating;
            eating.lock();
            QThread::msleep(5000);
            ui->listWidget->addItem(QString::number(food) + " cannibal ate");
            food--;
            eating.unlock();

            return 0;
        }

            ~MainWindow();

private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

mainwindow.cpp
Код:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#define N 20
#define M 100

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
    std::thread Cannibals[N];
    while(true)
    {
        std::thread cook = std::thread(&MainWindow::Cooking_a, this);
        cook.join();

        int food=Cooking_a();


        for(int i=0;i<food;i++)
                {
                   int coven = M;
                   Cannibals[i] = std::thread(&MainWindow::Dinner_a, this, coven);
                   coven --;
                   Cannibals[i].join();
                }

    }

}

void MainWindow::on_pushButton_2_clicked()
{
    exit(0);
}


Название: Re: Некорректное выполнение
Отправлено: Alexu007 от Ноябрь 23, 2014, 11:40
Чё то маловато кода для такой задачи...


Название: Re: Некорректное выполнение
Отправлено: Igors от Ноябрь 23, 2014, 15:28
Отличная задачка, только сначала с логикой разберитесь, а потом UI рисуйте
Код:
        int Dinner_a(int food)
        {
            std::mutex eating;
            eating.lock();
            QThread::msleep(5000);
            ui->listWidget->addItem(QString::number(food) + " cannibal ate");
            food--;
            eating.unlock();

            return 0;
        }
1) Локальный мутекс ничего не защищает
2) Пока выходит что дите съело одну сливу и return 0. А должно есть пока папв (push_button) не скажет "хватит жрать"
3) Никто не говорил что пока один ест свою сливу - все должны ждать, поэтому msleep должен быть не под мутексом
4) UI не будет работать из др нитки (а только из главной), поэтому заряжайте сигнал

Потом дальше поговорим, пока слишком резво  :)


Название: Re: Некорректное выполнение
Отправлено: vulko от Ноябрь 23, 2014, 17:24
реализовывал её средствами С++11 т.к так яснее создание тредов

мож лучше qthread, не?))


Название: Re: Некорректное выполнение
Отправлено: Igors от Ноябрь 24, 2014, 12:54
Здесь хорошо на семафорах, содержательная часть

Код
C++ (Qt)
bool doEat = true;
QAtomicInt numPlum(100);
QSemaphore childSemaphore(numPlum);
QSemaphore mamaSemaphore;
 
void ChildThread::run( void )
{
while (doEat) {
 childSemaphore.acquire();
 if (!doEat) break;
 if (!numPlum.deref())
  mamaSemaphore.release();
}
}
 
Но можно ли обойтись без атомарного счетчика (numPlum)? Мне кажется что нет


Название: Re: Некорректное выполнение
Отправлено: Alexu007 от Ноябрь 24, 2014, 21:01
Задача интересная. Я бы тож такую задачу попробовал решить. Только не знаю, с чего начать. Вот допустим, я сделал форму, на ней кнопку пуск. Пару меток - дети, которые кушают. То есть они сперва сытые (допустим 10), потом начинают хотеть кушать (сытость падает), и когда она становится равна 0 - берут сливу.  Пару - сперва два потока замутить, потом когда принцип будет понятен, увеличить можно.

И собственно тарелка int - на форме это метка с цифрой, сколько на ней слив. Сразу вопрос - где объявлять "тарелку"? Делать её глобальной, или где? К ней кроме детей ещё мама должна доступ иметь.

Дети очевидно класс и экземпляры класса. Они должны уметь "голодать", т.е. сами уменьшать свою сытость до 0. Как они могут голодать? В потоке ребёнка через паузу уменьшать соотв. число?  И отправлять сигнал к слоту тарелки?


Название: Re: Некорректное выполнение
Отправлено: Old от Ноябрь 24, 2014, 21:26
А вы не начинайте с формы. Начните с участников действа.
У нас есть тарелка, у нас есть мама, у нас есть дети. Это три класса.
Мама должна уметь накладывать фрукты в тарелку, т.е. у тарелки должен быть метод для этого (мама знает про тарелку - хранит ссылку на объект тарелки).
Дети должны уметь брать фрукты, еще один метод (дети так же знают про тарелку + они знают про маму, что бы ее позвать).
Можно продумать вариант с "умной" тарелкой, которая зовет маму когда опустеет вместо детей. :)
Голодание у детей можно сделать с помощью таймера, вышло время - ребенок проголодался - полез за фруктом - нет, позвал маму.

А вот когда это все заработает, можно подумать как это удобно показывать на форме.

Псевдокод функции main:
Код
C++ (Qt)
{
   QApplication app(...);
 
   // Создали тарелку, пока пустую
   Plate plate;
 
   // Маман
   Mom mom( plate );
 
   // Спиногрызы
   QList<Child> childs;
   for( int i = 0; i < MaxChilds; ++i )
       childs.append( Child( plate, mom, appetite( i ) ) );    // У каждого ребенка свой аппетит
 
   // Киданули им слив
   plate.putPlum( 100 );
 
   // Запустили симуляцию
   app.exec();
}
 

Объект мамы считает сколько оно всего положила слив, каждый ребенок считает сколько он съел. Всю статистику потом визуализируем.


Название: Re: Некорректное выполнение
Отправлено: Old от Ноябрь 24, 2014, 22:03
Наверное самый примитивный вариант тарелки:

Код
C++ (Qt)
class Plate
{
public:
   explicite Plate() : m_plums( 0 ) {}
 
   // Положить слив
   void putPlums( unsigned int num )
   {
       QMutexLocker lock( &m_mutex );
       m_plums += num;
   }
 
   // Если в тарелке сливы есть, то берем одну и возвращаем true
   // Если тарелка пуста, возвращаем false (по этому признаку, ребенок может звать маму)
   bool takePlum()
   {
       QMutexLocker lock( &m_mutex );
       if( !m_plums )
           return false;
       --m_plums;
       return true;
   }
 
private:
   unsigned int m_plums;
   QMutex m_mutex;
};
 

Примерный алгоритм: дети, как проголодается, вызывают takePlum тарелки, как только эта функция начнет возвращать false, они начинаю звать маму, мама соответственно делает putPlums тарелке.


Название: Re: Некорректное выполнение
Отправлено: Alexu007 от Ноябрь 24, 2014, 22:36
А вы не начинайте с формы. Начните с участников действа.
У нас есть тарелка, у нас есть мама, у нас есть дети. Это три класса.
Мама должна уметь накладывать фрукты в тарелку, т.е. у тарелки должен быть метод для этого (мама знает про тарелку - хранит ссылку на объект тарелки).
Дети должны уметь брать фрукты, еще один метод (дети так же знают про тарелку + они знают про маму, что бы ее позвать).
Можно продумать вариант с "умной" тарелкой, которая зовет маму когда опустеет вместо детей. :)
Голодание у детей можно сделать с помощью таймера, вышло время - ребенок проголодался - полез за фруктом - нет, позвал маму.

А вот когда это все заработает, можно подумать как это удобно показывать на форме.
Ну дети понятно. Их хоть много. Мама класс, ладно. Но тарелка? Это же просто переменная, в которую мама добавляет, а дети забирают. Её тоже оформлять как класс? Из одной переменной?


Название: Re: Некорректное выполнение
Отправлено: Old от Ноябрь 24, 2014, 22:39
Я бы оформил, точнее уже оформил чуть выше. :)
Сейчас у нас в тарелке могут быть только сливы, а завтра там будут еще яблоки и персики с виноградом.


Название: Re: Некорректное выполнение
Отправлено: Igors от Ноябрь 25, 2014, 10:30
Я бы оформил, точнее уже оформил чуть выше. :)
Сейчас у нас в тарелке могут быть только сливы, а завтра там будут еще яблоки и персики с виноградом.
А пока только сливы - я бы не спешил с классом "тарелка".

Код
C++ (Qt)
   // Маман
   Mom mom( plate );
 
   // Спиногрызы
   QList<Child> childs;
   for( int i = 0; i < MaxChilds; ++i )
       childs.append( Child( plate, mom, appetite( i ) ) );    // У каждого ребенка свой аппетит
 
   // Киданули им слив
   plate.putPlum( 100 );
 
   // Запустили симуляцию
   app.exec();
}
 
Хмм... спорно. Если тарелка сама добавляет сливы - зачем тогда мама? И технически неясно что есть копирование класса Child. Я бы начинал по-другому, сначала распределил бы классы по ниткам

- каждый ребенок нитка
- мама еще 1 нитка

Ну и должен быть папа - пресловутый флажок по которому все завершается. Пусть это будет из главной нитки по нажатию на кнопку. Скелетик такой

Код
C++ (Qt)
   QApplication app(...);
 
   // Мама
   Mom mom();
 
   // Дети
   QVector <Child *> childs;
   for( int i = 0; i < MaxChilds; ++i )
       childs.append(new Child(...));
 
   // запускаем
   mom.start();  
   for( int i = 0; i < MaxChilds; ++i )
       childs[i]->start();
 
   // UI
   SetupUI();
   app.exec();
 
  // ждем пока все нитки выйдут
   mom.wait();  
   for( int i = 0; i < MaxChilds; ++i )
       childs[i]->wait();
 
  // печатаем статистику
  PrintStat();
 
  // удаляем отработавшие нитки
 qDeleteAll(childs.begin(), childs.end());
По поводу "зовет маму" - можно по-всякому

- если миска пуста. Тут может получиться что 2 и более детей зовут. Это не проблема, мама (захватив мутекс) может проверить

- зовет взявший последнюю сливу, это оптимальнее

2Alexu007 - главное в задаче не сказано, а подразумевается: нужно каким-то образом останавливать нитки (детей и маму) когда им нечего делать             


Название: Re: Некорректное выполнение
Отправлено: Old от Ноябрь 25, 2014, 11:22
А пока только сливы - я бы не спешил с классом "тарелка".
Напрасно, все меняется очень быстро, а потом нужно будет всех переучивать на тарелу.

Хмм... спорно. Если тарелка сама добавляет сливы - зачем тогда мама?
Нет, тарелка сама не добаляет, это должна делать мама (вызывать этот метод).
В main мы изначально наполняем тарелку сливами, что бы они уже там были. Этого можно не делать, тогда дети захотев взять сливу и обнаружив, что тарелка пуста - позовут маму и она ее наполнит, уже после начала симуляции.

И технически неясно что есть копирование класса Child.
Считайте что внутри Child используется Implicit Sharing, хотя это был просто псевдокод.

Я бы начинал по-другому, сначала распределил бы классы по ниткам
- каждый ребенок нитка
- мама еще 1 нитка
Это все в условии задачи.


Название: Re: Некорректное выполнение
Отправлено: Igors от Ноябрь 25, 2014, 11:31
Нет, тарелка сама не добаляет, это должна делать мама (вызывать этот метод).
Дело в том что если Вы хотели делать на мутексах (конечно можно и так), то мутекс должна захватить мама (а не тарелка)


Название: Re: Некорректное выполнение
Отправлено: Old от Ноябрь 25, 2014, 11:33
Дело в том что если Вы хотели делать на мутексах (конечно можно и так), то мутекс должна захватить мама (а не тарелка)
С чего бы это? :)

И что значит захватывает мама или тарелка? Если мама вызывает метод тарелки putPlums, кто захватывает мьютекс? :)

А делать можно еще много на чем, хоть на атомарных операциях.


Название: Re: Некорректное выполнение
Отправлено: Igors от Ноябрь 25, 2014, 12:46
С чего бы это? :)

И что значит захватывает мама или тарелка? Если мама вызывает метод тарелки putPlums, кто захватывает мьютекс? :)
Покажите как "разбуженная мама" наполняет тарелку (и снова засыпает), я объясню что имею ввиду.


Название: Re: Некорректное выполнение
Отправлено: Old от Ноябрь 25, 2014, 12:48
Покажите как "разбуженная мама" наполняет тарелку, я объясню что имею ввиду.
Код
C++ (Qt)
void Mom::fill()
{
   m_plate.setPlums( 100 );
}
 


Название: Re: Некорректное выполнение
Отправлено: Igors от Ноябрь 25, 2014, 12:53
Покажите как "разбуженная мама" наполняет тарелку, я объясню что имею ввиду.
Код
C++ (Qt)
void Mom::fill()
{
   m_plate.setPlums( 100 );
}
 
Я просил "разбуженную" и "снова засыпающую" (а не просто рисование методов  :))


Название: Re: Некорректное выполнение
Отправлено: Old от Ноябрь 25, 2014, 12:56
Я просил "разбуженную" и "снова засыпающую" (а не просто рисование методов  :))
Я пока так далеко не думал. :)
Жду реакции Alexu007.

Но могу вам сразу сказать, если я правильно понял, к чему вы начали этот разговор, то это не все необходимые мутексы (в тарелке). Понадобятся и другие средства синхронизации.


Название: Re: Некорректное выполнение
Отправлено: Igors от Ноябрь 25, 2014, 13:30
Жду реакции Alexu007.
Там пареньку в первый раз трудно придется, это ему не goto. Ну посмотрим, может выплывет...

Но могу вам сразу сказать, если я правильно понял, к чему вы начали этот разговор, то это не все необходимые мутексы (в тарелке). Понадобятся и другие средства синхронизации.
А зачем? Это та же очередь, та же схема (Q)WaitCondition, только извлекающий еще может будить,


Название: Re: Некорректное выполнение
Отправлено: Old от Ноябрь 25, 2014, 13:33
А зачем?
Пока не знаю, но детей много и будить они могут толпой, а положить мама должна один раз.

Тут бы вообще хорошо подошел семафор: мама добавляет - дети убавляют, но все равно нужно атомарно проверять количество и звать маму, иначе может получиться так, что child проверил тарелку, там пусто, заснул, мама положила новых слив, он проснулся и давай заново звать маму, а сливы уже на тарелке. Все равно нужно это контролировать.


Название: Re: Некорректное выполнение
Отправлено: Igors от Ноябрь 25, 2014, 14:54
Тут бы вообще хорошо подошел семафор: мама добавляет - дети убавляют, но все равно нужно атомарно проверять количество и звать маму, иначе может получиться так, что child проверил тарелку, там пусто, заснул, мама положила новых слив, он проснулся и давай заново звать маму, а сливы уже на тарелке. Все равно нужно это контролировать.
Да, хотелось бы напр так
Код
C++ (Qt)
void ChildThread::run( void )
{
while (doEat) {
  childSemaphore.acquire();
  if (!childSemaphore.available())
    mamaSemaphore.release();
}
}
Но так пробьет. "Близок локоть да не укусишь"

А что же так поредели ряды обсуждающих? Судя по др тредам, "многопоточностью" владеют все, а тут какая-то детская задачка со сливами....  :)


Название: Re: Некорректное выполнение
Отправлено: Alexu007 от Ноябрь 25, 2014, 18:44
Самое простое - зовёт маму тот, кому не хватило сливы. То есть отправляет сигнал маме. Мама наполняет тарелку.

Алгоритм голодных детей детей такой: пробуют взять сливу. Если слив нет - зовут маму. Снова пробуют взять сливу - и так далее.

Алгоритм мамы: получает сигнал - проверяет пуста ли тарелка - если пуста, наполняет - если не пуста, игнорирует сигнал.

У детей получаются бесконечные циклы, останавливать потоки не надо. Только в конце программы. Мама вообще может быть функцией, которая вызывается в слоте, связанном с сигналами голодных детей. Но не очень понятно, где должен быть этот слот, если несколько потоков. Ему тоже свой поток создавать?

Пока ещё не решился начать... сложновато как то.


Название: Re: Некорректное выполнение
Отправлено: Igors от Ноябрь 26, 2014, 11:51
Самое простое - зовёт маму тот, кому не хватило сливы. То есть отправляет сигнал маме. Мама наполняет тарелку.

Алгоритм голодных детей детей такой: пробуют взять сливу. Если слив нет - зовут маму. Снова пробуют взять сливу - и так далее.

Алгоритм мамы: получает сигнал - проверяет пуста ли тарелка - если пуста, наполняет - если не пуста, игнорирует сигнал.

У детей получаются бесконечные циклы, останавливать потоки не надо. Только в конце программы.
Это (неудачный) план обойтись без всякой синхронизации, просто налепив бесконечные циклы. В итоге 21 нитка молотит по-пустому, вероятно загрузив проц до упора. Др словами куча детей орет на маму которая сбивается с ног  :)

В таких задачах всегда имеется ввиду что нитка/поток ожидает пока для нее нет работы. Поэтому то что Вы изложили - не решение.   


Название: Re: Некорректное выполнение
Отправлено: Igors от Ноябрь 26, 2014, 17:37
Ладно, реализация на одном мутексе, содержательная часть
Код
C++ (Qt)
void ChildThread::run( void )
{
while (doEat) {
  mutex.lock();
  while (numPlum == 0) {
   condition.wait(&mutex);
   if (!doEat) {
     mutex.unlock();
     return;
   }
  }
  --numPlum;
  if (!numPlum)
   condition.wakeAll(&mutex);
  mutex.unlock();
  // здесь задержка, статистика
}
}
 
void MamaThread::run( void )
{
while (doEat) {
  QMutexLocker lock(&mutex);
  while (numPlum > 0) {
   condition.wat(&mutex);
   if (!doEat) return;
  }
  numPlum = maxPlum;  // const int maxPlum = 100
  condition.wakeAll(&mutex);
}
}
 
void StopEat( void )
{
 doEat = false;
 QMutexLocker lock(&mutex);
 condition.wakeAll();
}
Критикуем, опровергаем - ну или хотя бы задаем вопросы  :)


Название: Re: Некорректное выполнение
Отправлено: Old от Ноябрь 26, 2014, 17:45
Ваша беда в том, что вы целеустремленно стараетесь избегать QMutexLocker.
Правда непонятно почему. Ну и имеете проблемы от которых он избавляет.

Я бы использовал две условных переменных для ребёнка и для мамы, тогда дети не будили бы друг друга криками "Мамаааааа!".


Название: Re: Некорректное выполнение
Отправлено: Alexu007 от Ноябрь 26, 2014, 17:50
Ну почему? Большую часть времени дети сыты и переваривают сливу. В это время работает таймер или цикл с паузами - для каждого ребёнка свой. Потом слива заканчивается и ребёнок лезет в тарелку за следующей. А если останавливать процессы - то кто будет считать, когда их пора включать?


Название: Re: Некорректное выполнение
Отправлено: Igors от Ноябрь 26, 2014, 18:01
Ваша беда в том, что вы целеустремленно стараетесь избегать QMutexLocker.
Правда непонятно почему. Ну и имеете проблемы от которых он избавляет.
Да, исправил, спасибо

Я бы использовал две условных переменных для ребёнка и для мамы, тогда дети не будили бы друг друга криками "Мамаааааа!".
Можно и 2 (Ваша реализация?), может еще лучше маму на семафор - дело вкуса. Зато у меня всего 1 мутекс, а "ложные побудки" неопасны (тем более если большинство еще едят свою сливу).   


Название: Re: Некорректное выполнение
Отправлено: Igors от Ноябрь 26, 2014, 18:07
Ну почему? Большую часть времени дети сыты и переваривают сливу. В это время работает таймер или цикл с паузами - для каждого ребёнка свой. Потом слива заканчивается и ребёнок лезет в тарелку за следующей. А если останавливать процессы - то кто будет считать, когда их пора включать?
Синхронизация - это, грубо говоря, стоп/останов. Это должно работать железно, без всяких предположений. Напр мама ушилась (встретила др интересного мужчину) на сутки или двое. Все это время 20 детей должны спать на мутексе (а не гавкать сигналами). Ясно?


Название: Re: Некорректное выполнение
Отправлено: Satansoft от Ноябрь 27, 2014, 02:32
Я рад, что мой вопрос повеселил присутствующих и они ударились в концепцию "У каждого свой код", однако с того времени проект переделывался 6 раз и многое переосмыслено, код стал чище и графику с логикой разделил, снова вопрос дня, почему объявление указателя на требуемый класс вызывает ошибку doesn't name of type (про хедер не шутить)

Что я сделал: минимум 10 раз переписал вручную подключение хедера, юзнул после ctrl+click, написал пременную-указатель с заглавной и пробовал пихать в namespace этот класс - всё тщетно...

На вопрос "Почему QThread не юзаю" отвечу, что параллельно пишу этот код и на чистом Qt, и хоть он более послушно выполняется, там так же проблема с объявлением указателя на класс и не ясно как массив тредов формировать, проинформируете?

cannibals.h
Код:
#ifndef CANNIBALS_H
#define CANNIBALS_H
#include "mainwindow.h"
#include <QThread>
#include <thread>
#include <mutex>
#include <time.h>

class Cannibals : public QThread
{
    Q_OBJECT
public:
    explicit Cannibals(QObject *parent = 0);
    void Cooking();
    void Dinner();
    void Dinner_a(int);

private:
    std::thread Cook;
    std::mutex eating;
    int food=10;

signals:
    void NumberChanged(int);

public slots:

};

#endif // CANNIBALS_H

cannibals.cpp
Код:
#include "cannibals.h"
#include "mainwindow.h"
#define M 100

Cannibals::Cannibals(QObject *parent) :
    QThread(parent)
{
}

void Cannibals::Cooking()
{
     food=M;
}

void Cannibals::Dinner_a(int z)
    {
        eating.lock();
        for(int i=0; i<z;i++){
        Dinner();}
        eating.unlock();
    }

void Cannibals::Dinner()
{
    if(food!=0){
    emit NumberChanged(food);
    --food;}
    else
    Cook = std::thread(&Cannibals::Cooking, this);
    Cook.join();

    msleep(rand()%2000);
}

mainwindow.h (косяк в Cannibals *Foo;)
Код:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "cannibals.h"
#include <ui_mainwindow.h>
#include <QMainWindow>
#include <thread>
#define N 20


namespace Ui {
class MainWindow;}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
     Cannibals *Foo;

private slots:
    void on_pushButton_clicked();

private:
    Ui::MainWindow *ui;
    std::thread Cannibal[N];

public slots:
    void OnNumberChanged (int);
};

#endif // MAINWINDOW_H

mainwindow.cpp
Код:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#define N 20
#define M 100
#define P (M/N)

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(Foo,SIGNAL(NumberChanged(int)),this,SLOT(OnNumberChanged(int)));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{

            for(int i=0;i<N;i++)
                    {
                       Cannibal[i] = std::thread(&Cannibals::Dinner_a, Foo, P);
                    }

            for(int i=0;i<N;i++)
            {
             Cannibal[i].join();
            }
}

void MainWindow::OnNumberChanged(int Num)
{
    ui->listWidget->clear();
    ui->pushButton->setEnabled(false);
    ui->listWidget->addItem(QString(Num) + " cannibal ate");
}


Название: Re: Некорректное выполнение
Отправлено: Igors от Ноябрь 27, 2014, 11:19
снова вопрос дня, почему объявление указателя на требуемый класс вызывает ошибку doesn't name of type (про хедер не шутить)
Выложите проект, тогда посмотрим

однако с того времени проект переделывался 6 раз и многое переосмыслено, код стал чище и графику с логикой разделил,
Видимо переосмысление касалось только UI и/или С++ 11. Что делает Ваш код: запускает 20 ниток, каждая поедает 5 слив и.. завершается. Причем счетчик слив у каждой свой. Но ведь это совсем не то что требовалось.


Название: Re: Некорректное выполнение
Отправлено: Alexu007 от Ноябрь 27, 2014, 12:37
Подскажите пжалста, как правильно связать сигнал SendStr со слотом GetStr:

сигнал:

Код
C++ (Qt)
class WorkThread : public QThread
{
   Q_OBJECT
public:
   explicit WorkThread(QObject *parent = 0);
 
protected:
   void run();
 
signals:
 
   void SendStr(const QString str);
 
public slots:
 
};

слот:

Код
C++ (Qt)
namespace Ui {
class MyWidget;
}
 
class MyWidget : public QWidget
{
   Q_OBJECT
 
public:
   explicit MyWidget(QWidget *parent = 0);
   ~MyWidget();
 
private:
   Ui::MyWidget *ui;
   WorkThread *thread;
 
public slots:
   void MyEventHandler1();
   void MyEventHandler2();
 
   void GetStr(QString str);
 
};


Название: Re: Некорректное выполнение
Отправлено: gil9red от Ноябрь 27, 2014, 13:09
Код:
WorkThread * th = new WorkThread();
MyWidget * w = new MyWidget();
...
QObject::connect(th, SIGNAL( SendStr(QString) ), w, SLOT( GetStr(QString) ));


Название: Re: Некорректное выполнение
Отправлено: Satansoft от Ноябрь 27, 2014, 14:01
Проject целиком.


Название: Re: Некорректное выполнение
Отправлено: Igors от Ноябрь 27, 2014, 14:23
Проject целиком.
Ну так елы-палы, у Вас же хедеры циклические: mainwindow.h включает cannibals.h и наоборот. Так нельзя


Название: Re: Некорректное выполнение
Отправлено: Satansoft от Ноябрь 27, 2014, 14:38
Убрал хедер mainwindow из cannibals, так что теперь оно идёт примерно так main->mainwindow->cannibals, да только крашится exe даже не начавшись... с объявлениями и дефайнами всё ли в порядке и можно ли define объявлять в *.h, из cpp его же будет видно?


Название: Re: Некорректное выполнение
Отправлено: Alexu007 от Ноябрь 27, 2014, 16:01
Код
C++ (Qt)
WorkThread * th = new WorkThread();

Где объявлять - в конструкторе формы?  Везде ругается, что: ошибка: undefined reference to `WorkThread::WorkThread(QObject*)'.


Название: Re: Некорректное выполнение
Отправлено: Пантер от Ноябрь 27, 2014, 16:05
А конструктор WorkThread имеет реализацию?


Название: Re: Некорректное выполнение
Отправлено: Alexu007 от Ноябрь 27, 2014, 16:32
Код
C++ (Qt)
#include <QThread>
 
class WorkThread : public QThread
{
   Q_OBJECT
public:
   explicit WorkThread(QObject *parent = 0);
 
protected:
   void run();
 
signals:
 
   void SendStr(const QString str);
 
public slots:
 
};

Объявление класса. А какая ещё реализация?


Название: Re: Некорректное выполнение
Отправлено: Satansoft от Ноябрь 27, 2014, 16:42
Как создать 10 потоков в Qt? В цикле вызвать метод start?


Название: Re: Некорректное выполнение
Отправлено: Alexu007 от Ноябрь 27, 2014, 17:22
Примерно тот же вопрос. Только: каждый поток должен иметь свой RUN, свой сигнал и свой слот. Если 20 детей - добавлять в проект 20 файлов по одному для каждого класса потока?


Название: Re: Некорректное выполнение
Отправлено: Igors от Ноябрь 27, 2014, 17:35
Молодежжж, в этой теме Old и я писали заготовки, посмотрите, а потом спрашивайте


Название: Re: Некорректное выполнение
Отправлено: Alexu007 от Ноябрь 27, 2014, 18:00
Извините, но в ваших заготовках я не нашёл ответа на поставленные мной вопросы. Нужно несколько неодинаковых детей, каждый со своей скоростью поедания сливы и со своим сигналом.

С помощью new можно наклонировать одинаковых детей. Как сделать разных?


Название: Re: Некорректное выполнение
Отправлено: Old от Ноябрь 27, 2014, 18:10
С помощью new можно наклонировать одинаковых детей. Как сделать разных?
Передавать разные параметры при конструировании каждого экземпляра или настраивать их индивидуально после создания.


Название: Re: Некорректное выполнение
Отправлено: Satansoft от Ноябрь 27, 2014, 18:32
Мой вызов идёт из кнопки по обращению к указателю на класс, так что не ясно как там массив сделать ... А маман, при вызове этой дамы - КРАШЪ!!11


Название: Re: Некорректное выполнение
Отправлено: Igors от Ноябрь 27, 2014, 18:40
Нужно несколько неодинаковых детей, каждый со своей скоростью поедания сливы и со своим сигналом.
Конечно Вы имеете право на свой стиль/подход, но возможно лучше отложить мелочи/детали, а сначала решить принципиальные вопросы. То же касается UI ("фoрм") - лучше сначала консольная версия.

Сделать на слот-сигнал - признаться, я не вижу как :) Да, есть неск очевидных вариантов, но они не соответствуют изначальной постановке задачи, получается типа "ребенок просит сливу у мамы" - это совсем не то что спрашивалось.


Название: Re: Некорректное выполнение
Отправлено: Satansoft от Ноябрь 27, 2014, 18:58
Я интерпретирую задачку в алгоритм, в своём понимании:

20 детей - массив из 20 потоков, вызываемый по нажатию на кнопку
мама - представлена отдельным потоком

20 детей получают доступ к переменной, поочередно декрементируя её благодаря мьютексу (до сих пор не ясно как быть, когда детей 20, а слив 100, выкрутился дав каждому по 100/20 слив...)
по достижении переменной 0, вызывается поток мамы, представленныйй отдельным классом, в котором объекту присвоивается 100, а затем переприсваивается классу деток через указатель на маму: food=mom->foodest;

Всё это выполняется неограниченное количество раз, пока не прервёмся (тут разные варианты)..


Название: Re: Некорректное выполнение
Отправлено: Alexu007 от Ноябрь 28, 2014, 01:04
Ну, значит каждый понял задачу по-своему. Точнее, я хочу её даже чуток усложнить - сделать детей неодинаковыми, чтобы каждый кушал свою сливу за разный промежуток времени (разный аппетит). Маман в моём понимании просто функция, которая наполняет пустую тарелку, и которую может вызвать любой из детей. А тарелка - глобальная переменная, к которой имеют доступ и дети и мама. Некошерно, но мне плевать.

Детей сделаю для начала одного, потом ещё двух, и посмотрим, как оно заработает.

Дети на экране будут представлены цифрой, показывающей степень голодности, допустим от 9 до 0, и когда 0 - ребёнок берёт сливу. Тарелка - цифра текущего количества слив. Мамы на экране не видно.

p.s. мама не функция, мама - слот, соединённый с сигналами детей.


Название: Re: Некорректное выполнение
Отправлено: Igors от Ноябрь 28, 2014, 07:45
Я интерпретирую задачку в алгоритм, в своём понимании:

20 детей - массив из 20 потоков, вызываемый по нажатию на кнопку
мама - представлена отдельным потоком

20 детей получают доступ к переменной, поочередно декрементируя её благодаря мьютексу (до сих пор не ясно как быть, когда детей 20, а слив 100, выкрутился дав каждому по 100/20 слив...)
по достижении переменной 0, вызывается поток мамы, представленныйй отдельным классом, в котором объекту присвоивается 100, а затем переприсваивается классу деток через указатель на маму: food=mom->foodest;

Всё это выполняется неограниченное количество раз, пока не прервёмся (тут разные варианты)..
У ребенка нет никакого своего счетчика 100/20, он берет сливу, ест ее, берет следующую и.т.д пока миска не пуста. Иначе зовет маму и ждет пока тарелка наполнится. Если кто-то другой уже позвал маму - сразу ждет.

Мама - постоянно действующее лицо (а не поток который запускается и сразу убивается как у Вас). Она ждет пока ее позовут, наполняет миску и снова ждет.

Смысл задачи - синхронизация, сделать так чтобы дети ждали когда мама наполнит, и наоборот, мама ждет когда дети позовут. "Ожидание" сводится к тому что нитка стоит на мутексе или семафоре


Название: Re: Некорректное выполнение
Отправлено: Alexu007 от Ноябрь 28, 2014, 10:32
Уря! Запустил 2 процесса, каждый запускается своей кнопкой и выводит в свою метку. Теперь этот мощный инструмент в руках дилетанта!!!

Пока ессно с 2-мя отдельными классами потоков и соотв. +4 файла в проект. А, кстати, что за фигня? Неужели каждый новый класс это обязательно 2 дополнительных файла? В каждом по неск. строчек кода. В один файл скинуть никак?

Теперь реализую "маму" по простому, без мьютексов и пауз. Например. Ребенок натыкается на пустю тарелку и начинает каждые 0,1 сек тыкаться в тарелку и отправлять сигнал маме. Мама получает сигнал, проверяет, пуста ли тарелка, если пуста - наполняет. Если не пуста - значит пришло уже несколько сигналов - лишние просто игнорируются.

Посмотрим, насколько дастся загрузить проц. моим тупым кодом ;D


Название: Re: Некорректное выполнение
Отправлено: gil9red от Ноябрь 28, 2014, 11:23
Неужели каждый новый класс это обязательно 2 дополнительных файла? В каждом по неск. строчек кода. В один файл скинуть никак?

Много классов можно тупо в один файл сохранять, но это может аукнуться при компиляции, например, медленной скоростью сборки. Да и просто не рекомендуется так делать в с++.


Название: Re: Некорректное выполнение
Отправлено: Alexu007 от Ноябрь 28, 2014, 12:59
Спасиб. Да это и не нужно наверное. В конструктор можно параметр передавать, я пробую, но пока что-то не получается. А... всё получилось, уесс!!!

Можно приступать.


Название: Re: Некорректное выполнение
Отправлено: Alexu007 от Ноябрь 29, 2014, 02:35
Код
C++ (Qt)
#include "widget.h"
#include "ui_widget.h"
 
 
int tarelka;
 
 
Widget::Widget(QWidget *parent) :
   QWidget(parent),
   ui(new Ui::Widget)
{
   ui->setupUi(this);
 
   d_01 = new detki(100);
   d_02 = new detki(110);
   d_03 = new detki(120);
   d_04 = new detki(130);
   d_05 = new detki(140);
   d_06 = new detki(150);
   d_07 = new detki(160);
   d_08 = new detki(170);
   d_09 = new detki(180);
   d_10 = new detki(190);
   d_11 = new detki(200);
   d_12 = new detki(210);
   d_13 = new detki(220);
   d_14 = new detki(230);
   d_15 = new detki(240);
   d_16 = new detki(250);
   d_17 = new detki(260);
   d_18 = new detki(270);
   d_19 = new detki(280);
   d_20 = new detki(290);
 
 
   QObject::connect(ui->phButton_01, SIGNAL(clicked()), this, SLOT(MyEventStart()));
 
   QObject::connect(d_01, SIGNAL(TarelkaInfo()), this, SLOT(TarelkaView()));
   QObject::connect(d_02, SIGNAL(TarelkaInfo()), this, SLOT(TarelkaView()));
   QObject::connect(d_03, SIGNAL(TarelkaInfo()), this, SLOT(TarelkaView()));
   QObject::connect(d_04, SIGNAL(TarelkaInfo()), this, SLOT(TarelkaView()));
   QObject::connect(d_05, SIGNAL(TarelkaInfo()), this, SLOT(TarelkaView()));
   QObject::connect(d_06, SIGNAL(TarelkaInfo()), this, SLOT(TarelkaView()));
   QObject::connect(d_07, SIGNAL(TarelkaInfo()), this, SLOT(TarelkaView()));
   QObject::connect(d_08, SIGNAL(TarelkaInfo()), this, SLOT(TarelkaView()));
   QObject::connect(d_09, SIGNAL(TarelkaInfo()), this, SLOT(TarelkaView()));
   QObject::connect(d_10, SIGNAL(TarelkaInfo()), this, SLOT(TarelkaView()));
   QObject::connect(d_11, SIGNAL(TarelkaInfo()), this, SLOT(TarelkaView()));
   QObject::connect(d_12, SIGNAL(TarelkaInfo()), this, SLOT(TarelkaView()));
   QObject::connect(d_13, SIGNAL(TarelkaInfo()), this, SLOT(TarelkaView()));
   QObject::connect(d_14, SIGNAL(TarelkaInfo()), this, SLOT(TarelkaView()));
   QObject::connect(d_15, SIGNAL(TarelkaInfo()), this, SLOT(TarelkaView()));
   QObject::connect(d_16, SIGNAL(TarelkaInfo()), this, SLOT(TarelkaView()));
   QObject::connect(d_17, SIGNAL(TarelkaInfo()), this, SLOT(TarelkaView()));
   QObject::connect(d_18, SIGNAL(TarelkaInfo()), this, SLOT(TarelkaView()));
   QObject::connect(d_19, SIGNAL(TarelkaInfo()), this, SLOT(TarelkaView()));
   QObject::connect(d_20, SIGNAL(TarelkaInfo()), this, SLOT(TarelkaView()));
 
 
   QObject::connect(d_01, SIGNAL(MamaHelp()), this, SLOT(MamaWork()));
   QObject::connect(d_02, SIGNAL(MamaHelp()), this, SLOT(MamaWork()));
   QObject::connect(d_03, SIGNAL(MamaHelp()), this, SLOT(MamaWork()));
   QObject::connect(d_04, SIGNAL(MamaHelp()), this, SLOT(MamaWork()));
   QObject::connect(d_05, SIGNAL(MamaHelp()), this, SLOT(MamaWork()));
   QObject::connect(d_06, SIGNAL(MamaHelp()), this, SLOT(MamaWork()));
   QObject::connect(d_07, SIGNAL(MamaHelp()), this, SLOT(MamaWork()));
   QObject::connect(d_08, SIGNAL(MamaHelp()), this, SLOT(MamaWork()));
   QObject::connect(d_09, SIGNAL(MamaHelp()), this, SLOT(MamaWork()));
   QObject::connect(d_10, SIGNAL(MamaHelp()), this, SLOT(MamaWork()));
   QObject::connect(d_11, SIGNAL(MamaHelp()), this, SLOT(MamaWork()));
   QObject::connect(d_12, SIGNAL(MamaHelp()), this, SLOT(MamaWork()));
   QObject::connect(d_13, SIGNAL(MamaHelp()), this, SLOT(MamaWork()));
   QObject::connect(d_14, SIGNAL(MamaHelp()), this, SLOT(MamaWork()));
   QObject::connect(d_15, SIGNAL(MamaHelp()), this, SLOT(MamaWork()));
   QObject::connect(d_16, SIGNAL(MamaHelp()), this, SLOT(MamaWork()));
   QObject::connect(d_17, SIGNAL(MamaHelp()), this, SLOT(MamaWork()));
   QObject::connect(d_18, SIGNAL(MamaHelp()), this, SLOT(MamaWork()));
   QObject::connect(d_19, SIGNAL(MamaHelp()), this, SLOT(MamaWork()));
   QObject::connect(d_20, SIGNAL(MamaHelp()), this, SLOT(MamaWork()));
 
   QObject::connect(d_01, SIGNAL(DetiInfo(QString)), ui->label_01, SLOT(setText(QString)));
   QObject::connect(d_02, SIGNAL(DetiInfo(QString)), ui->label_02, SLOT(setText(QString)));
   QObject::connect(d_03, SIGNAL(DetiInfo(QString)), ui->label_03, SLOT(setText(QString)));
   QObject::connect(d_04, SIGNAL(DetiInfo(QString)), ui->label_04, SLOT(setText(QString)));
   QObject::connect(d_05, SIGNAL(DetiInfo(QString)), ui->label_05, SLOT(setText(QString)));
   QObject::connect(d_06, SIGNAL(DetiInfo(QString)), ui->label_06, SLOT(setText(QString)));
   QObject::connect(d_07, SIGNAL(DetiInfo(QString)), ui->label_07, SLOT(setText(QString)));
   QObject::connect(d_08, SIGNAL(DetiInfo(QString)), ui->label_08, SLOT(setText(QString)));
   QObject::connect(d_09, SIGNAL(DetiInfo(QString)), ui->label_09, SLOT(setText(QString)));
   QObject::connect(d_10, SIGNAL(DetiInfo(QString)), ui->label_10, SLOT(setText(QString)));
   QObject::connect(d_11, SIGNAL(DetiInfo(QString)), ui->label_11, SLOT(setText(QString)));
   QObject::connect(d_12, SIGNAL(DetiInfo(QString)), ui->label_12, SLOT(setText(QString)));
   QObject::connect(d_13, SIGNAL(DetiInfo(QString)), ui->label_13, SLOT(setText(QString)));
   QObject::connect(d_14, SIGNAL(DetiInfo(QString)), ui->label_14, SLOT(setText(QString)));
   QObject::connect(d_15, SIGNAL(DetiInfo(QString)), ui->label_15, SLOT(setText(QString)));
   QObject::connect(d_16, SIGNAL(DetiInfo(QString)), ui->label_16, SLOT(setText(QString)));
   QObject::connect(d_17, SIGNAL(DetiInfo(QString)), ui->label_17, SLOT(setText(QString)));
   QObject::connect(d_18, SIGNAL(DetiInfo(QString)), ui->label_18, SLOT(setText(QString)));
   QObject::connect(d_19, SIGNAL(DetiInfo(QString)), ui->label_19, SLOT(setText(QString)));
   QObject::connect(d_20, SIGNAL(DetiInfo(QString)), ui->label_20, SLOT(setText(QString)));
}
 
 
 
 
 
 
Widget::~Widget()
{
   delete d_01, d_02, d_03, d_04, d_05;
   delete d_06, d_07, d_08, d_09, d_10;
   delete d_11, d_12, d_13, d_14, d_15;
   delete d_16, d_17, d_18, d_19, d_20;
 
   delete ui;
}
 
 
 
 
 
 
 
// кнопка Start
void Widget::MyEventStart()
{
   tarelka = 100;
 
   d_01->start();
   d_02->start();
   d_03->start();
   d_04->start();
   d_05->start();
   d_06->start();
   d_07->start();
   d_08->start();
   d_09->start();
   d_10->start();
   d_11->start();
   d_12->start();
   d_13->start();
   d_14->start();
   d_15->start();
   d_16->start();
   d_17->start();
   d_18->start();
   d_19->start();
   d_20->start();
 
}
 
 
 
 
 
void Widget::TarelkaView()
{
 
  ui->label_mama->setText(QString::number(tarelka));
 
}
 
 
 
 
 
void Widget::MamaWork()
{
   static int cx = 0;
 
   if(tarelka == 0) tarelka = 100;
 
   ui->label_22->setText(QString::number(++cx));
}
 
 

Код
C++ (Qt)
void detki::run()
{
   this->setPriority(QThread::IdlePriority); // приоритет потока
 
 
   while(1)
   {
 
       for (int i = 0; i < 20; i++)
       {
           emit DetiInfo(QString::number(i));
           this->msleep(appetit);
       }
 
       emit TarelkaInfo();
 
       if(tarelka > 0) tarelka--;
       else emit MamaHelp();
 
   }
 
   exec();
}




Название: Re: Некорректное выполнение
Отправлено: Satansoft от Ноябрь 29, 2014, 03:22
В Qt, если класс не порождать ни от какого из классов Qt, а сделать его "чистым", то компилятор, естественно, не понимает объявления сигналов-слотов, как это исправить?


Название: Re: Некорректное выполнение
Отправлено: gil9red от Ноябрь 29, 2014, 04:09
В Qt, если класс не порождать ни от какого из классов Qt, а сделать его "чистым", то компилятор, естественно, не понимает объявления сигналов-слотов, как это исправить?

чтобы класс мог отсылать сигналы и принимать их он должен наследоваться от QObject


Название: Re: Некорректное выполнение
Отправлено: Igors от Ноябрь 29, 2014, 10:46
Некошерно, но мне плевать.
Будете продолжать в том же духе - перестану отвечать

Код
C++ (Qt)
   QObject::connect(d_01, SIGNAL(MamaHelp()), this, SLOT(MamaWork()));
   QObject::connect(d_02, SIGNAL(MamaHelp()), this, SLOT(MamaWork()));
   QObject::connect(d_03, SIGNAL(MamaHelp()), this, SLOT(MamaWork()));
...
 
Так писать - себя не уважать.

Код
C++ (Qt)
       if(tarelka > 0) tarelka--;
       else emit MamaHelp();
}
Так вот, люмпен-пролетарий, это НЕ будет работать правильно, счетчик tarelka окажется отрицательным. Почему - разберетесь, а то расплевались тут


Название: Re: Некорректное выполнение
Отправлено: Alexu007 от Ноябрь 29, 2014, 11:55
Так писать - себя не уважать.
Ну а как? Это не я задачу придумал с двадцатью процессами... кстати, процессор они практически не грузят, что даже удивительно.

А чего разбираться? Всё работает. Как часы (что тоже сюрприз...). В минус ничего не уходит. Проверяйте.


Название: Re: Некорректное выполнение
Отправлено: Satansoft от Ноябрь 29, 2014, 13:38
Вопрос с объявлением указателя решился убиранием цикличности хедеров, вопрос краша на старте решился инициализацией указателя, черт его дери (ну сколько можно повторять про выделение памяти...), однако ошибка runtime library следующего содержания:
Цитировать
Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.
terminate called after throwing an instance of 'std::system_error'
  what():  Invalid argument
QObject::killTimers: timers cannot be stopped from another thread

намекает на проблемы интеграции С++11 и возможно, где-то надобно память выделить, но не факт...


Название: Re: Некорректное выполнение
Отправлено: Alexu007 от Ноябрь 30, 2014, 15:51
Код
C++ (Qt)
Widget::Widget(QWidget *parent) :
   QWidget(parent),
   ui(new Ui::Widget)
{
   ui->setupUi(this);
 
   d_01 = new detki(50);   dd[0] = d_01;
   d_02 = new detki(60);   dd[1] = d_02;
   d_03 = new detki(70);   dd[2] = d_03;
   d_04 = new detki(80);   dd[3] = d_04;
   d_05 = new detki(90);   dd[4] = d_05;
   d_06 = new detki(100);  dd[5] = d_06;
   d_07 = new detki(110);  dd[6] = d_07;
   d_08 = new detki(120);  dd[7] = d_08;
   d_09 = new detki(130);  dd[8] = d_09;
   d_10 = new detki(140);  dd[9] = d_10;
   d_11 = new detki(150); dd[10] = d_11;
   d_12 = new detki(160); dd[11] = d_12;
   d_13 = new detki(170); dd[12] = d_13;
   d_14 = new detki(180); dd[13] = d_14;
   d_15 = new detki(190); dd[14] = d_15;
   d_16 = new detki(200); dd[15] = d_16;
   d_17 = new detki(210); dd[16] = d_17;
   d_18 = new detki(220); dd[17] = d_18;
   d_19 = new detki(230); dd[18] = d_19;
   d_20 = new detki(240); dd[19] = d_20;
 
 
   QObject::connect(ui->phButton_01, SIGNAL(clicked()), this, SLOT(MyEventStart()));
 
 
   for(int i = 0; i < 20; i++)
       {
       QObject::connect(dd[i], SIGNAL(TarelkaInfo()), this, SLOT(TarelkaView()));
       QObject::connect(dd[i], SIGNAL(MamaHelp()), this, SLOT(MamaWork()));
       }
 
 
   QObject::connect(dd[0], SIGNAL(DetiInfo(QString)), ui->label_01, SLOT(setText(QString)));
   QObject::connect(dd[1], SIGNAL(DetiInfo(QString)), ui->label_02, SLOT(setText(QString)));
   QObject::connect(d_03, SIGNAL(DetiInfo(QString)), ui->label_03, SLOT(setText(QString)));
   QObject::connect(d_04, SIGNAL(DetiInfo(QString)), ui->label_04, SLOT(setText(QString)));
   QObject::connect(d_05, SIGNAL(DetiInfo(QString)), ui->label_05, SLOT(setText(QString)));
   QObject::connect(d_06, SIGNAL(DetiInfo(QString)), ui->label_06, SLOT(setText(QString)));
   QObject::connect(d_07, SIGNAL(DetiInfo(QString)), ui->label_07, SLOT(setText(QString)));
   QObject::connect(d_08, SIGNAL(DetiInfo(QString)), ui->label_08, SLOT(setText(QString)));
   QObject::connect(d_09, SIGNAL(DetiInfo(QString)), ui->label_09, SLOT(setText(QString)));
   QObject::connect(d_10, SIGNAL(DetiInfo(QString)), ui->label_10, SLOT(setText(QString)));
   QObject::connect(d_11, SIGNAL(DetiInfo(QString)), ui->label_11, SLOT(setText(QString)));
   QObject::connect(d_12, SIGNAL(DetiInfo(QString)), ui->label_12, SLOT(setText(QString)));
   QObject::connect(d_13, SIGNAL(DetiInfo(QString)), ui->label_13, SLOT(setText(QString)));
   QObject::connect(d_14, SIGNAL(DetiInfo(QString)), ui->label_14, SLOT(setText(QString)));
   QObject::connect(d_15, SIGNAL(DetiInfo(QString)), ui->label_15, SLOT(setText(QString)));
   QObject::connect(d_16, SIGNAL(DetiInfo(QString)), ui->label_16, SLOT(setText(QString)));
   QObject::connect(d_17, SIGNAL(DetiInfo(QString)), ui->label_17, SLOT(setText(QString)));
   QObject::connect(d_18, SIGNAL(DetiInfo(QString)), ui->label_18, SLOT(setText(QString)));
   QObject::connect(d_19, SIGNAL(DetiInfo(QString)), ui->label_19, SLOT(setText(QString)));
   QObject::connect(d_20, SIGNAL(DetiInfo(QString)), ui->label_20, SLOT(setText(QString)));
}

1. Как засунуть в цикл "d_01 = new detki(50);   dd[0] = d_01;"?

   "dd[j] =  new detki(j*10 + 50);" - не работает...

2. Как засунуть в цикл разные label ы?


Название: Re: Некорректное выполнение
Отправлено: Alexu007 от Декабрь 01, 2014, 10:28


Код
C++ (Qt)
Widget::Widget(QWidget *parent) :
   QWidget(parent),
   ui(new Ui::Widget)
{
   ui->setupUi(this);
 
   d_01 = new detki(50);   dd[0] = d_01;   lb[0] = ui->label_01;
   d_02 = new detki(60);   dd[1] = d_02;   lb[1] = ui->label_02;
   d_03 = new detki(70);   dd[2] = d_03;   lb[2] = ui->label_03;
   d_04 = new detki(80);   dd[3] = d_04;   lb[3] = ui->label_04;
   d_05 = new detki(90);   dd[4] = d_05;   lb[4] = ui->label_05;
   d_06 = new detki(100);  dd[5] = d_06;   lb[5] = ui->label_06;
   d_07 = new detki(110);  dd[6] = d_07;   lb[6] = ui->label_07;
   d_08 = new detki(120);  dd[7] = d_08;   lb[7] = ui->label_08;
   d_09 = new detki(130);  dd[8] = d_09;   lb[8] = ui->label_09;
   d_10 = new detki(140);  dd[9] = d_10;   lb[9] = ui->label_10;
   d_11 = new detki(150); dd[10] = d_11;  lb[10] = ui->label_11;
   d_12 = new detki(160); dd[11] = d_12;  lb[11] = ui->label_12;
   d_13 = new detki(170); dd[12] = d_13;  lb[12] = ui->label_13;
   d_14 = new detki(180); dd[13] = d_14;  lb[13] = ui->label_14;
   d_15 = new detki(190); dd[14] = d_15;  lb[14] = ui->label_15;
   d_16 = new detki(200); dd[15] = d_16;  lb[15] = ui->label_16;
   d_17 = new detki(210); dd[16] = d_17;  lb[16] = ui->label_17;
   d_18 = new detki(220); dd[17] = d_18;  lb[17] = ui->label_18;
   d_19 = new detki(230); dd[18] = d_19;  lb[18] = ui->label_19;
   d_20 = new detki(240); dd[19] = d_20;  lb[19] = ui->label_20;
 
   for(int i = 0; i < 20; i++)
   {
       QObject::connect(dd[i], SIGNAL(TarelkaInfo()), this, SLOT(TarelkaView()));
       QObject::connect(dd[i], SIGNAL(MamaHelp()), this, SLOT(MamaWork()));
       QObject::connect(dd[i], SIGNAL(DetiInfo(QString)), lb[i], SLOT(setText(QString)));
   }
 
   QObject::connect(ui->phButton_01, SIGNAL(clicked()), this, SLOT(MyEventStart()));
}

Всё решил сам. Всем спасибо.


Название: Re: Некорректное выполнение
Отправлено: Bepec от Декабрь 01, 2014, 11:31
Совет всё же пересмотреть свой подход к коду, слишком он...


Название: Re: Некорректное выполнение
Отправлено: Igors от Декабрь 01, 2014, 12:26
1. Как засунуть в цикл "d_01 = new detki(50);   dd[0] = d_01;"?

   "dd[j] =  new detki(j*10 + 50);" - не работает...

2. Как засунуть в цикл разные label ы?
Напр так (аттач)