0 / 0 / 0
Регистрация: 22.10.2012
Сообщений: 40
1

Как сделать "Старт", "Пауза", Стоп"?

26.12.2012, 11:11. Показов 15807. Ответов 71
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго времени суток,
как сделать так, чтобы при нажатии на кнопку начиналось цикличное действие (рисование например) и продолжалось бы пока не будет нажата другая кнопка. Грубо говоря, как сделать "Старт", "Пауза", Стоп".
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.12.2012, 11:11
Ответы с готовыми решениями:

C++ Threads или как запрограммировать кнопку Старт и Стоп
Погуглил нечего не нашёл на эту тему..

нужно сделать кнопки старт и пауза для движущихся фигур
пауза нормально работает. но после паузы нажимаешь на старт фигуры не продолжают движение по...

В билдеровском MediaPlayer-е кнопка стоп работает как пауза?
Ребята, кто-нибудь сталкивался с такой проблемой, в билдеровском медиаплеере кнопка стоп, работает...

Одна форма, кнопки старт и стоп. Как остановить?
Одна форма с двумя кнопками. Старт - начало некоторого длинного по времени алгоритма, который можно...

Через интерфейсе (GUI) сделать кнопку стоп, старт, пауза
Здравствуйте ,есть проблема ,преподаватель дал задание ,что бы через интерфейсе (GUI) сделать...

71
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
07.01.2013, 01:38 61
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от Avazart Посмотреть сообщение
Ситуация: один поток рисует в одном окне, а другой владеет другим окном
Цитата Сообщение от Avazart Посмотреть сообщение
А GDI -ф-ции обращаются не к разделяемому ресурсу - окну программы, сообщения от которого обрабатываются в оконной процедуре в основном потоке ?
там пьяный что ли? Меня же цитируешь где я говорю о РАЗНЫХ окнах и тут же возражаешь так, будто я говорю об одном окне.

Нет, представь себе. Я говорю о случае, когда, каждый поток владеет собственным окном, следовательно, оно- неразделяемый ресурс. И я даже знаю что ты сейчас скажешь, ты скажешь:
Цитата Сообщение от Avazart Посмотреть сообщение
А GDI -ф-ции обращаются не к разделяемому ресурсу - окну программы, сообщения от которого обрабатываются в оконной процедуре в основном потоке ?
скучно с тобой становится.

++++++++++++++++++++++++++++++++++++++++++++++++++

Цитата Сообщение от Avazart Посмотреть сообщение
Все понятно ...

это типа крест на мне...

++++++++++++++++++++++++++++++++++++++++++++++++++

Цитата Сообщение от Avazart Посмотреть сообщение
Какую консоль ты о чем ? приложение оконное изначально было ( напоминаю если ты об этом уже забыл )
Ну и что? Мало ли что там было изначально?
Я ставлю ДРУГОЙ вопрос- вернее ты его ставишь, а именно- потоки в билдер реализованы круче, нежели в pthread, а когда я предлагаю пободаться- в кусты сразу. Консоль вполне подойдёт. Нет, конечно можно попытаться меня запутать, так тот чел- отправить не знаю куда где лежит какой-то там проект, можно глубокомысленно изречь:
Цитата Сообщение от Avazart Посмотреть сообщение
Тут конечно строк по более но и задумка куда по более вашей ...
Ещё вариант: можно продолжать твердить про четыре строчки кода, как мантру.

Не хошь не надо.
Оставайся со своими четырьмя строчками кода.

Цитата Сообщение от Avazart Посмотреть сообщение
Это даже не интересно ... тут и без TThread обойтись можно ... ( CreateThread() + крит секция )
повторюсь: ну раз неинтересно, и сиди со своими четырьмя строчками кода.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
07.01.2013, 02:09 62
Цитата Сообщение от kravam Посмотреть сообщение
пободаться- в кусты сразу.
Бодаются бараны, я не таков ...

Цитата Сообщение от kravam Посмотреть сообщение
скучно с тобой становится.
Скучно писать :
Цитата Сообщение от kravam Посмотреть сообщение
Ну то есть: поток запустился, написал "Hello, word" и отработал.
Есть претензии укажи - ошибки в моем коде, либо напиши свой код как альтернативу с теми же возможностями (или более...)

