(РЕШЕНО) TEdit прыжок курсора вправо при удалении
Модератор: Модераторы
1 Определиться где проблемное место. в проекте, в лазаре (lcl) или fpc. В последнем варианте компилятор придется собрать с отладочной инфой, проект и lcl можно ковырять включив отладочную инфу в настройках проекта.
2 Воспроизвести вылет, перед вылетом поставить точку останова в проблемном месте (в случае если проблемное место исполняется много раз, если только один - точку останова можно ставить перед запуском)
3 смотришь при обращении к чему происходит ошибка. на скриншоте вижу FLookup.ControlItems.Count
наводишь курсор на FLookup - смотришь что это такое и что там есть, потом на ControlItems, потом на Count и т.д. и так всё в этой строчке.
Если ты наводишь курсор на пропертю - отладчик неможет ее вычисллить и показать, самое простое если проперти это обертка для приватного поля - как count для fcount. тогда жмешь alt+f7 и в окне "вычислить-изменить" вбиваешь FLookup.ControlItems.FCount - смотришь что там лежит (конечно если FLookup и ControlItems не вычислимые проперти)
Так глядишь все что есть в проблемной строчке. Если поглядеть неполучается - пробуешь выполнить строку по F7 - внимательно глядя что куда уходит и что откуда возвращается.
Так шаг за шагом находишь при обращении к чему происходит вылет. Потом раскидываешь мозгами как могло получиться что это "к чему" сбоит. Оно или не инициализировано, или уже уничтожено, или испорчено - затерто чемто другим. Ищешь причину этого сбоя.
Данный процесс называется отладкой, он очень интересный)))
Также есть более простые (но не всегда срабатывающие) пути - прогнать программу под valgind`ом, прогнать програму с heaptrc. Обычно они ругаются на проблемные места.
2 Воспроизвести вылет, перед вылетом поставить точку останова в проблемном месте (в случае если проблемное место исполняется много раз, если только один - точку останова можно ставить перед запуском)
3 смотришь при обращении к чему происходит ошибка. на скриншоте вижу FLookup.ControlItems.Count
наводишь курсор на FLookup - смотришь что это такое и что там есть, потом на ControlItems, потом на Count и т.д. и так всё в этой строчке.
Если ты наводишь курсор на пропертю - отладчик неможет ее вычисллить и показать, самое простое если проперти это обертка для приватного поля - как count для fcount. тогда жмешь alt+f7 и в окне "вычислить-изменить" вбиваешь FLookup.ControlItems.FCount - смотришь что там лежит (конечно если FLookup и ControlItems не вычислимые проперти)
Так глядишь все что есть в проблемной строчке. Если поглядеть неполучается - пробуешь выполнить строку по F7 - внимательно глядя что куда уходит и что откуда возвращается.
Так шаг за шагом находишь при обращении к чему происходит вылет. Потом раскидываешь мозгами как могло получиться что это "к чему" сбоит. Оно или не инициализировано, или уже уничтожено, или испорчено - затерто чемто другим. Ищешь причину этого сбоя.
Данный процесс называется отладкой, он очень интересный)))
Также есть более простые (но не всегда срабатывающие) пути - прогнать программу под valgind`ом, прогнать програму с heaptrc. Обычно они ругаются на проблемные места.
Ну это всё я же делал и описывал.
Последний вариант - переделать проблемную таблицу в программе заново. Сделал копию программы для опытов. Сейчас я убрал из запроса все Lookup поля и заработало. Добавил одно. Cancel работает. Post не работает, т.к. теперь в версии 1.7, видимо, в автоматически создаваемые update идут и лукап поля (в 1.6 не шли вычисляемые поля в автосоздаваемые запросы инсёрта, обновления, удаления, рефреша), т.к. мне вылезает ошибка, что нет такого поля и указывает имя лукапового поля. Значит придётся UpdateSQL сейчас вручную прописывать.
- Скорее всего не lcl и не fpc отдельно. А их сожительство:
- lcl 1.6 + fpc 3.0.0 всё работает
- lcl 1.7 + fpc 3.0.0 не работает
- lcl 1.7 + fpc 3.1.1 всё работает правда заработало в одном только месте. Вторая программа не работает в этом же месте.
- Я делал скриншоты. Это и есть точка останова, а дальше любое продолжение и с входом и в обход и запуск вызывают обвал.
- Ошибка при обращении к FLookup.ControlItems.Count. Если это условие из if убрать, то проходит дальше до FControlItems.Clear; получается по сути ошибка при обращении к TStrings. Курсор я наводил на ControlItems и там всё ок. Он показывает в xml структуру, да и если бы не существовал, то не прошло бы проверку условие на nil я выше писал, что специально даже явно добавлял {$B-}, хотя она и так выключена
Последний вариант - переделать проблемную таблицу в программе заново. Сделал копию программы для опытов. Сейчас я убрал из запроса все Lookup поля и заработало. Добавил одно. Cancel работает. Post не работает, т.к. теперь в версии 1.7, видимо, в автоматически создаваемые update идут и лукап поля (в 1.6 не шли вычисляемые поля в автосоздаваемые запросы инсёрта, обновления, удаления, рефреша), т.к. мне вылезает ошибка, что нет такого поля и указывает имя лукапового поля. Значит придётся UpdateSQL сейчас вручную прописывать.
Последний раз редактировалось tema 25.02.2017 13:44:24, всего редактировалось 2 раза.
>>Скорее всего не lcl и не fpc отдельно. А их сожительство:
Скорее всего ты))
Скорее всего ты))
Огромнейшая просьба к знающим буржуйский запостить в багзиллу лазаруса или fpc эту проблему: viewtopic.php?f=5&t=17326&start=15#p112141
Очень не хочется, чтобы она вылезла в 1.8...
Добавлено спустя 6 минут 19 секунд:
Сейчас сам попробую с яндекс-переводчиком составить багу.. Отпишусь, что получилось
Добавлено спустя 24 минуты 25 секунд:
http://mantis.freepascal.org/view.php?id=31445
Очень не хочется, чтобы она вылезла в 1.8...
Добавлено спустя 6 минут 19 секунд:
Сейчас сам попробую с яндекс-переводчиком составить багу.. Отпишусь, что получилось
Добавлено спустя 24 минуты 25 секунд:
http://mantis.freepascal.org/view.php?id=31445
вы сделали и показали скрины результата, а не следствия.Я делал скриншоты. Это и есть точка останова, а дальше любое продолжение и с входом и в обход и запуск вызывают обвал.
Т.е. смотрите что вы делали не так в своём коде. А потом грешите на лазарь или фпс.
Вы считаете верным делать Edit при не заполненных данных в компоненте. Я считаю этот вариант ошибочным. Ну что вам компонент может отредактировать? Т.е. каким образом он это будет редактировать? Сам придумает? Вот он и "придумал". Бросил в эксепшин.
Далее. По поводу бокса. Из сорцов следует что вы берёте данные из поля tkvalName но..о в запросе кажись нет такого поля... Т.е. что вам должен сказать лазарь? Ещё один эксепшин. Т.е. он есть но в SQLQuery2, а вы дергаете данные из SQLQuery1 (а тут его нету). Спутали DataSource ????
По поводу крякозяблов. Уж больно не красиво получается ваша теория "обрубки символов". Это из скрина. Почему у вас поле Пол всё в этих символах? Ведь, по идее, там один символ и он должен влезть. В принципе вызывают вопросы и иные поля.
Учитывая что вы не дали проект с багом, а тот что дали ещё больше вопросов возникает о корректности создания вами программы, следует: смотрите что не так у вас в программе. Тем более, если учесть, что баг повторился во второй программе. При этом вы, если не ошибаюсь, исправили баг....
п.с.
Возможно я и ошибаюсь.... Но у меня сломался волшебный шар.
pupsik писал(а):вы сделали и показали скрины результата, а не следствия.Я делал скриншоты. Это и есть точка останова, а дальше любое продолжение и с входом и в обход и запуск вызывают обвал.
Т.е. смотрите что вы делали не так в своём коде. А потом грешите на лазарь или фпс.
Вы считаете верным делать Edit при не заполненных данных в компоненте. Я считаю этот вариант ошибочным. Ну что вам компонент может отредактировать? Т.е. каким образом он это будет редактировать? Сам придумает? Вот он и "придумал". Бросил в эксепшин.
Это не мой код, где остановка. Это код lcl
Почему при незаполненных?
У меня база заполнена. Если в базе пусто, то эта процедура не выполнится вообще. Это именно модификация конкретной записи на которой стоит курсор.
pupsik писал(а):Далее. По поводу бокса. Из сорцов следует что вы берёте данные из поля tkvalName но..о в запросе кажись нет такого поля... Т.е. что вам должен сказать лазарь? Ещё один эксепшин. Т.е. он есть но в SQLQuery2, а вы дергаете данные из SQLQuery1 (а тут его нету). Спутали DataSource ????
Есть такое поле. Оно лукап. И всегда работало именно так. Кстати, в той программе, которую Вы, наверное, смотрите, у меня всё работает так что ошибок нет. Но в другой программе большой у меня всё сделано точно так же, но не работает. Отличие только в том, что та программа создавалась в младших версиях Lazarus и fpc, т.к. начало написания программы 3 года назад. Я могу попробовать извлечь эту форму из большой программы и прикрепить сюда, чтобы Вы могли посмотреть как там это организовано.
pupsik писал(а):По поводу крякозяблов. Уж больно не красиво получается ваша теория "обрубки символов". Это из скрина. Почему у вас поле Пол всё в этих символах? Ведь, по идее, там один символ и он должен влезть. В принципе вызывают вопросы и иные поля.
Один символ не влезает потому что для одного русского символа нужно два символа, а выдаётся только один.
pupsik писал(а):Учитывая что вы не дали проект с багом, а тот что дали ещё больше вопросов возникает о корректности создания вами программы, следует: смотрите что не так у вас в программе.
Я сейчас постараюсь извлечь часть проекта, чтобы показать где баг. Если не возражаете, то заполнения таблиц я по запросу в личку отправлю, т.к. там фамилии и имена, чтобы не постить на всебщий обзор. Хотя можно просто для проверки заполнить Иванов, Петров, Сидоров
pupsik писал(а):Тем более, если учесть, что баг повторился во второй программе. При этом вы, если не ошибаюсь, исправили баг....
Баг я не исправил. Он волшебным образом ушёл после того, как я удалил лукап поле и снова его создал точно такое же. Но это плохое исправление. Мне теперь во всём проекте чтоли лукап поля удалять-создавать?
Добавлено спустя 9 минут 27 секунд:
Кстати, пользуясь случаем, хочу поблагодарить alexs как вдохновителя меня на этот проект и на переход с дельфи на лазарус и с винды на линукс
Именно его программа стала отправной точкой, когда я понял, что создать этот проект можно и не только на дельфи, но и на лазарусе.
alexs, пока этот мой проект до конца не закончен, до сих пор используются элементы твоей той программы (я её уже довольно сильно перекорячил, но в целом много чего ещё осталось от первоначального) на всех основных соревнованиях в России по Тхэквондо пхумсэ
tema я описал то что увидел в данном вашем исходнике и скрине...
По поводу заполнение. Св-во Edit в запросе подразумевает выполнение уже готового запроса. У вас его нет. Что далее должно быть? Всё равно что вы потом делаете.

Но опять вопрос: не проще ли в одном запросе делать выборку из двух таблиц, а бокс "прицепить" к справочнику?

По поводу заполнение. Св-во Edit в запросе подразумевает выполнение уже готового запроса. У вас его нет. Что далее должно быть? Всё равно что вы потом делаете.
хм... вы верите в волшебство? Значит у вас что то было не так.Он волшебным образом ушёл после того, как я удалил лукап поле
мдя...Один символ не влезает потому что для одного русского символа нужно два символа, а выдаётся только один.
упс... теперь досмотрел этот гамбитКстати, в той программе, которую Вы, наверное, смотрите, у меня всё работает так что ошибок нет.
Но опять вопрос: не проще ли в одном запросе делать выборку из двух таблиц, а бокс "прицепить" к справочнику?
что то мне подсказывает что вы таким образом и найдёте ошибкуЯ сейчас постараюсь извлечь часть проекта, чтобы показать где баг
pupsik писал(а):tema я описал то что увидел в данном вашем исходнике и скрине...
По поводу заполнение. Св-во Edit в запросе подразумевает выполнение уже готового запроса.
Это не так. Процедура Edit просто переводит таблицу в режим редактирования. С помощью лукап полей я изменяю квалификацию спортсмена и т.п. Если не перевести в режим редактирования, то нельзя будет изменять поля в текущей записи с помощью, например, Querry1.FieldByName('field1').AsInteger:=1;. А дальше Post или Cancel, чтобы принять или отменить изменения соответственно.
pupsik писал(а):хм... вы верите в волшебство? Значит у вас что то было не так.Он волшебным образом ушёл после того, как я удалил лукап поле
Приходится верить. Я проверил несколько раз. Никаких изменений я не вношу. Просто удаляю лукап поле и создаю абсолютно точно такое же лукап поле.
pupsik писал(а):упс... теперь досмотрел этот гамбитКстати, в той программе, которую Вы, наверное, смотрите, у меня всё работает так что ошибок нет.
Но опять вопрос: не проще ли в одном запросе делать выборку из двух таблиц, а бокс "прицепить" к справочнику?
Не проще. Лукап поле применяется как раз для того чтобы было проще, т.к. параметров и лукап полей много.
pupsik писал(а):что то мне подсказывает что вы таким образом и найдёте ошибкуЯ сейчас постараюсь извлечь часть проекта, чтобы показать где баг
Очень надеюсь. Пойду ребёнка кормить, потом займусь
э..э,а вы не спутали? Это же не локальная база...Процедура Edit просто переводит таблицу в режим редактирования
см. выше.Не проще. Лукап поле применяется как раз для того чтобы было проще...
В принципе в дбф таких нюансов бы не было. Но вы же не с дбф работаете. Можно и с литлом такое винтить - если работать как с таблицей, а не запросами.
повторяю: вы что то не так делаете. Волшебства нет, по крайней мере в программировании.Приходится верить. Я проверил несколько раз.
п.с.
не спорю: сложновато, на первый взгляд, соединять несколько таблиц в одном запросе. А может стоит попробовать?
И, вполне возможно, попытка работы реляционки как с обычным дбф (образно) может привести к странным глюкам.
pupsik писал(а):э..э,а вы не спутали? Это же не локальная база...Процедура Edit просто переводит таблицу в режим редактирования
Не спутал. Попробуйте.
pupsik писал(а):см. выше.Не проще. Лукап поле применяется как раз для того чтобы было проще...
В принципе в дбф таких нюансов бы не было. Но вы же не с дбф работаете. Можно и с литлом такое винтить - если работать как с таблицей, а не запросами.
Тут и идёт работа как с таблицей именно так и организованы компоненты lcl, а потом всё отправляется на сервер.
pupsik писал(а):повторяю: вы что то не так делаете. Волшебства нет, по крайней мере в программировании.Приходится верить. Я проверил несколько раз.
Есть. У меня даже бубен есть настоящий шаманский с северов нашей необъятной. Очень часто помогает. Но сейчас оказался бессилен.
pupsik писал(а):п.с.
не спорю: сложновато, на первый взгляд, соединять несколько таблиц в одном запросе. А может стоит попробовать?
И, вполне возможно, попытка работы реляционки как с обычным дбф (образно) может привести к странным глюкам.
Сложновато не соединять. Таких соединений у меня навалом, хоть в запросах, хоть в самой базе в виде view. Бессмысленно усложнять редактирование простой но длинной таблицы с кучей зависимых полей, когда каждое поле к своей таблице: квалификация, спортивная квалификация, клуб и т.п.. Это элементарно решается встроенным функционалом лукапа. Зачем усложнять?
Добавлено спустя 29 минут 52 секунды:
Мне уже в баге ответить успели, что *2 мало надо *4
Добавлено спустя 10 часов 39 минут 37 секунд:
Всё сдаюсь!
В этом ужасном транке столько глюков, что мне проще смириться с прыгающим курсором при удалении. Попробую с ним как-нибудь справиться
http://bugs.freepascal.org/view.php?id=31447
Добавлено спустя 19 минут 49 секунд:
Несколько раз давал себе зарок не ставить всякие транки! Я три дня просто потерял на это! В общем глюков вылезло там ну просто немеряно. Я готов с ними поиграть/поискать, но не когда у меня горит программа.
В общем решил сабж так:
Код: Выделить всё
Index: lcl/interfaces/gtk2/gtk2callback.inc
===================================================================
--- lcl/interfaces/gtk2/gtk2callback.inc (revision 53089)
+++ lcl/interfaces/gtk2/gtk2callback.inc (working copy)
@@ -601,7 +601,7 @@
begin
{mark as invalid event for gtkchanged_editbox, so
it doesn't update cursor pos or we have a mess.}
- if (gtk_major_version = 2) and (gtk_minor_version < 17) then
+ // if (gtk_major_version = 2) and (gtk_minor_version < 17) then
begin
Info := GetWidgetInfo(Widget, False);
include(Info^.Flags, wwiInvalidEvent);
Index: lcl/interfaces/gtk2/gtk2widgetset.inc
===================================================================
--- lcl/interfaces/gtk2/gtk2widgetset.inc (revision 53089)
+++ lcl/interfaces/gtk2/gtk2widgetset.inc (working copy)
@@ -465,7 +465,7 @@
if GTK_IS_ENTRY(gObject) then
begin
ConnectSenderSignal(gObject,'backspace', @gtkchanged_editbox_backspace);
- if (gtk_major_version = 2) and (gtk_minor_version < 17) then
+ // if (gtk_major_version = 2) and (gtk_minor_version < 17) then
ConnectSenderSignal(gObject,'delete-from-cursor', @gtkchanged_editbox_delete);
end;
ConnectSenderSignal(gObject, 'changed', @gtkchanged_editbox);
Всё остальное работает и так. Никаких больше вмешательств не требуется. Можно было и просто виджетсет на qt поменять и все дела.
Добавлено спустя 25 минут 53 секунды:
zub писал(а):попытка обращения к несозданому TStrings
Именно так.
Я поставил writelnы в нескольких местах в lcl .inc связаных с лукапом. Так вот, когда он перебирает лукапкомбобоксы после Cancel он имена полей получает позже, чем данные каким-то образом. Т.е. в объекте имя указывается одно а данные от следующего имени. Т.е. у него до момента падения распечатываются так:
имя лукапа 1, а данные из лукапкомбобокса 2
имя лукапа 2, а данные из лукапкомбобокса 3
.....
имя лукапа N, а данные из лукапкомбобокса N+1, которого не существует и ссылка ушла на обычный TEdit который существует, поэтому не nil, но у которого просто нету свойства Count
Причём, при загрузке формы он тоже перечисляет, но правильно. Там всё совпадает. Это начинается только при Cancel.
Волшебство, описанное выше, оказалось в следующем.
Когда я удалил на этой форме обычный комбобокс, который даже не DB, а простой у меня на форме один есть и создал его в последнюю очередь, то при перечислении:
имя лукапа N, а данные из обычного комбобокса
Ничего после этого не падает, но это какой-то зверский глюк. Я не нашёл где идёт опережение получения данных.
Тут: viewtopic.php?f=5&t=17326&start=15#p112120 всё печатается как надо без опережения.
Могу предположить, что если я удалил бы на форме и пересоздал ВСЕ комбобоксы заново, то ошибка бы тоже ушла, но это было бы как раз волшебство компилятора и/или лазаруса при переходе с версии на версию.
Обрезание русских букв в транке пофиксили:
http://bugs.freepascal.org/view.php?id=31445
http://bugs.freepascal.org/view.php?id=31445
