Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.72/25: Рейтинг темы: голосов - 25, средняя оценка - 4.72
5 / 5 / 2
Регистрация: 29.08.2012
Сообщений: 46

Мышь в виде перекрестия на весь PaintBox (Image)

27.01.2016, 16:12. Показов 6317. Ответов 58
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте! Использую PaintBox, но можно поговорить и об Image, т.к. почти одно и тоже)
Задача в следующем:

На своём PaintBox (далее PB) сверху (примерно 80% его высоты) у меня отведено под некий график, а в нижней части PB (20%) я вывожу другой график, который идейно связан с верхним. Т.е. каждая точка на нижнем графике "рассказывает" пользователю о состоянии соответствующей точки верхнего графика. Но зрительно проводить вертикаль между далеко отстоящими друг от друга графиками не всем пользователям позволит косоглазие ))) Поэтому возникла идея превратить мышь в вертикаль на всю картинку, которая будет точно показывать, какая точка нижнего графика соответствует какой точке верхнего. Ну, а горизонталь за компанию: значение оси Y показывать будет... хотя особой необходимости в ней нет... так что если от этого зависит решение, то горизонталью я готов пожертвовать )))

Можно использовать OnMouseMove и рисовать линии на PB. Но если перерисовывать всю картинку при каждом движении мышки на 1 пиксель - то PB нереально дёргается (как мониторы компьютеров, которые показывают по телевизору, только быстро), программа иногда вылетает, да и вообще, выглядит это не эстетично и ужасно...

Возникла идея создавать новый огромный курсор мыши в виде креста (ведь он не связан графически с PB и своим перемещением зарисовывать изображение на нём не будет). А поскольку расстояния от перекрестия до границ PB всегда будут разными, то создавать этот курсор надо каждый раз новый в OnMouseMove, а не просто загрузить курсор из файла размером в три монитора ))). Может, кто-то знает, как это сделать? Или у кого-то будет оригинальное гениальное решение? Смысл в том, чтоб рисовать крест не на PB и не удалять его, восстанавливая изображение под ним, после того, как мышь ушла в другое место. Заранее, спасибо.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
27.01.2016, 16:12
Ответы с готовыми решениями:

Скопировать картинку с PaintBox в Image
Помогите, пожалуйста. Нужно скопировать картинку с PaintBox в Image. C помощью CopyRect не получается.

Графические компоненты Image, Shape, Chart, PaintBox
Написать программу: Организовать выбор способа задания параллелограмма из списка: - по двум сторонам и углу между ними, - по двум...

Image во весь экран
Подскажите, как прописать чтобы изображение было на весь экран? то есть вообще форма скрывается и картина по всему экрану.

58
Практикантроп
 Аватар для nick42
4841 / 2726 / 534
Регистрация: 23.09.2011
Сообщений: 5,798
29.01.2016, 16:47
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Avazart Посмотреть сообщение
Вечный цикл?
Я хотел сказать, что постоянно перезапускается. Некоторые начинающие думают, что его достаточно раз запустить - и всё, обработчик таймера один раз отработает и успокоится до следующего запуска. А это не так.
0
5 / 5 / 2
Регистрация: 29.08.2012
Сообщений: 46
29.01.2016, 16:51  [ТС]
Цитата Сообщение от nick42 Посмотреть сообщение
А таймер сам собой не остановится
А зачем мне его останавливать? Он же типа поток заменять должен.. Он каждую секунду обращается к памяти и смотрит, пришли ли новые данные. Если пришли, то рисовать. Если нет, то проверим через секунду. А если он успел нарисовать картинку за 0,01 сек, то оставшееся время (0,99 сек) зависаний нет. Всё отлично.
Цитата Сообщение от Avazart Посмотреть сообщение
Вечный цикл?
C++ (Qt)
1
2
3
while (true)
{...
}
И брэйка нет. Т.е. выход из цикла по событию OnReset или OnAsteroidomPoSystemniku ))))
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
29.01.2016, 17:14
Ну так убрать цикл, убрать Sleep и в таймер.
0
5 / 5 / 2
Регистрация: 29.08.2012
Сообщений: 46
29.01.2016, 17:28  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
Ну так убрать цикл, убрать Sleep и в таймер.
Т.е. в цикле виснет, а при рисовании виснуть не будет? ))) Чем же
C
1
2
3
4
while (true)
{i++;
 Edit1 -> Text = i;
}
отличается от
C
1
2
3
4
for (i = 1; i < PaintBox1 -> Width; i++)
{PaintBox1 -> MoveTo(i - 1, Y);
 PaintBox1 -> LineTo(i, Y);
}
кроме количества итераций, определяемого PaintBox1 -> Width из-за которого время подвисания второго варианта меньше первого?

