Skocz do zawartości

Matthew11

Użytkownicy
  • Zawartość

    81
  • Rejestracja

  • Ostatnio

  • Wygrane dni

    2

Wszystko napisane przez Matthew11

  1. Plan zakłada artykuły z takiej tematyki, jednak na razie nie ma żadnych terminów. Między innymi wykorzystanie ESP8266/ESP32 i połączenie go z serwerem napisanym w Qt na kilka sposobów. Idea jest taka, żeby po serii można było zbudować podwaliny np. pod własny system inteligentnego domu. Kolejna cześć będzie małym wstępem do łączności za pomocą TCP/IP w lokalnej sieci, co powinno wystarczyć do ustanowienia połączenia między ESP a aplikacją. @Quasiprogmista jak jesteś bardzo zainteresowany tematem to napisz do mnie a ja wskażę Ci miejsca gdzie szukać informacji.
  2. Na razie przycisk Run nie jest dostępny. Jest to znane ograniczenie w STMCubeIDE, tutaj przeczytamy: "The [Run] button is not yet implemented and has therefore been hidden from the toolbar menu and Run menu."
  3. Szukając przez chwilę u wujka Google, _delay_ms() odnosi mnie do funkcji z bibliotek AVR. Natomiast delay() to funkcja z API (myślę że można nazwać to API) które stworzyło Arduino (lub Wiring jeśli tam było pierwsze). We wszystkim spod parasola Arduino będzie używane właśnie delay(), dlatego że nieważne jaką płytkę weźmiesz, delay() i kod napisany za pomocą API Arduino, będzie działać funkcjonalnie (przynajmniej powinien) tak samo. A postarać się muszą o to twórcy konkretnej implementacji. I teraz jeśli _delay_ms() jest funkcją z biblioteki AVR, to niekoniecznie użyjemy ją dla płytek na procesorach ARM itp. Jak piszesz kod do konkretnego zadania i będzie tam tylko wspomniana 328P (lub inna z rodziny, dla której działa _delay_ms()), to używaj zoptymalizowanych funkcji. Natomiast jeśli piszesz "multiplatformowy" kod to używaj funkcji i metod z API Arduino.
  4. Cześć, Zacznę od efektu tego co chciałbym osiągnąć a potem przejdę do pytań: Chciałbym posiadać odpowiednio skrojoną (z pośród tych dostępnych) lub stworzoną własną dystrybucję Linuxa przeznaczoną na mini komputer klasy PC (konkretnie chodzi o serię Intel NUC z procesorem Intel i3/i5/i7 czyli popularną architekturę x86-64). Do komputera będzie podłączony ekran dotykowy (HDMI + USB na dotyk) i klawiatura z myszką po USB i co jakiś czas pendrive. Chciałbym, żeby przy starcie system bez konieczności logowania użytkownika wyświetlał aplikację na pełny ekran - bez okienek i przycisków w stylu zamknij lub zminimalizuj (aplikacja ma być wyświetlona na pełny ekran i nie powinno jej dać się zminimalizować lub zamknąć) - chodzi między innymi o to, żeby nie było np. loga Ubuntu, gdy system będzie się ładował. Aplikacja będzie napisana w Qt - więc rzeczy w stylu pełny ekran i brak przycisków okna załatwię w samej aplikacji. Sama implementacja aplikacji w Qt nie jest dla mnie żadnym problemem jednak problemem jest to, że za pomocą aplikacji powinienem być w stanie zamontować/odmontować pendrive i odczytać lub skopiować znajdujące się na nim pliki - generalnie aplikacja powinna mieć możliwość wykonywania procesów które wymagają sudo. Ponadto aplikacja będzie korzystać z portu szeregowego, do którego musi mieć dostęp. Również system / aplikacja muszą obsługiwać ekran dotykowy - aplikacja może być sterowana przez dotykowy ekran, nie tylko myszkę lub klawiaturę (które ostatecznie mogą być opcjonalne). Teraz chciałbym przejść do pytań, zakładając że chciałbym spełnić powyższe wymagania, która droga będzie lepsza lub szybsza: Skrojenie gotowej dystrybucji np. dostosowanie Ubuntu? Zastosowanie narzędzia w stylu Ubuntu-Builder do zbudowania własnej dystrybucji? Zastosowanie Yocto lub Buildroot'a (jak to opisał @Elvis odpowiednio tutaj i tutaj) do zbudowania dopasowanej/optymalnej do potrzeb dystrybucji? Jeśli pominąłem jakąś ważną rzecz, o której na tym etapie nie wiem, to będę bardzo wdzięczy za jej wypunktowanie. Dodam tylko, że nie miałem nigdy okazji budowania własnej dystrybucji Linuxa, natomiast wydaje mi się (może mylnie) że skoro architektura x86-64 jest popularna to budowa własnej dystrybucji i dopasowanie jej do wymagań dla lalika w temacie może być osiągalne i do wykonania. Ale nie ukrywam, że chciałbym wybrać najszybszą drogę, którą osiągnę zamierzony efekt nie mniej chętnie nauczę się czegoś nowego. Dzięki z góry za wszelkie podpowiedzi, sugestie lub uwagi.
  5. Z poziomu Qt Creatora - w drzewie projektów - klikasz na projekt PPM i klikasz Clean.
  6. Tak tych plików będzie sporo, a jeszcze więcej gdy budujemy projektu typu QtQuick - natomiast warto pamiętać, o tym aby po deploy przeprowadzić czyszczenie projektu, wtedy wszystkie niepotrzebne pliki (te z kompilacji) zostaną usunięte.
  7. @zwora Szybki test, jak tworzysz nowy projekt to ile masz różnych narzędzi? U mnie np: U Ciebie jeśli jest odpowiednio skonfigurowany MVSC to powinien być u Ciebie właśnie tam dostępny do wyboru. Jeśli nie jest dostępny to znaczy, że konfiguracja nie jest prawidłowa - wtedy pozostaje Ci szukanie informacji w sieci np. tutaj. Znajdziesz na ten temat mnóstwo informacji. Jeśli masz dostępny MVSC to po prostu otwórz projekt i kliknij ikonkę "Projects", następnie jeśli w projekcie nie masz aktywnego kompilatora MVSC to kliknij go z listy - u mnie jest np dostępny kompilator dla RPi3, ale nie jest aktywny: jak go kliknę to stanie się aktywny: Tak samo zrób u siebie z kompilatorem MVSC. Następnie wybierz wersje kompilatora / narzędzia na które chcesz zbudować program, u mnie np. zmieniłem na kompilator, który zbuduje mi program na RPi3 - Ty powinieneś tutaj wybrać MVSC, analogiczna sytuacja u mnie: Wtedy jak zbudujesz program to zostanie on zbudowany za pomocą wybranego kompilatora i na wybrane narzędzie. I wtedy możesz spróbować zrobić deploy na wersji zbudowanej przez MVSC.
  8. @zwora Na forum Qt użytkownik mumushuiding pisze: Tłumacząc to w translatorze i nieco poprawiając językowo mamy: Czyli teraz tak: jeśli podczas instalacji Qt wybrałeś kompilatory MinGW i MSVC jak w tym linku, to wystarczy że zmienisz projekt tak, aby budować za pomocą MSVC - albo zrobiłeś to na etapie kreatora projektu - wtedy musiałeś zaznaczyć oba kompilatory, albo możesz to zrobić w otwartym projekcie, u mnie to wygląda tak - mam aktywny kompilator GCC dla architektury x86 (mój PC), i aktywny kompilator GCC dla RPi3, żeby włączyć możliwość budowania na Androida muszę kliknąć któryś z nich powyżej tych opisanych przed chwilą (nie widać tego dobrze, ale są tam 3 różne kompilatory na tym zdjęciu): Następnie aby zmienić kompilator klikasz ikonkę komputera powyżej zielonego przycisku run i wybierasz MSVC, następnie deploy robisz jak poprzednio tylko tym razem musisz pamiętać aby użyć windeployqt dla MSVC: Jeśli podczas instalacji Qt NIE wybrałeś kompilatorów MinGW albo MSVC to musisz odpalić narzędzie Qt Maintenance Tool i odpowiedni kompilator doinstalować do Twojej wersji Qt, a następnie jak wyżej.
  9. @zwora Jedyna rozbieżność jaką widzę a potencjalnie może mieć znaczenie to Twoje punkty 3-5 -> po zbudowaniu projektu nie musisz nic nigdzie (na tym etapie) kopiować ręcznie. Szukasz folderu gdzie został zbudowany projekt (skąd wiem, że to jest ten katalog? a no stąd że jak spróbuje uruchomić program.exe który się tam znajduje to dostanę masę komunikatów o brakujących plikach dll - i to własnie ten katalog podaję dla windeployqt). I teraz nie kopiujesz niczego z niego ani do niego, tylko po prostu wywołujesz na tym katalogu windeployqt jak w instrukcji. Istnieje szansa ze windeployqt oprócz analizowania twojej binarki (.exe) analizuje też pozostałe pliki w tym katalogu - a Ty z katalogu gdzie zbudowałeś program skopiowałeś tylko binarkę - dlatego może występować Twój problem. Podsumowując po punkcie 2. wywołaj windeployqt. Jeśli to również nie zadziała to pozostaje Ci szukanie problemu w sieci np. tutaj. Różnica jest taka, że wersja Debug będzie wolniejsza i końcowy program (całościowo) dużo większy - przez dołączenie całego bagażu jaki niesie wersja debug. Dlatego jak dystrybuujemy programy to budujemy je w trybie Release. Jak sprawdzisz różnice w wielkości plików .dll które zostały dołączone dla obu trybów to różnica w rozmiarze może być na poziomu setek MB. Jeśli masz wersję starszą niż 5.15 to nie powinno to mieć żadnego znaczenia. Ja cały czas korzystam z wersji open source. Natomiast od wersji Qt 5.15 nastąpiły pewne zmiany, ale raczej nie powinno to mieć wpływu.
  10. @konx8 Odpalając VSC i PlatformIO podczas tworzenia nowego projektu i wpisując w polu Board "2560" mam trzy opcje: Zakładam, że jedna z tych trzech opcji powinna ostatecznie zadziałać. PlatformIO nie robi wiele więcej niż samo Arduino i prawdopodobnie ArduinoIDE i PlatformIO korzystają z tych samych toolchainów. W razie problemów z toolchainami, które dostarcza plugin PlatformIO możesz przekopiować zawartość toolchainu dostarczonego z ArduinoIDE do katalogu w którym PlatformIO umieściło ten, z którego korzysta - nie wiem czy zadziała przekopiowanie 1:1 do ale na 90% powinno.
  11. Wyręczę @koza_yo, problem był bardzo prosty, ale zdradliwy. Mianowicie @koza_yo stworzył swój projekt powiedzmy o nazwie X, do którego przekopiował zawartość plików z projektu dołączonego do artykułu czyli projektu o nazwie Qt_Forbot_BluetoothCommunication. Przekopiował również zawartość pliku .pro, w którym znajdowała się linijka "TARGET = Qt_Forbot_BluetoothCommunication". Czyli w projekcie X chciał zbudować program dla projektu Qt_Forbot_BluetoothCommunication przez co system budowania rzucał błędami, prawdopodobnie żeby zadziałało, należałoby zmienić linię (tą z TARGET) na "TARGET = X". Aby uniknąć takich błędów, poprawnym podejściem byłoby skopiowanie tylko zawartości plików mainwindow.h/cpp pod warunkiem, że nazywałyby się tak samo w obu projektach, a plik .pro zostawić nietknięty. Natomiast tworząc nowy projekt korzystając z nowszych wersji Qt (nie wiem konkretnie od której, ale w moim przypadku przy wersji 5.12.6) w pliku pro nie znajdziemy już definicji TARGET, jest ona prawdopodobnie zapożyczana z nazwy pliku .pro.
  12. Ok, spokojnie. Generalnie Qt składa się z wielu różnych modułów, np. QtCore, QtBluetooth, QtNetwork itp. I teraz w ramach każdego modułu masz X różnych klas, np. w ramach modułu QtBluetooth wspomnianą QBluetoothDeviceDiscoveryAgent. I teraz jak wiesz ze chcesz skorzystać w takiej klasy musisz najpierw poinformować system budowania żeby dołączył dany moduł, robisz to właśnie w pliku o nazwie projektu z rozszerzeniem .pro - (nazwaProjektu.pro). Jak otworzysz ten plik to masz np.: QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets I teraz chcąc skorzystać z klasy QBluetoothDeviceDiscoveryAgent to w dokumentacji tej klasy masz taką tabelkę gdzie znajdziesz (chodzi o wiersz z qmake) Header: #include <QBluetoothDeviceDiscoveryAgent> qmake: QT += bluetooth Since: Qt 5.2 Inherits: QObject Czyli wiesz, że musisz w pliku .pro dopisać: QT += core gui bluetooth I teraz jeśli chodzi o pliki tej klasy, to nie musisz ich brać znikąd, bo one będą już w postaci skompilowanych bibliotek dostarczone wraz z zainstalowaniem Qt, więc jedyne co robisz, to w pliku gdzie chcesz skorzystać z tej klasy np. w mainwindow.h, dodajesz: #include <QBluetoothDeviceDiscoveryAgent> Dokładnie tak samo było to pokazane w 4 części. Dla szybkiego testu, pobierz gotowy kod z 4 części i spróbuj go zbudować. Jeśli nadal będziesz miał problemy, to podaj jak najwięcej informacji i będziemy szukać.
  13. Z informacji, które podałeś strzelam, że chodzi o brak #include <QBluetoothDeviceDiscoveryAgent> w pliku mainwindow.h. Jeśli masz dołączoną klasę, a nadal masz taki błąd to może w pliku .pro brakuje QT += bluetooth.
  14. W takim razie, jeśli chcesz zbudować drona od totalnego zera - programowanie obsługi silników, komunikacji czy kontrolera lotu etc. - to możesz zacząć od tych filmów: dron na ATmedze 328p (w filmach płytka Arduino Uno): https://www.youtube.com/watch?v=XFxqFQwRumc&list=PL0K4VDicBzsibZqfa42DVxC8CGCMB7G2G dron na STM32F103 (w filmach płytka Blue Pill): https://www.youtube.com/watch?v=EeJeSE_5rns&list=PL0K4VDicBzshwCpUHzIB6hOLQVkDFHbxC Natomiast, jeśli chcesz kupić klocki i złożyć je w drona to najlepiej rozejrzeć się za gotowymi kontrolerami lotu i nie bawić się implementację własnych, a finalnie je tylko skonfigurować/dostroić. W tej pierwszej opcji można się bardzo dużo nauczyć, ale niekoniecznie musi się udać, w drugiej z kolei będziesz miał działającą zabawkę.
  15. Podstawy podstaw JS (zmienne, funkcje, operacje na stringach i tablicach, obiekty w JS) na pewno będą przydatne, pozostałe problemy można rozwiązywać w trakcie nauki. Znajomość HTML i CSS nie jest wymagana. Za dokumentacją Qt: Dobre wprowadzenie do QML znajdziemy w dokumentacji. I to powinno w zupełności wystarczyć.
  16. @Shog A więc po kolei: Nie jest wymagane. Rok temu, gdy pisałem części 1-4 używałem "this", teraz używam go tylko tam, gdzie jest konieczny albo w definicjach konstruktorów. Natomiast stosowanie o które pytasz - do metod i zmiennych wewnątrz klasy - to już powiedziałbym, że to kwestia gustu albo wytycznych coding rules. Tak. Możesz to sprawdzić w dokumentacji at(index), [index]. Zwróć uwagę, że operator [] jest dwukrotnie przeładowany w tej klasie. Zdecydowanie tak. Części 1--4 powstały prawie rok temu, teraz pewnie napisałbym większość inaczej/lepiej. Nie mam nic pod ręką co bym mógł polecić z literatury, może ktoś inny poleci coś wartego przeczytania. Ale zachęcam do własnych eksperymentów i rozpoczęcia od prostej rzeczy czyli założenia, że mamy bufor nadawczy (txBuffer) i odbiorczy (rxBuffer) i nasz pakiet składa się z kilku bajtów: Preambuły (np. 'Q', 't'), Rozmiaru, Komendy i na początek 4 bajtów danych. I założenia, że rozmiar pakietu jest stały. Ramka będzie wtedy wyglądać tak: +----------------------+---------+---------+---------+ | Preambuła ('Q', 't') | Rozmiar | Komenda | Dane | +----------------------+---------+---------+---------+ | 2 bajty | 1 bajt | 1 bajt | 4 bajty | +----------------------+---------+---------+---------+ I teraz zakładając, że chcemy przesłać pakiet z numerem komendy = 1 i 4 bajty danych postaci 0xAA5500FF - to pakiet o rozmiarze 4 bajtów (licząc tylko dane) będzie miał następujące wartości: +-----+-----+---+---+------+------+------+------+ | 'Q' | 't' | 4 | 1 | 0xAA | 0x55 | 0x00 | 0xFF | +-----+-----+---+---+------+------+------+------+ Preambułę specjalnie zapisałem w postaci znaków ASCII (w formacie heksadecymalnym miałaby wartości 0x51 oraz 0x74), a Rozmiar i Komendę zapisałem w formacie decymalnym (w formacie heksadecymalnym miały by wartości odpowiednio 0x04 i 0x01). I teraz odebrane bajty "zapisujesz" w buforze rxBuffer robiąc, to w ten sposób, że wpisujesz na sztywno (oczywiście na czas rozwoju) w ten bufor wartości z tabelki powyżej. I teraz piszesz sobie obsługę analizy bufora odbiorczego w poszukiwaniu początku pakietu - preambuły i następnie rozkodowania odnalezionego pakietu w buforze - czyli określenia jaki rozmiar ma pakiet, jaką przesyła komendę i jakie dane. Możesz to zrobić na wiele sposobów, możesz sobie stworzyć strukturę, która będzie reprezentować pakiet etc. Możesz też tutaj wykorzystać np. maszyny stanów - masz pełną dowolność w tym jak osiągniesz zamierzony efekt. ... I dalej musisz wziąć pod uwagę, takie czynniki jak to, że możesz odebrać kilka pakietów - jeden po drugim, albo odebrać kilka różnych - znowu wpisując na sztywno różne kombinacje danych do bufora odbiorczego - rozszerzając kod analizy pakietu. Kolejno będziesz musiał rozszerzyć możliwości buforu odbiorczego na bufor w postaci bufora kołowego, tak żeby nowe dane "doklejać" do tych które odebrałeś wcześniej i nadpisywać, te które zostały już przetworzone. Co wiąże się z rozszerzeniem funkcjonalności analizy bufora odbiorczego i wzięcia pod uwagę, że tym razem korzystamy z buforu kołowego - znowu wpisując na sztywno różne kombinacje danych do bufora odbiorczego, ale tym razem zakładając, że na ostatnim indeksie buforu znajduje się np. pierwszy bajt preambuły, a kolejna część pakietu na indeksie 0 buforu. ... Następnie musisz wziąć pod uwagę, że możesz odebrać "uszkodzony" pakiet np. zamiast 0xAA odebrać 0xEA, dlatego będziesz musiał dodać kilka kolejnych bajtów do ramki - czyli obliczoną wartość CRC dla pakietu i sprawdzać tym samym integralność danych. Czyli odczytaną wartość CRC (tą którą policzył układ, który wysłał dane) porównujesz z obliczoną wartością CRC dla bajtów odebranego pakietu (czyli odebrałeś te dane i teraz "u siebie" liczysz dla nich wartość CRC) - jeśli jest taka sama, oznacza, że dane, które odebrałeś nie są uszkodzone. +----------------------+---------+---------+---------+-----------------+ | Preambuła ('Q', 't') | Rozmiar | Komenda | Dane | CRC (np. CRC16) | +----------------------+---------+---------+---------+-----------------+ | 2 bajty | 1 bajt | 1 bajt | 4 bajty | 2 bajty | +----------------------+---------+---------+---------+-----------------+ Wartość CRC obliczana jest tutaj dla pól Preambuły, Rozmiaru, Komendy i Danych. Tutaj możesz spojrzeć na przykłady implementacji obliczania CRC. Czyli kolejny raz, będziesz musiał rozszerzyć analizę odebranych danych i ramki pakietu. ... Następnie musisz sobie napisać kod strony nadawczej i formowania pakietów (wraz z obliczaniem CRC itp). I faktyczne wysyłanie danych z bufora nadawczego i faktyczne odbieranie danych w buforze odbiorczym (co możesz potrzebować gdzieś wcześniej) - tak, aby pozbyć się tego ręcznego wpisywania danych w bufor i móc faktycznie skorzystać z napisanego protokołu. ... Następnie możesz dowolnie rozszerzać możliwości protokołu np. przez wprowadzenie zmiennego rozmiaru danych, czy gotowe funkcje/metody do tworzenia określonych pakietów, czy np. przesyłania danych w postaci typów uint16_t czy np. floatów - co wymaga np. użycia memcpy i tak dalej i tak dalej.
  17. @Wrona W samym błędzie masz podpowiedź co robisz źle, podajesz katalog w którym nie ma pliku wynikowego (.exe). Sprawdź w QtCreatorze gdzie jest katalog build twojego projektu (przycisk Projects i tam szukasz tego katalogu) - pisałeś, że jak klikałeś .exe to pojawiały się komunikaty o brakujących dll-kach, no to właśnie to jest ten katalog i jego musisz podać dla windeployqt.
  18. @Wrona dobrze, że o to zapytałeś bo to jest klasyczny problem, z którym spotykają się ludzie, gdy chcą dystrybuować swój program napisany w Qt. QtCreator jak uruchamia naszą aplikację to zapewnia, że wszystkie biblioteki DLL są odpowiednio podlinkowane. Jak chcemy uruchomić program z folderu to dostajemy właśnie komunikaty o braku dll-ek. Dla wszystkich zainteresowanych dystrybucją programów napisanych w Qt: Generalne uwagi: Najlepiej korzystać z gotowych narzędzi do dystrybucji, gdy w projekcie mamy masę plików np. qml, plików tłumaczeń, plików multimedialnych lub innych plików i korzystamy z wielu bibliotek Qt, to te narzędzia zadbają, o to aby te wszystkie pliki i biblioteki znalazły się w katalogu z naszym programem. Podczas budowania aplikacji przeznaczonej do dystrybucji, to pamiętajmy o tym, aby zbudować aplikację w trybie Release. Po użyciu narzędzia do dystrybucji, dobrze jest wyczyścić projekt w celu pozbycia się zbędnych plików w katalogu, gdzie została zbudowana nasza aplikacja. Wynikowy program (i wszystkie pozostałe, konieczne pliki) gotowy do dystrybucji znajdziemy w katalogu "build" (jego lokalizację znajdziemy w QtCreatorze pod przyciskiem Projekty na pasku po lewej stronie, w polu Katalog wersji). Wtedy dystrybuujemy cały katalog (Windows, Linux) lub plik .apk (Android). Windows: Korzystamy z narzędzia windeployqt, znajduje się ono w katalogu gdzie zainstalowaliśmy Qt i kolejno w katalogu odpowiedniego kompilatora. Musimy zwrócić uwagę jakim kompilatorem budujemy naszą aplikację, standardowo będzie to pewnie MinGW, ale istotne jest też czy budujemy aplikację 32 bitową czy 64 bitową, jak w QtCreatorze budujemy 64 bitową to przy deploy'u używamy narzędzia windeployqt z katalogu kompilatora 64 bitowego. Przykładowo w QtCreatorze używam kompilatora MinGW 64bit, szukam katalogu gdzie zainstalowałem Qt - u mnie przykładowo: D:\Dev\Qt\5.12.6\mingw73_64\bin tam znajdziemy między innymi narzędzie windeployqt (znajdują się tam też inne narzędzia), jak budowałbym 32bitową aplikację to używałbym windeployqt z katalogu ..\mingw73_32\bin\ Aby uruchomić narzędzie uruchamiamy konsolę Windows (cmd, albo powershell) i przechodzimy do katalogu z narzędziem windeployqt i wywołujemy komendą: dla projektu QtWidgets: windeployqt <path-to-app-binary> dla projektu QtQuick: windeployqt --qmldir <path-to-app-qml-files> <path-to-app-binary> Dla przykładu, katalog ze źródłami projektu mam w katalogu D:\Dev\Projects\TestDesktop natomiast katalog ze zbudowanym programem (katalog "build") mam w katalogu: D:\Dev\Projects\build-TestDesktop-Desktop_Qt_5_12_6_MinGW_64_bit-Release\release i zakładam, że buduję aplikację QtQuick kompilatorem MinGW 64bit oraz zakładam, że wcześniej znalazłem się w katalogu D:\Dev\Qt\5.12.6\mingw73_64\bin wykorzystując powershell'a to wywołanie będzie takie: .\windeployqt.exe --qmldir D:\Dev\Projects\TestDesktop D:\Dev\Projects\build-TestDesktop-Desktop_Qt_5_12_6_MinGW_64_bit-Release\release Następnie uruchamiam program (.exe) i patrzę jakich plików dll brakuje - windeployqt nie dodaje kilku plików np: libgcc_s_seh-1.dll libwinpthread-1.dll libstdc++-6.dll Brakujące pliki znajdują się w folderze z narzędziem windeployqt czyli w przykładzie: D:\Dev\Qt\5.12.6\mingw73_64\bin. Należy je skopiować do folderu z programem (.exe), następnie program powinien już uruchamiać się bez problemu. I dopiero cały katalog D:\Dev\...\release możemy już dystrybuować wraz z naszym programem. Więcej informacji znajdziemy w dokumentacji. Linux (Ubuntu): Na tym samym komputerze, nie musimy robić nic z bibliotekami linkowanymi dynamicznie. Możemy program uruchomić prosto z folderu build. Gdy chcemy przenieść program na inny komputer to możemy skorzystać z narzędzia linuxdeployqt lub zobaczyć co na ten temat mówi dokumentacja. Android: QtCreator tworzy wynikowy plik .apk, który ma dołączone wszystkie wymagane biblioteki, więc dystrybuujemy sam instalator w postaci pliki .apk. Plik ten znajdziemy w otchłani folderu build. Ostatnia najważniejsza rzecz, o której musimy pamiętać przy dystrybucji naszych programów to spełnienie wszystkich warunków licencji, z których korzystają wykorzystane przez nas biblioteki.
  19. Generalnie zmienić każde wystąpienie "MainWindow" na "Inne" - najlepiej użyć globalnego "zamień na" powinna być taka opcja w QtCreatorze, (możliwe, że w pliku .ui, też coś jest wykorzystane, nie pamiętam trzeba sprawdzić), zmienić prawdopodobnie nazwy plików mainwindow.h/cpp na inne.h/cpp, zmienić #include, które includują mainwindow.h na include inne.h/cpp. Może wtedy kompilacja się uda, jak nie to patrz co mówią błędy. Ostatecznie możesz stworzyć projekt od nowa z odpowiednią nazwą (ale to dużo więcej pracy).
  20. @Wrona Ok, należy zacząć od tego jak po stronie mikrokontrolera są wysyłane dane: czy a) jest to kilka paczek wysyłanych w określonych odstępach czasu na jedno kliknięcie wyślij czy b) jedna dłuższa paczka wysłana raz na jedno kliknięcie wyślij. Jeśli a) to musisz określić najdłuższy z tych odstępów załóżmy, że 200ms, to bezpiecznie po stronie programu ustalasz, że jak dane nie pojawiają się od ostatnich 250ms to oznacza, że transmisja się zakończyła i można odblokować przycisk. Jeśli opcja b) to pod warunkiem, że nic nie blokuje wysyłania paczki danych po stronie mikrokontolera i zaczyna on wysyłać dane natychmiast po odebraniu komendy z PC to możesz śmiało założyć jakiś krótki okres czasu, że np. po czasie 20ms (lub krótszym) po ostatnim odebranym bajcie możesz odblokować przycisk. I teraz po stronie aplikacji istotne są dwie rzeczy: 1) zablokowanie przycisku przy kliknięciu, 2) obsługa timera w slocie odbierania danych. Czyli klikasz przycisk -> zablokuj go i uruchom timer z odpowiednim interwałem dostosowanym do twojego układu. Następnie w slocie odbierania danych resetujesz timer - dlaczego? Dlatego, że do tego slotu możesz wejść kilka razy, na jedną paczkę danych - i nie obchodzi Cię ile razy tam wejdziesz, tylko to, żeby resetować timer dopóki dane są odbierane - i teraz jak wszystkie dane zostaną odebrane to już slot odbioru danych nie będzie wywoływany, a tym samym nie zrestujesz timera, który ostatecznie wyemituje sygnał triggered() w którym odblokujesz przycisk. (Natomiast najlepszą opcją było by tu wprowadzenie pakietowej transmisji, gdzie odebranie całego pakietu z danymi było by równoznaczne z zakończeniem transmisji, lub po prostu wysyłanie pakietu o jej zakończeniu.)
  21. Jak chcesz zablokować przycisk na jakiś określony czas to użyj klasy QTimer i stałego interwału, w dokumentacji, w opisie masz sposób użycia. Przycisk ma możliwość ustawienia opcji enabled. Czyli enabled = true - przycisk można klikać, enabled = false - przycisku nie możesz kliknąć (na interfejsie będzie szary). Sposób działania może być taki: przy kliknięciu wyślij blokujesz przycisk za pomocą setEnabled(false), uruchamiasz w tym samym czasie timer, gdy timer wyemituje sygnał triggered() to w slocie jego obsługi odblokowujesz przycisk przez setEnabled(true). Druga opcja to znowu zablokowanie przycisku w momencie jego kliknięcia i uruchomienie timera 5 sekundowego tak jak napisałeś (lub o innym odpowiednim interwale) i resetowanie go w slocie odbioru danych przez wywołanie metody start() - zresetuje to timer. Gdy dane będą odbierane to timer będzie resetowany i przycisk nadal będzie zablokowany, natomiast jak skończy się transmisja to po 5 sekundach timer wyemituje sygnał (bo już nic nie będzie go resetować), następnie w slocie jego obsługi możesz odblokować przycisk co umożliwi ponowne użycie przycisku.
  22. Wzięte z półki, raczej na pewno nie zadziałają, przynajmniej nie od razu. Arduino to od dawna już nie tylko płytki i biblioteki ale ogromny framework jak inne, gdzie masz setki różnych interfejsów i określonych API. Jeśli twój procesor ma wsparcie Arduino (ktoś napisał drivery), to po dołączeniu wszystkich zależności i bibliotek do peryferiów, które ta konkretna biblioteka potrzebuje raczej powinno ostatecznie zadziałać. Tylko właśnie problem w tym, że tych zależności może być sporo, które mogą wymagać kolejnych. Inna sprawa to fakt, że większość z tych bibliotek jest napisana w C++.
  23. Jak ma być zaawansowanie, ładnie i nowocześnie to ja polecam C++ i framework Qt, a konkretnie technologie QtQuick i QML do budowy interfejsów, a C++ zostaje na cześć bacekend'ową. Polecam Ci wpisać w wyszukiwarkę "built with qt" gdzie znajdziesz studium przypadków użycia Qt w komercyjnych projektach np. https://www.qt.io/ulstein-built-with-qt. Sam na co dzień korzystam z tych technologii i szczerze mówiąc nigdy nie pomyślałem o próbie poszukania czegoś innego. Nie mam dużego doświadczenia ze wspomnianym GTK, ale uważam że wykorzystanie Qt jest znacznie wygodniejsze. Aktualnie pracujemy z @Treker nad kontynuacją kursu Qt i właśnie wszystko nowe (dotyczące interfejsu) będzie oparte w 95% na QtQuick i QML. Więc sama będziesz mogła ocenić czy to jest to czego oczekujesz. Inną, dopiero rosnącą alternatywą jest język Dart i framework Flutter. Flutter to takie cross platformowe Qt stworzone z myślą o urządzeniach mobilnych ale nie tylko, które prawdopodobnie zagarnie część rynku.
  24. Musisz po prostu dodać kontrolkę do wprowadzania tekstu np. https://doc.qt.io/qt-5/qlineedit.html i w niej wpisywać imię badanego, której zawartość możesz na jakiś przycisk dodać do okna logów i/lub wysłać za pomocą metody, która została przedstawiona w artykule. Podałem Ci w poprzedniej wiadomości: "QTextEdit daje Ci dwie metody: toPlainText() i toHtml() obie zwracają QString'a", czyli biorąc kod z artykułu ui->textEditLogs->toPlainText(); i z tym robisz już to co w przykładzie z zapisem do pliku. I tak jak napisał @atMegaTona niestety, ale bez odpowiedniej wiedzy C++ i podstaw OOP nie zrobisz dużych postępów i nie będziesz w stanie dobrze wykorzystać Qt. Nie wiem jaką Ty preferujesz metodę uczenia, ale tutaj masz darmowy kurs od Johna Purcella do podstaw C++ (składnia, podstawy programowania obiektowego, dziedziczenie, zarządzanie pamięcią itp). Pomijając projekt na końcu kursu (5h) i podstawy (1h) zostaje około 12 godzin, który robiąc na przyspieszeniu zajmie Ci około tygodnia poświęcając ~1h dziennie.
  25. Cześć @Wrona Metoda MainWindow::sendMessageToDevice(QString message) właśnie zapewnia, Ci taką funkcjonalność, mamy na sztywno w kodzie: this->sendMessageToDevice("1"); a możesz zrobić w slocie pod dowolnym przyciskiem (generalnie możesz tam wysłać to co chcesz): this->sendMessageToDevice("Mateusz"); wtedy powinieneś po drugiej stronie odebrać cały string. Okej, to można zrobić na wiele sposobów w zależności od celu jaki chcesz osiągnąć, chyba najprostszy moim zdaniem to zapisanie zawartości okna z logami do pliku. QTextEdit daje Ci dwie metody: toPlainText() i toHtml() obie zwracają QString'a. W twoim przypadku chyba odpowiedniejsza będzie toPlainText(), wtedy używając klasy QFile, możesz takiego QStringa, wcześniej konwertując do QByteArray zapisać do pliku, przykład poniżej: #include <QCoreApplication> #include <QFile> #include <QString> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QFile file("logs.txt"); // Uwaga! Plik będzie stworzony w katalogu, gdzie znajdują się pliki wynikowe programu (build dir) if(!file.open(QIODevice::WriteOnly)) { qDebug() << "Could not open!"; } else { const QString dataToWrite("Mateusz"); file.write(dataToWrite.toUtf8()); file.close(); } return a.exec(); } W twoim programie, musisz wydostać zawartość okna z logami i wykorzystać powyższe. Więcej info znajdziesz w dokumentacji.
×
×
  • Utwórz nowe...