Aleks133
-
Постов
38 -
Зарегистрирован
-
Посещение
Активность репутации
-
Aleks133 отреагировална Igor в TStringGrid - удалить строку, удалить все строки
не знаю актуально ещё или нет, но возможно так:
http://stringgrid-delphi.ru/delete-row.php
Удаление одной строки:
процедура:
procedure TForm1.DeleteRow(ARow: Integer); var i, j: Integer; begin with StringGrid1 do begin for i:=ARow+1 to RowCount-1 do for j:=0 to ColumnCount-1 do Cells[j, i-1]:=Cells[j, i]; RowCount:=RowCount-1; end; end;
вызов процедуры:
DeleteRow(номер строки);
Удаление всех строк:
StringGrid1.RowCount:=0;
-
Aleks133 отреагировална krapotkin в Работа с БД в класс
Хорошей практикой является следующая концепция.
Есть модель данных (МД) - набор классов, описывающий все, что происходит в вашей программе, и хранящий все нужные данные.
А есть отдельный модуль, который отвечает за загрузку и сохранение этой МД. В нем класс-"загрузчик". Чтобы вам было удобнее, можно в качестве такого модуля сделать Datamodule, в котором будут все нужные все компоненты и методы.
При этом становится не суть важно, откуда идет загрузка, хоть из интернета, хоть из БД.
Вопросов с выделением этих процессов в отдельные потоки не будет, только нужно помнить только одно - один поток - один Datamodule. Т.е. создавать их надо динамически.
создали объект модели данных, создали datamodule, вызвали некий метод для загрузки данных в объект.
Хорошим тоном будет не создавать/уничтожать Datamodule каждый раз заново, потому что процесс подключения к БД довольно длительный по сравнению с простым запросом в БД. Поэтому можно создать какой-то пул(массив, список) уже созданных DM и брать одну штуку из него для совершения операции, и возвращать обратно по ее окончанию.
Получается, что каждый поток будет иметь свой Datamodule и следовательно свой FDConnection и свой FDQuery для каждой операции.
Надеюсь, я ответил на ваш вопрос
-
Aleks133 отреагировална ophion в Записать картинку с камеры в BLOB
Вот пример того, как писать и читать BLOB
procedure SaveToFireDACBlob; var MemStream: TMemoryStream; begin FireDAC.Connected := True; MemStream := TMemoryStream.Create; try Image1.Bitmap.SaveToStream(MemStream); MemStream.Seek(0,0); FDQueryInsert.ParamByName('Media').LoadFromStream(MemStream,ftBlob); FDQueryInsert.ParamByName('MType').AsString := '0'; FDQueryInsert.ExecSQL(); except on e: Exception do begin ShowMessage(e.Message); end; end; MemStream.Free; FireDAC.Connected := False; end; procedure LoadFromFireDACBlob; var BlobStream: TStream; begin FireDAC.Connected := True; try FDQuerySelect.Open; FDQuerySelect.First; while(not FDQuerySelect.EOF)do begin // access a stream from a blob like this BlobStream := FDQuerySelect.CreateBlobStream(FDQuerySelect.FieldByName('Media'),TBlobStreamMode.bmRead); // access a string from a field like this if (FDQuerySelect.FieldByName('MType').AsString='0') then begin // load your blob stream data into a control ImageViewer.Bitmap.LoadFromStream(BlobStream); end; BlobStream.Free; FDQuerySelect.Next; end; except on e: Exception do begin //ShowMessage(e.Message); end; end; FireDAC.Connected := False; end; {источник http://www.fmxexpress.com/read-and-write-a-blob-field-using-firedac-with-firemonkey-on-android-and-ios/} Касательно работы с изменением качества/размера, считаю что необходимо использовать TBitmapSurface (unit FMX.Surfaces)
-
Aleks133 получил реакцию от Ingalime в Сканер QR Кода зависает приложение
Сам не знаю как, но получилось)))пол дня читал форумы чтобы хоть что-то понять из этого.
И методом "научного тыка" вот:
uses androidapi.helpers, Androidapi.JNI.app,FMX.Helpers.Android, Androidapi.JNI.GraphicsContentViewText; var FMessageSubscriptionID:integer; procedure tform1.Scan1; var intent: JIntent; begin FMessageSubscriptionID := TMessageManager.DefaultManager.SubscribeToMessage(TMessageResultNotification, HandleActivityMessage); intent := TJIntent.Create; intent.setAction(StringToJString('com.google.zxing.client.android.SCAN')); SharedActivity.startActivityForResult(intent, 0); end; procedure TForm1.HandleActivityMessage(const Sender: TObject; const M:TMessage); var RequestCode, ResultCode: Integer; Intent: JIntent; s:string; begin if not(M is TMessageResultNotification) then exit; TMessageManager.DefaultManager.Unsubscribe(TMessageResultNotification, FMessageSubscriptionID); FMessageSubscriptionID := 0; RequestCode:=TMessageResultNotification(M).RequestCode; ResultCode:=TMessageResultNotification(M).ResultCode; Intent:=TMessageResultNotification(M).Value; if ResultCode = TJActivity.JavaClass.RESULT_OK then begin if Assigned(Intent) then begin s:=JStringToString(intent.getStringExtra(StringToJString('SCAN_RESULT'))); //получил результат со сканера convert(s); //использовал результат со сканера в своей процедуре end; end else if ResultCode = TJActivity.JavaClass.RESULT_CANCELED then begin //Memo1.Lines.Append('RESULT_CANCELED'); end; end; procedure TForm1.Button2Click(Sender: TObject); begin scan1; //запуск сканеровки; end; Не знаю правильно ли это все будет работать, но во всяком случае приложение не виснит(пока) и что хотел получил.
Slym'у большое спасибо за наводку.
Если кто знает что нужно добавить\исправить для гарантированно стабильной(без сюрпризов в дальнейшем) работы кода, буду благодарен.
-
Aleks133 отреагировална Slym в Сканер QR Кода зависает приложение
SharedActivity.startActivityForResult(intent, 0);
результат получаешь в TMessageResultNotification
intent.getStringExtra("SCAN_RESULT");
intent.getStringExtra("SCAN_RESULT_FORMAT");
-
Aleks133 отреагировална krapotkin в Загрузка настроек приложения из БД
правильный ответ - не делать так ))
нужно хранить настройки приложения в отдельном классе
тогда кроме самого класса нужны методы, которые
1) читают пишут его из ... файла, БД, интернета и т.д.
2) в нужный момент (обычно чтобы изобразить форму и заполнить св-ва компонентов или еще для чего угодно) использовать эти настройки
3) вытекает из 2) сохранять в нужный момент новые значения в переменную, где лежат настройки
для хранения настроек отлично подходит JSON. Т.к. он может иметь иерархическую структуру, что очень удобно. Его и хранить в БД.
Можно и прямо поля, строки и все такое, но все равно, собирать их нужно в некое хранилище в программе.
Пример разбирал тут http://www.cyberforum.ru/blogs/469693/blog4883.html
-
Aleks133 отреагировална Slym в Загрузка настроек приложения из БД
FDQuery1.Lookup?
или RTTI
c:=FindComponent(FDQuery1.Fields[1].AsString)
if assigned(c)
SetProp(c,FDQuery1.Fields[2].AsString,TValue.From(FDQuery1.Fields[3].AsString))
-
Aleks133 получил реакцию от qz5 в [ListView] получить список элементов у которых Checkmark=true
Долго я искал как это сделать в DynamicAppearance.
procedure TForm1.Button2Click(Sender: TObject);
var
i: integer;
begin
Memo1.Lines.Clear;
for i := 0 to ListView1.ItemCount - 1 do
begin
if ListView1.Items.Objects.FindObjectT<TListItemAccessory>('Accessory2')
.Visible = true then
begin
Memo1.Lines.Add('Индекс отмеченного итема= ' + inttostr(i) + ',Значение = ' +
ListView1.Items.Objects.FindObjectT<TListItemText>('Text3').Text );
end;
end;
end;
-
Aleks133 получил реакцию от Ingalime в [ListView] получить список элементов у которых Checkmark=true
Долго я искал как это сделать в DynamicAppearance.
procedure TForm1.Button2Click(Sender: TObject);
var
i: integer;
begin
Memo1.Lines.Clear;
for i := 0 to ListView1.ItemCount - 1 do
begin
if ListView1.Items.Objects.FindObjectT<TListItemAccessory>('Accessory2')
.Visible = true then
begin
Memo1.Lines.Add('Индекс отмеченного итема= ' + inttostr(i) + ',Значение = ' +
ListView1.Items.Objects.FindObjectT<TListItemText>('Text3').Text );
end;
end;
end;