Цитата Сообщение от kravam Посмотреть сообщение
Я ставлю ДРУГОЙ вопрос- вернее ты его ставишь, а именно- потоки в билдер реализованы круче, нежели в pthread, а когда я предлагаю пободаться- в кусты сразу.
Это твой вывод ... для меня это не вопрос ... для данной задачи (для данного компилятора,операционной системы) TThread лучше подходит...
Но никто не запрещает юзать что угодно и как угодно при этом - но будет много буков, как я уже сказал.

Да собственно спросите ТС какой из предложенных кодов ему больше подходит ... и на этом думаю можно тему закрывать (если нет конечно вопросов по сути)

Цитата Сообщение от kravam Посмотреть сообщение
Я ставлю ДРУГОЙ вопрос
Другая тема ...
0
0 / 0 / 0
Регистрация: 22.10.2012
Сообщений: 40
07.01.2013, 15:04  [ТС] 63
Цитата Сообщение от Avazart Посмотреть сообщение
на этом думаю можно тему закрывать
Вопросы есть, один из способов - это с помощью потока рисовать средствами Апи на канве, всё хорошо, НО тогда встает вопрос: как изменять цвет и толщину пера?

Второй реализованный мною способ - это с помощью таймера рисовать на канве средствами Vcl, здесь же слишком большое время исполнения, т.к одной прорисовки предшествует 1000 шагов расчетов (при шаге таймера 1 миллисекунда - это минимум 1 секунда).

Вы предлагали также другие способы, но реализовать их не удалось, что подскажете, что выбрать?
0
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
07.01.2013, 18:14 64
Ну вот, то, о чём я и говорил. Задержка в 1 секунду не допускается, но она есть. Вот и таймер.
Но и мой способ не подойдёт по этой же самой причине. Если его использовать, тогда управляющий поток должен передать управление рисующему потоку, который точно также будет чего-то расчитывать в течении1-ой секунды, а, поскольку он в это время будет владеть окном, та же задержка в управлении и выйдет. Только реализация ещё труднее.

Что же делать?

Нужен симбиоз решений.
Пусть у тебя рисует всё в таймере- у то есть через 100 миллисекунд к примеру. Это нормально. Но все расчёты пуст делаются в ДРУГОМ потоке.
Ну то есть как-то так:

---в потоке A нажал старт-> создался параллельный поток B (чисто для расчётов, он окно не занимает)

(Теперь по расчётам. Я так понимаю, все данные для расчётов формируются динамически, иначе их просто можно было расчитать до начала отрисовки, а потом махом всё отрисовать. То есть

произошла отрисовка- новые данные
произошла отрисовка- новые данные
произошла отрисовка- новые данные
произошла отрисовка- новые данные

Отсюда вывод: по каждому расчёту поток B должен приостанавливать свою деятельность и ждать, сигнала "произошла отрисовка", после этого генерить новые данные и посылать их потоку A).
---В потоке B делается расчёт и посылается об этом сигнал потоку A; поток B приостанавливает деятельность
---Поток A отрисовывает чё надо и посылает сигнал об этом потоку B
---В потоке B делается расчёт и посылается об этом сигнал потоку A; поток B приостанавливает деятельность
---Поток A отрисовывает чё надо и посылает сигнал об этом потоку B

И так сколько нам надо раз. Можно сделать, чтобы поток B сделал, к примеру 10 расчётов по 1-ой секунде каждый после чего самоубился. Тогда вся работа займёт примерно 1- секунд- то же самое, что и в твоём варианте с той лишь разницей, что в эти 10 секунд окно тормозить не будет .
Можно просто напросто реализовать убиение потока по нажатию кнопки стоп.

Я тебе сразу говорил с кандачка эту задачу не решить.

Не по теме:

А в билдере, как я понял, надо только подумать и синхронизацию прописывать не надо, всё само пропишется.