PS: ну, кэнвас, и всё такое... пропустил...
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
29.01.2016, 17:46
C++
1
2
3
4
5
6
7
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
 static int i=0;
 Edit1->Text= i++;
}
//---------------------------------------------------------------------------
Виснет?
0
5 / 5 / 2
Регистрация: 29.08.2012
Сообщений: 46
29.01.2016, 17:57  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
Виснет?
Здрасьте! ))) Сравнили операцию в одно действие с невдолбенным массивом задач! ))) Я что, картинку по одному пикселю в итерацию таймера рисовать буду? )))) Смысл же ж в том, чтоб нагрузить один запуск таймера, а не одну операцию выполнить.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
29.01.2016, 18:00
Цитата Сообщение от Kvarcenar Посмотреть сообщение
мысл же ж в том, чтоб нагрузить один запуск таймера,
По минимуму.

Добавлено через 52 секунды
Цитата Сообщение от Kvarcenar Посмотреть сообщение
а не одну операцию выполнить.
Операцию "Ы" ?
Откуда мне знать что у вас там за операции.

Вы вообще вникаете что вам пишут? Код пробовали?
0
5 / 5 / 2
Регистрация: 29.08.2012
Сообщений: 46
29.01.2016, 18:21  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
По минимуму.
Наоборот. По максимуму. Чтоб проверить, будет виснуть или нет. Что ж это за проверка, если по минимуму?
Цитата Сообщение от Avazart Посмотреть сообщение
Операцию "Ы" ?
Ы++. Да. )))
Цитата Сообщение от Avazart Посмотреть сообщение
Откуда мне знать что у вас там за операции.
Всё время ж об этом говорим. Картинка рисуется. Сложная, загруженная графиками. Долго.
Цитата Сообщение от Avazart Посмотреть сообщение
Вы вообще вникаете что вам пишут?
А есть основания полагать, что нет? Разумеется, вникаю.
Цитата Сообщение от Avazart Посмотреть сообщение
Код пробовали?
Ну, я и так понял, что этот код делает. Но только что, специально ради Вас, проверил ))) Меняет эдит раз в секунду. Тут даже советский калькулятор никогда не зависнет. ))) В чём тест состоял? Вы напишите так:
C++ (Qt)
1
2
3
4
5
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{int i;
 for (i = 0; i < 2000000; i++)
 Edit1 -> Text = i;
}
Это будет больше похоже на рисование картинки )))) ктрл+ф2 в помощь! )))
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
29.01.2016, 18:56
Цитата Сообщение от Kvarcenar Посмотреть сообщение
Чтоб проверить, будет виснуть или нет.
Конечно будет, если у того кто пишет код руки из .... и он не понимает что нельзя в пихать в одну кучу а дать возможность обработать системные сообщения.

Добавлено через 1 минуту
Цитата Сообщение от Kvarcenar Посмотреть сообщение
В чём тест состоял? Вы напишите так:
Тест состоял в то что бы кого-то отучить так писать....
0
5 / 5 / 2
Регистрация: 29.08.2012
Сообщений: 46
29.01.2016, 19:41  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
Тест состоял в то что бы кого-то отучить так писать....
Ну, так отучайте, если взялись. Каким путём идти, чтоб не было зависаний и вылетов? Конкретно, а не
Цитата Сообщение от Avazart Посмотреть сообщение
у того кто пишет код руки из ....
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
29.01.2016, 19:43
Ну та я не вижу конкретного кода...
0
5 / 5 / 2
Регистрация: 29.08.2012
Сообщений: 46
30.01.2016, 16:43  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
Ну та я не вижу конкретного кода...
А что Вам конкретно нужно? Ну, сделайте цикл по оси ОХ по ширине картинки и вложенный в него цикл по оси ОY по высоте картинки и рисуйте по ПэинтБоксу линии длиной в 1 пиксель рандомного цвета, заполняя всё поле ПэинтБокса рандомным узором... Какая разница, что я рисую: "десятую производную от синуса от логарифма от гиперболического ареотангенса в степени арккосинус двадцать пятой степени икс" или разукрашиваю слонёнка, контур которого задан точками? ))) Смысл в том, что есть какая-то сложная функция рисования на ПэинтБоксе. И надо сделать так, чтоб пока она рисуется, пользователь не втыкал в зависший комп, а что-то делал в программе... И пусть самое оптимальное время её рисования на 147-миядерном процессоре - 0,5 секунды. По-моему, условие задачи вполне достаточно задано... Если нет - то спросите, что Вам уточнить... Поток с этой задачей справляется, но иногда вылетает. А таймер вешает комп на полсекунды каждый раз. Из двух зол выбираю пока что поток.. Как-то так... Если знаете, что предложить - предлагайте, с меня всегда будет "спасибо" )))

Добавлено через 20 часов 31 минуту
Цитата Сообщение от nick42 Посмотреть сообщение
Я использовал два шейпа ( TShape )
А как сделать так, чтоб эти шейпы не исчезали во время движения по картинке? Ну, когда мышка остановилась - то они беленькие и видны. А если начинаешь вести вертикально - то горизонтальный шейп моргает и исчезает пока ведёшь, а если вести горизонтально - то вертикалтный. А если под произвольным углом - то оба моргают и исчезают пока мышка не остановится. Оно, вроде как кажется, что они чёрными становятся и сливаются с чёрным фоном... но сделал их красными, а фон белым - всё равно исчезают и вроде как белыми становятся на время движения мышки.. Есть решение или терпеть?
0
Практикантроп
 Аватар для nick42
4841 / 2726 / 534
Регистрация: 23.09.2011
Сообщений: 5,798
30.01.2016, 16:59
Цитата Сообщение от Kvarcenar Посмотреть сообщение
Есть решение или терпеть?
Видимо - терпеть. Я с PaintBrush практически не работаю, разве что эпизодически. Рисовать всё в OnPaint для меня mauvais ton. PaintBrush - это как бы графика с открытым нервом, - всё сверху. Когда я эти Shapes использовал на канве графиков (Chart), мне даже двойная буферизация не понадобилась; всё работало прилично и без мерцаний. Что у вас там с потоками, и как вы эти шейпы организовали - мне не известно. Поэтому от советов я воздержусь.
0
5 / 5 / 2
Регистрация: 29.08.2012
Сообщений: 46
30.01.2016, 17:45  [ТС]
Цитата Сообщение от nick42 Посмотреть сообщение
Что у вас там с потоками
В данном случае поток нарисовал и ушёл. Отдыхает. Бегает у себя там в цикле и ждёт новых данных. В PaintBox даже не заглядывает. Картинку вообще никто не трогает, просто мышка лазит по ней - и всё.
Цитата Сообщение от nick42 Посмотреть сообщение
как вы эти шейпы организовали - мне не известно
так а чё там сложного-то...
C++ (Qt)
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
//---------------------------------------------------------------------------
void __fastcall TForm1::Shape1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
{PaintBox1MouseMove(NULL, Shift, Shape1 -> Left, Y);}
//---------------------------------------------------------------------------
void __fastcall TForm1::Shape2MouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
{PaintBox1MouseMove(NULL, Shift, X, Shape2 -> Top);}
//---------------------------------------------------------------------------
void __fastcall TForm1::PaintBox1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
{...
 // куча кода не имеющего отношения к теме
 ...
 Shape1 -> Visible = true;
 Shape1 -> Width = 1;
 Shape1 -> Height = PaintBox1 -> Height;
 Shape1 -> Top = 0;
 Shape1 -> Left = X;
 Shape2 -> Visible = true;
 Shape2 -> Height = 1;
 Shape2 -> Width = PaintBox1 -> Width;
 Shape2 -> Left = 0;
 Shape2 -> Top = Y;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
{Shape1 -> Visible = false;
 Shape2 -> Visible = false;}
//---------------------------------------------------------------------------
Как-то так...
0
Практикантроп
 Аватар для nick42
4841 / 2726 / 534
Регистрация: 23.09.2011
Сообщений: 5,798
31.01.2016, 01:31
Цитата Сообщение от Kvarcenar Посмотреть сообщение
Как-то так..
Предположим, действительно так, как написали... . Возможно, оговаривая толщину шейпов при каждом движении мышки, вы вызываете некие лишние функции..., но это ведь не нужно. В моей программе их цвет и размеры задавались сразу, а на перемещение мышки менялась только их "видимость" (Visible) и расположение. Хотя я думаю - корень зла не в этом. Изменение размещения или размеров любого компонента окна вызовет его перерисовку (OnPaint); у вас при мышиных маневрах сразу два контрола меняют позиции, да еще в этом же обработчике некие действия по отображению пэйнтбокса. Ужас, одним словом.
0
5 / 5 / 2
Регистрация: 29.08.2012
Сообщений: 46
31.01.2016, 01:48  [ТС]
Цитата Сообщение от nick42 Посмотреть сообщение
В моей программе их цвет и размеры задавались сразу, а на перемещение мышки менялась только их "видимость" (Visible) и расположение.
Оставил в маусмуве только
C++ (Qt)
1
2
3
4
5
6
 Shape1 -> Visible = true;
 Shape1 -> Left = X;
 Shape2 -> Visible = true;
 Shape2 -> Width = PaintBox1 -> Width - i;
 Shape2 -> Left = i;
 Shape2 -> Top = Y;
i - обычно = 0, но если дополнительное окно открывается - шэйп его огибать должен. В общем, не обращайте внимания. И это... без изменений... моргает. как и моргало..
Цитата Сообщение от nick42 Посмотреть сообщение
да еще в этом же обработчике некие действия по отображению пэйнтбокса. Ужас, одним словом.
Ну, так это ж Avazart посоветовал все рисования в ОнПэинт скинуть. И теперь, благодаря этому, рисунок не исчезает при перекрытии другими окнами.. А где ужас-то? )))
0
Практикантроп
 Аватар для nick42
4841 / 2726 / 534
Регистрация: 23.09.2011
Сообщений: 5,798
31.01.2016, 01:59
Ужас в результате, разумеется. Хоть я обещал больше не советовать..., попробуйте вставить где-нибудь для шейпа ->BringToFront() - вдруг поможет.
0
5 / 5 / 2
Регистрация: 29.08.2012
Сообщений: 46
31.01.2016, 02:07  [ТС]
Цитата Сообщение от nick42 Посмотреть сообщение
попробуйте вставить где-нибудь для шейпа ->BringToFront() - вдруг поможет
не.. не помогло.. эх, ладно.. ну его в баню.. ))))
0
5 / 5 / 2
Регистрация: 29.08.2012
Сообщений: 46
31.01.2016, 12:32  [ТС]
Цитата Сообщение от nick42 Посмотреть сообщение
Предположим, действительно так, как написали...
В общем, таки разобрался, но не исправил... Если в функции ОнПэинт рисовать что-то "быстрое", ну, например, фон залить и пару линий кинуть - то не моргают шэйпы. Но если там будет цикл по пикселям по ширине с рисованием трудоёмкой функции - то время рисования картинки становится сравнимым со временем перемещения мыши от пикселя к пикселю. Поэтому оно на микросекунды подвисает и мы это видим как моргание шэйпов. попытался отменить выполнение ОнПэинт при МаусМуве - так шэйпы начали замазывать картинку, как было до переноса рисования в ОнПэинт... Т.е. картинка действительно перерисовывается дважды: 1 - при рисовании из ОнПэинта (и это рисование затирается накладываемыми объектами), и 2 - при автоматическом перерисовывании из-за события ОнПэинт, которое делает что-то хитрое, чтоб рисунок не затирался.. Как отменить первое и сохранить второе - ещё не разобрался... Но ОнПэинт действительно почему-то вызывается при МаусМуве... Написал простую программу для этого дела (на картинке палочка - это шэйп, а цифра - это лэйбл, в котором мышиная координата Х выводится) (можете себе скопипастить и проверить, только цвета шейпа и лэйбла белыми настройте):
C++ (Qt)
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
//---------------------------------------------------------------------------
void __fastcall TForm1::FormActivate(TObject *Sender)
{PaintBox1Paint(NULL);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::PaintBox1MouseMove(TObject *Sender,
      TShiftState Shift, int X, int Y)
{Shape1 -> Left = X;
 Shape1 -> Top = Y;
 Label1 -> Left = X;
 Label1 -> Top = Y;
 Label1 -> Caption = X;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::PaintBox1Paint(TObject *Sender)
{int i, j;
 PaintBox1 -> Canvas -> Brush -> Color = clBlack;
 PaintBox1 -> Canvas -> Pen -> Color = clBlack;
 PaintBox1 -> Canvas -> Rectangle(-1, -1, PaintBox1 -> Width + 1, PaintBox1 -> Height + 1);
 PaintBox1 -> Canvas -> Pen -> Color = clWhite;
 j = 100000;
 for(i = 0; i < j; i++)
 {PaintBox1 -> Canvas -> MoveTo(i, sin(i*50) * 50 + 50);
  PaintBox1 -> Canvas -> LineTo(i + 1, sin((i+1)*50) * 50 + 50);
 }
}
//---------------------------------------------------------------------------
При указанном значении j шэйп и лэйбл моргают. Если удалить один нолик (или больше) - то всё отлично.
Думаю, может, вызывать ещё один поток из ОнПэинта, который будет рисовать трудный рисунок и не вешать основной поток... что думаете? ))))
Миниатюры
Мышь в виде перекрестия на весь PaintBox (Image)  
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
31.01.2016, 12:32

Как сместить Canvas в PaintBox не смещая PaintBox?
Как сместить например на 3 пикселя весь рисунок в PaintBox, не изменяя при этом размеров и позиции PaintBox?

Растянуть Image на весь Glyph SpeedButton-а
Такой кодdynamic_cast&lt; TImage*&gt;(Form13-&gt;FindComponent(&quot;I160&quot;))-&gt;Width=SB-&gt;Width; dynamic_cast&lt;...

Acronis True Image тоже весь жёсткий диск форматирует
Acronis True Image тоже ВЕСЬ жёсткий диск форматирует, если конфигурация разделов изменилась? Эта проблема появилась когда я везде...

Вывести весь текст словами в виде количественного числительного
Задано некоторое натуральное число k. Требуется вывести весь текст словами в виде количественного числительного, которое означает заданное...

Вывести весь текст словами в виде количественного числительного
Задано некоторое натуральное число k. Требуется вывести весь текст словами (например, при k=5 вывод имеет вид &quot;пять&quot;, при k=123...


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

Или воспользуйтесь поиском по форуму:
59
Ответ Создать тему
Новые блоги и статьи
GitHub Copilot в JetBrains: модель по умолчанию, Fix и контроль MCP
and_y87 12.10.2026
10 октября 2026 года GitHub обновил Copilot для JetBrains: добавил настройки стартовой модели, исправления из диагностики и управление автозапуском MCP. Поддержка IDE 2025. 1 прекращена — требуется. . .
GitHub Copilot в JetBrains: модель по умолчанию, Fix и контроль MCP
and_y87 12.10.2026
10 октября 2026 года GitHub обновил Copilot для JetBrains: добавил настройки стартовой модели, исправления из диагностики и управление автозапуском MCP. Поддержка IDE 2025. 1 прекращена — требуется. . .
День 5 из 28: Codex подсказывает следующий запрос
and_y87 12.10.2026
9 октября 2026 года OpenAI запустила бету Composer predictions — подсказок следующего сообщения в текущем диалоге Codex. Это помощь с формулировкой запроса, а не автоматическое продолжение задачи. . . .
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru