Potrzebna pomoc z typem rekordowym, błąd z wyświetlaniem w Label.

0

Cześć, mam problem z wyświetlaniem Labela, wszystko chodzi idealnie tylko nie ta jedna linijka, Bez względu na jaki Item klikne w Listboxie wyświetla się to samo.Problem musi być w tej części z typem rekordowym, Bo jak tą procedurę poniżej zrobię przez pętle for działa i Label

LblWords.Caption := IWord.spelling +'   ( ' + IWord.pronunciation + ' )';

Procedure TForm1.DisplayjALL();
var
  lWord: Tword;
begin
 lWord := getWordBySpelling(ListBox1.Items.Strings[ListBox1.ItemIndex], self.XMLIntf);

LblWords.Caption := IWord.spelling +'   ( ' + IWord.pronunciation + ' )';
LoadImage(extractfilepath(paramstr(0)) + lWord.picture, Image1);
PlayFile (extractfilepath(paramstr(0)) + lWord.mp3, MediaPlayer1, Image2);
end;
interface

uses TRANSLATORXML, sysutils;

type
  Tword = record
    id: integer;
    mp3: string;
    spelling: string;
    pronunciation: string;
    categoryId: integer;
    language: string;
    picture: string;
  end;

procedure copyWord(aFrom: IXMLWordType; var aTo: Tword);
function getWordById(aId: integer; aIXMLDictionaryType: IXMLDictionaryType): Tword;
function getWordBySpelling(aSpelling: string; aIXMLDictionaryType: IXMLDictionaryType): Tword;

implementation

procedure copyWord(aFrom: IXMLWordType; var aTo: Tword);
begin
  aTo.id := aFrom.id;
  aTo.mp3 := aFrom.mp3;
  aTo.spelling := aFrom.spelling;
  aTo.pronunciation := aFrom.pronunciation;
  aTo.spelling := aFrom.spelling;
  aTo.categoryId := aFrom.categoryId;
  aTo.language := aFrom.language;
  aTo.picture := aFrom.JPEG;
end;

function getWordBySpelling(aSpelling: string; aIXMLDictionaryType: IXMLDictionaryType): Tword;
var
  I: integer;
  lIWord: IXMLWordType;
begin
  fillchar(result, sizeof(result), 0);
  result.id := -1;              
  for I := 0 to aIXMLDictionaryType.words.Count - 1 do
  begin
    lIWord := aIXMLDictionaryType.words[I];
    if uppercase(aSpelling) = uppercase(lIWord.spelling) then
    begin
      copyWord(lIWord, result);
    end;
  end;
end;

function getWordById(aId: integer; aIXMLDictionaryType: IXMLDictionaryType): Tword;
var
  I: integer;
  lIWord: IXMLWordType;
begin
  fillchar(result, sizeof(result), 0);
  result.id := -1;
  for I := 0 to aIXMLDictionaryType.words.Count - 1 do
  begin
    lIWord := aIXMLDictionaryType.words[I];
    if aId = lIWord.id then
    begin
      copyWord(lIWord, result);
    end;
  end;
end;

1

W metodzie getWordBySpelling brakuje Exit po spełnieniu warunku (w getWordById też go brakuje). Poza tym:

LblWords.Caption := IWord.spelling +'   ( ' + IWord.pronunciation + ' )';

Tu można użyć funkcji Format.

if uppercase(aSpelling) = uppercase(lIWord.spelling) then

A tutaj funkcji SameText.

Poza tym ciągi znaków przekazuj przez stałą (ze słówkiem const) - jest to najszybszy możliwy sposób (pomijając wskaźniki rzecz jasna). No i stosuj PascalCase dla nazw metod, zmiennych itd.

0

Wyszło mi coś takiego, poniżej., Jakbyś mógł pokazać o co chodzi dokładnie z tym const jak to ma wyglądać. Ale dalej nie rozwiązuję to problemu z Label ale dziękuję za uwagi i dobrze poznać nową funkcję SameText Jak zrobię procedurę tą gdzie jest osadzony Label (przez pętle For) to chodzi bez problemu więc chochlik musi być w tych funkcjach, tylko nie wiem gdzie. Tym bardziej że i wyświetlanie obrazka się zmienia i mp3 tylko nie Label, poza tym wyświetla się tylko spelling bez pronunciation a miało jedno i drugie

begin
    lIWord := aIXMLDictionaryType.words[I];
   if SameText(aSpelling,lIWord.spelling)then
      begin
      copyWord(lIWord, result);
      exit
      end;
  end;
0

Problem nie tkwi w typie rekordowym ale w tym co siedzi w zmiennej rekordowej
Być może masz coś nie tak w samym pliku XML i stąd IWord.pronunciation jest pustym stringiem, a najlepiej sprawdź pod debuggerem co siedzi w IWord.pronunciation

1
ToBylaOna:

Wyszło mi coś takiego, poniżej.

No to wyszło Ci zupełnie co innego, bo brakuje pętli. Sugerowałem wymianę jednej linijki, a nie usunięcie połowy.

Jakbyś mógł pokazać o co chodzi dokładnie z tym const jak to ma wyglądać.

Przecież napisałem - jak przekazujesz ciągi znaków w parametrach to rób to przez const:

function GetWordBySpelling(const ASpelling: String; {...}): TWord;

Jak zrobię procedurę tą gdzie jest osadzony Label (przez pętle For) to chodzi bez problemu więc chochlik musi być w tych funkcjach, tylko nie wiem gdzie.

No to zrób ją i pokaż, bo inaczej skąd mamy wiedzieć co ona robi?

0

Gdyby było coś poza tym to tu poniżej też by nie miało prawa działać, tak na zdrowy rozum myśleć

i : Integer;
begin
for I := 0 to XMLIntf.Words.Count - 1 do
 if ListBox1.Items.Strings[ListBox1.ItemIndex] = XMLIntf.Words[I].spelling then
  begin
 LblSlowo.Caption := XMLIntf.Words[i].Spelling +'   ( ' + XMLIntf.Words[i].Pronunciation + ' )';
 LoadImage(extractfilepath(paramstr(0)) + XMLIntf.Words[i].Jpeg, Image1);
 PlayFile (extractfilepath(paramstr(0)) + XMLIntf.Words[i].Mp3, MediaPlayer1, Image2);
end;
 end;

A w ten sposób działa

0

W tym kodzie nie korzystasz z dodatkowej zmiennej typu IXMLWordType, więc ona musi sprawiać problem.

2

błąd literowy ....

Procedure TForm1.DisplayjALL();
var
  lWord: Tword; /// tutaj zmienna lWord pisana z małej litery 'l' jak Leon
begin
 lWord := getWordBySpelling(ListBox1.Items.Strings[ListBox1.ItemIndex], self.XMLIntf);
 
 LblWords.Caption := IWord.spelling +'   ( ' + IWord.pronunciation + ' )';  // tutaj zmienna IWord pisana z dużej litery "I" jak Irena 
 LoadImage(extractfilepath(paramstr(0)) + lWord.picture, Image1);
 PlayFile (extractfilepath(paramstr(0)) + lWord.mp3, MediaPlayer1, Image2);
end;
0

dwie funkcje getWordByXXX można by zastąpić przeciążeniem

0

Pomógł by mi ktoś w ostatniej rzeczy by to ukończyć? Już mam wszystko brakuje tylko kropki nad **i ** a przy tym też najważniejszego.**spelling ** po dokonaniu tzw filtracji( na kategorie: liczebniki, kolory..., oraz język DE,PL) wybrane dodaje do Listboxa. To wszystko działa. brakuje mi tylko obsłużyć buton tłumacz. Słowo DE i PL mają ten sam translationId
Tak w skrócie wygląda plik xml .

<dictionary>
    <words>
        <word>    
            <translationId>1</translationId>
            <spelling>Jeden</spelling>
        </word>
        <word>
            <translationId>1</translationId>
            <spelling>Eins</spelling>
        </word>
        <word>
            <translationId>2</translationId>
            <spelling>Czerowny</spelling>
        </word>
        <word>
            <translationId>2</translationId>
            <spelling>Rot</spelling>
        </word>
    </words>
</dictionary>

I teraz jak obsłużyć buton Tłumacz : że jak w Listboxie będzie Select na ** spelling Jeden ** to ButtonTłumaczClick --> program odnajdzie nam w xml ten sam translationId = 1 czyli w tym przypadku spelling Eins Tylko że Select w Listboxie musi pozostać na swoim miejscu czyli na jeden. Po czym wykona nam się kod poniżej. Celowo opuściłam tu record by nie komplikować sprawy. Proszę gdyby ktoś z Was miał chwilkę
Dzięki Wam daleko już doszłam. Lecz tego jednego nie umiem ułożyć. Jestem tak blisko a jednak tak daleko. Bo właśnie brakuje mi najważniejszego

i : Integer;
begin
for I := 0 to XMLIntf.Words.Count - 1 do
 if ListBox1.Items.Strings[ListBox1.ItemIndex] = XMLIntf.Words[I].spelling then
  begin
 LblSlowo.Caption := XMLIntf.Words[i].Spelling +'   ( ' + XMLIntf.Words[i].Pronunciation + ' )';
 LoadImage(extractfilepath(paramstr(0)) + XMLIntf.Words[i].jpeg, Image1);
 PlayFile (extractfilepath(paramstr(0)) + XMLIntf.Words[i].Mp3, MediaPlayer1, Image2);
end;
 end;
0

Niepotrzebnie komplikujesz sobie pracę. Już Ci kiedyś tłumaczyłem, że wybierasz złą strukturę pliku konfiguracyjnego, przez co odczyt danych jest utrudniony (implementacja komplikuje się). W jednym elemencie (pisząc ogólnie) powinnaś grupować wszystkie informacje na temat danego słowa, a nie rozsiewać je po kilku elementach.

Myślę, że niezłym pomysłem będzie wrzucenie wszystkich tych informacji do atrybutów:

<dictionary>
  <word pl="jeden" en="one" />
  <word pl="czerwony" en="red" />
</dictionary>
  • zawartość pliku jak sama widzisz jest o wiele krótsza,
  • informacje na temat danego słowa i wszystkich jego tłumaczeń są ładnie i czytelnie zgrupowane w jednym elemencie,
  • brak konieczności użycia pętli iterującej w celu wskazania węzła do odczytu,
  • brak konieczności przechowywania ID elementu - ten z ListBox odpowiada elementowi w drzewie,
  • jeśli dojdzie nowe tłumaczenie to wystarczy dopisać nowy atrybut:
<dictionary>
  <word pl="jeden" en="one" de="eins" />
  <word pl="czerwony" en="red" de="rot" />
</dictionary>

Dobrze się zastanów nad tym, zanim naklepiesz sporo redundantnego kodu.

0

A gdzie dam ścieżki do mp3.pl mp3.de do jpg a to dopiero początek chcę to jeszcze dalej rozbudować ale to wszystko nie ma sensu jak nie obsłużę tego buttona. On mi został ostatni. Gdyby to był zwykły słownik Label i nic więcej to tak jak najbardziej. Pisałeś kiedyś kiedyś xml - jest ale tego najważniejszego przeskoczyć nie potrafię. Ja tu celowo opuściłam rekord i uprościłam xml zostawiając tylko jego strukturę i to co jest istotne resztę wymazałam by problem był czytelny.

0

Ścieżki do plików możesz wyznaczać na podstawie słów i używanych języków. Co innego, gdyby w konfigu miał znajdować się jeden element z zapisaną ścieżką, a co innego upychać je w każdym elemencie - nie ma to najmniejszego sensu.

Zmień więc koncepcję, zamiast zastanawiać się nad załataniem dziur w niej istniejących.

1 użytkowników online, w tym zalogowanych: 0, gości: 1