И напоследок ты спросишь- а где тут таймер? Как видишь, обошлись без него. Ведь для чего он нам нужен был? Чтобы циклично выполнялись какие-то действия (перерисовка). Но тут таймером может с успехом служить поток B- всякий раз по окончании расчётов он посылает сигнал об этом потоку A; так что не будем плодить лишние сущности.

Щас изобразим. Сразу говорю- кнопки пауза не будет, кроме того. Данные потоку B передаваться не будут. Передача динамически формирующихся данных- это отдельная тема. Вместо этого будет например семафор какой-нибудь (тоже вид данных своего рода),
то есть так:

поток B расчитал- сбросил флаг
поток A отрисовал- установил флаг


Считай что флаг это и есть данные
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
07.01.2013, 19:10 65
Цитата Сообщение от Shpion007 Посмотреть сообщение
Вопросы есть, один из способов - это с помощью потока рисовать средствами Апи на канве, всё хорошо, НО тогда встает вопрос: как изменять цвет и толщину пера?
Ну я уже говорил что это опасно -раз, неудобно - два,в этом нет необходимости так как решение предусмотрено VCL - три.
(о рисование можно найти в любом справочнике по WinApi ( работа GDI ) )

Собственно в коде который я предлагал для потоков можно увидеть как я выставляю толщину пера с помощью VCL

Цитата Сообщение от Shpion007 Посмотреть сообщение
Второй реализованный мною способ - это с помощью таймера рисовать на канве средствами Vcl, здесь же слишком большое время исполнения, т.к одной прорисовки предшествует 1000 шагов расчетов (при шаге таймера 1 миллисекунда - это минимум 1 секунда).
Ну говорил об этом расчетов много - таймер не подойдет, решать надо в потоке....

Более того в VCL таймер работает адекватно с интервалом ~300 мс ( меньше выставить нельзя- не сработает ).
Если это слишком надо то нужно реализовывать таймер на основе WinApi ( что собственно несложно и пример этого есть в одной из книг Архангельского, которые указывал раньше)

Цитата Сообщение от Shpion007 Посмотреть сообщение
Вы предлагали также другие способы, но реализовать их не удалось....
Что именно ? Что не удалось ?
Я же выкладывал готовый проект...

Цитата Сообщение от Shpion007 Посмотреть сообщение
что подскажете, что выбрать?
Моё мнение тоже TThread c синхронизацией ...

Да и переформулируй задание по конкретнее, а то благодаря некоторым уже и непонятно что именно нужно тебе ....



Добавлено через 3 минуты
Цитата Сообщение от kravam Посмотреть сообщение
Нужен симбиоз решений.
Это идиотизм, пЫрдонте...
Цитата Сообщение от kravam Посмотреть сообщение
Я тебе сразу говорил с кандачка эту задачу не решить.
Да да... тебе не решить...
1
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
19.01.2013, 16:38 66
Цитата Сообщение от Avazart Посмотреть сообщение
Это идиотизм, пЫрдонте...
мели, Емеля.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
#include <windows.h>
#include <pthread.h> 
#include <stdio.h> 
#include<semaphore.h>
 
//лепим своё сообщение
#define WM_OUR  WM_USER+100
#define zaderzhka  1000
 
 
#define ButtonID 1
#define ButtonID_ 2
 
 
//оконная процедура
LRESULT CALLBACK WndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
//функция потока
void *task2(void *X);
 
//ЭТО для объявления потоков всё
void* status; 
pthread_t ThreadA; // Объявляем потоки. 
bool flag= false;
 
//это семафор будет
sem_t sem;
 
 
 
char ClassName       []= "SimpleWinClass";
char AppName         []= "Our First Window";
char ButtonClassName []= "button";
char ButtonText      []= "Пуск";
char ButtonText_     []= "Стоп";
char* OurText          = (char*)"Win32 assembly is great and easy!";
 
HINSTANCE hInstance;
LPSTR CommandLine;
HWND hwndButton;
HWND hwndEdit;
char buffer [512];
 
//Длина OurText
int dlina_OurText;                                      //+
                                      //+
                                      //+
                                      //+
                                      //+
                                      //+
//Главная функция, создаёт окно
int WINAPI WinMain (HINSTANCE hInst,
                    HINSTANCE hPrevInst,
                    LPSTR CmdLine,
                    int CmdShow)
 
{
 SetConsoleCP(1251);
 SetConsoleOutputCP(1251);
 
 dlina_OurText= strlen (OurText);
 
 
 
 hInstance= hInst;
 CommandLine= CmdLine;
 //структуры
 WNDCLASSEX wc;
 MSG msg;
 HWND hwnd;
 
 //инициализация;
 wc.cbSize= sizeof (WNDCLASSEX);
 wc.style= CS_HREDRAW | CS_VREDRAW;
 wc.lpfnWndProc= WndProc;
 wc.cbClsExtra= 0;
 wc.cbWndExtra= 0;
 wc.hInstance= hInst;
 wc.hbrBackground= (HBRUSH)(COLOR_BTNFACE+1);
 wc.lpszMenuName= NULL;
 wc.lpszClassName= ClassName;
 wc.hIcon= LoadIcon (NULL,IDI_APPLICATION);
 wc.hIconSm= wc.hIcon;
 wc.hCursor= LoadCursor (NULL,IDC_ARROW);
 
 
 RegisterClassEx (&wc);
 
 hwnd= CreateWindowEx (WS_EX_CLIENTEDGE, ClassName,AppName,\
           WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
           CW_USEDEFAULT,500, 500,NULL,NULL,\
           hInst,NULL);
 
 ShowWindow (hwnd,SW_SHOWNORMAL);
 UpdateWindow (hwnd);
 
 
 
 while (true) {
   if (!GetMessage (&msg,NULL,0,0))
     break;
    TranslateMessage (&msg);
    DispatchMessage  (&msg);
 }
 return msg.wParam;
}
                                      //+
                                      //+
                                      //+
                                      //+
                                      //+
                                      //+
 
//+++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++
//Оконная процедура                              
LRESULT CALLBACK WndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
   static int i= 0;
   HDC hdc;
   PAINTSTRUCT ps;
   RECT rect;
  if (uMsg==WM_DESTROY) 
      PostQuitMessage (0);
  else if (uMsg==WM_CREATE) {
      //И две кнопки
      hwndButton= CreateWindowEx (0, ButtonClassName,ButtonText,\
      WS_CHILD + WS_VISIBLE + BS_DEFPUSHBUTTON,\
      75,70,140,25,hWnd,(HMENU)ButtonID,hInstance,NULL);
 
 
      hwndButton= CreateWindowEx (0, ButtonClassName,ButtonText_,\
      WS_CHILD + WS_VISIBLE + BS_DEFPUSHBUTTON,\
      75,100,140,25,hWnd,(HMENU)ButtonID_,hInstance,NULL);
  }
  else if (uMsg==WM_PAINT) {
      hdc= BeginPaint (hWnd, &ps);
      GetClientRect (hWnd, &rect);
      DrawText (hdc, OurText ,-1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
      EndPaint (hWnd, &ps);
      //Отрисовали? Теперь устанавливаем семафор в единицу,
      //типа послали новые данные для вычисляемого потока
      sem_post(&sem);
  }
  else if (uMsg==WM_COMMAND) {
      WPARAM eax= wParam%0xffff;
      if (lParam) {
            if (eax==ButtonID) {
                eax= wParam/0Xffff;
                if (eax==BN_CLICKED) {
                   //Если нажимаем на вехнюю кнопку, то               
                   //создаём отдельный поток                          
                   //Создаём один раз, для этого используем флаг flag 
                   //когда поток аннулируется можно снова создат будет
                   if (!flag) {
                    
                    //Семафор инициализируем НУЛЁМ, всё, как положено:
                    sem_init(&sem, 0, 0);
                    
                    pthread_create(&ThreadA,NULL,task2, (void*)hWnd); 
                    flag= true;
                   }
                }
            }
            else if (eax==ButtonID_) {
                eax= wParam/0Xffff;
                if (eax==BN_CLICKED) {
                  //Убиваем на хрен поток, который пишет всякую херь
                  //но только если он создан                        
                  if (flag)
                  pthread_cancel(ThreadA); 
                }
            }
      }
  }
  else 
      return DefWindowProc (hWnd,uMsg,wParam,lParam );      
  return 0;
}
 
 
 
 
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Функция- дестуктор потока, выполняется при его анулировании
void routine  (void* x) {
 printf ("всё, я спёкся");
 flag= false;
}
 
 
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                   //Функция потока
void *task2(void *X) { 
 
 int x;
 void* arg= &x;
 pthread_cleanup_push (&routine, arg); 
 int OldState,OldType; 
// // Разрешено аннулирование асинхронного типа. 
 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &OldState); 
 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS,&OldType); 
 
 //Вот твой вечный цикл                         
 //ОН работает пока другой поток (родительский) 
 //не убьёт этот поток (дочерний)               
 //иначе будет рабтать вечно                    
 //Тут типа вычисления                          
 while (true) {
  printf ("Я, поток-тормоз, делаю расчёты %d секунд, но окна не занимаю!", zaderzhka/1000);
  printf ("шевели окно как тебе угодно\n");
  Sleep (zaderzhka);
 
  
  //Првоначально я не думал разбиратться здесь со строкой OurText,
  //а думал это делать всякий раз при обработке OurText,          
  //но передумал                                                  
  //Грамотно это будет зделать здесь                              
  //Это и будет перерасчётом данных                               
  OurText++;
  if (!(*OurText))
   OurText-= dlina_OurText;
  
  //Так, а тут поток заканчивает свои расчёты и посылает об этом сигнал окну
  //просто задействуем функцию                                              
  InvalidateRect ((HWND)X, NULL, true);
  
  //ждём на семафоре, когда он станет равным 1 
  sem_wait(&sem);
 
 }
 
 
 pthread_cleanup_pop (false); 
 
 return NULL; 
}
компилить с опциями:
-lpthread -lgdi32
0
0 / 0 / 0
Регистрация: 04.03.2014
Сообщений: 25
27.11.2016, 21:37 67
Но если не использовать сторонних библиотек, то как можно реализовать старт, паузу и выход из консольной программы?
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
27.11.2016, 22:07 68
mary_19, Вы о чем? О каких сторонних библиотеках речь?
0
0 / 0 / 0
Регистрация: 04.03.2014
Сообщений: 25
28.11.2016, 23:34 69
Ну есть же чисто С++ - ные библиотеки как заголовочный файл iostream включён в стандартную библиотеку C++. А вот Boost это как не стандартная библиотека.

Вопрос не по теме, кто-то может знает, что такое log state-переходов и как это оформить в формате .txt
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
28.11.2016, 23:36 70
Вы про потоки? Есть std::thread в > С++11
0
0 / 0 / 0
Регистрация: 04.03.2014
Сообщений: 25
29.11.2016, 00:01 71
Я с многопоточностью ещё не знакомилась, не могу сказать)
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
29.11.2016, 00:07 72
Цитата Сообщение от mary_19 Посмотреть сообщение
Я с многопоточностью ещё не знакомилась, не могу сказать)
А читать умеете вообще? - Читайте тему с начала...
А затем задайте себе вопрос "о чем это я?"
0
29.11.2016, 00:07
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
29.11.2016, 00:07
Помогаю со студенческими работами здесь

Нужно вместо кнопки старт/ стоп сделать смену цвета круга
Помогите, пожалуйста, исправить прогу, нужно вместо кнопки старт/ стоп сделать смену цвета круга....

Как добавить кнопку Старт/Стоп
скажем ввели 1 минут и нажали старт ) отсчет пошел и потом нажали Стоп и таймер остановил на 35...

TextureView video-старт/пауза как?
Добрый день! помогите разобраться: public class MainActivity extends AppCompatActivity...

Функция старт/стоп
Как сделать кнопки старт/стоп на этот код? Помогите пожалуйста, сам попробовал - не получилось var...

Процесс старт\стоп
Всем Доброго времени суток. Делаю небольшой таймер для приложений. То есть приложение, которое...

Таймаут, старт, стоп
Здравствуйте. Есть 2 вопроса: 1).В программе необходимо сделать задержку 4 секунды, причём так,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
72
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru