QTableWidget - przycisk jako item

QTableWidget - przycisk jako item
grzesiek51114
grzesiek51114
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad 4 lata
  • Postów:2442
0

Dobry wieczór.

Od wczoraj męczę się z takim pomysłem: Mam w oknie programu obiekt typu QTableWidget. Do tego obiektu wczytuję sobie dane w postaci obiektów QTableWidgetItem.

Obiekt QTableWidget posiada na starcie programu pięć predefiniowanych kolumn oraz zero rzędów. Rzędy pojawiają się kiedy użytkownik użyje opcji wyszukiwania i coś znajdzie (nie ważne co, jakieś dane po prostu).

To wszystko bardzo ładnie działa, ponieważ obiekty typu QTableWidgetItem zawierają dane tekstowe, z którymi nic się nie robi tylko czyta z ekranu.

Ja chciałbym do rzędów, które się pojawią wczytać przyciski, tak żeby wyglądało to następująco:

Kopiuj
// Pionowe kreski reprezentują kolumny tabeli
Dane | Dane | Dane | Przycisk | Przycisk   // rząd nr 1

...

Dane | Dane | Dane | Przycisk | Przycisk   // rząd nr 'n'

// gdzie 'n' to liczba znalezionych przez użytkownika rzędów
// wg jakichś tam kryteriów.

Jak to zrobić w kodzie to wiem, bo robię sobie odpowiednio dużą dynamiczną tablicę obiektów klasy QPushButton i wklejam jej elementy do tabeli na zasadzie:

Kopiuj
this->ui->twWyniki->setCellWidget(0,4,&pb[0]); 
// gdzie obiekt pb[0] to obiekt typu QPushButton, a
// twWyniki to obiekt klasy QTableWidget.

// powoduje to wczytanie do rzędu nr '0', w kolumnie nr '5' przycisku nr [0] z ww tablicy.

Pytanie:
Jak napisać do tego sloty kiedy nie wiem jak duża będzie tak naprawdę tablica przycisków? Chcę żeby te przyciski wyświetlały nowe okno z rysunkiem pobranym z pliku jpg z dysku. Jak zaprogramować sloty do tego skoro liczba przycisków jest zmienna i zależy od ilości rzędów w tabeli wyszukiwania?

Pozdrawiam
Grzegorz

[EDIT]
Zapomniałem dopisać, że działa coś takiego:

Kopiuj
    for(int i = 0; i < 3; i++) // dla trzech przycisków
        connect(&pb[i],SIGNAL(clicked()),pb,SLOT(hide())); // przykładowy slot 'hide()'

tylko teraz chodzi o to, że chcę pojedynczy slot do każdego przycisku, który to slot będzie miał argument, będący ścieżką do jpg na dysku.
Jeżeli każdy przycisk otwiera plik o innej nazwie to musiałbym mieć i-tą ilość takich slotów - tutaj jest pies pogrzebany, bo nie ma sygnału typu clicked(QString tekst).
Pozwalałoby mi to na zdefiniowanie jednego slotu, gdzie ścieżka byłaby przekazywana przez tego stringa.

edytowany 5x, ostatnio: grzesiek51114
grzesiek51114
grzesiek51114
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad 4 lata
  • Postów:2442
0

Co wymyśliłem (specjalnie w osobnym poście):

  1. Definiuję sobie taki sygnał:
Kopiuj
 
signals:
    void clicked(QString tekst);
  1. I takie dwa sloty:
Kopiuj
 
void pbclicked(){ emit clicked("Grzegorz"); } // Zamias "Grzegorz" będzie ścieżka do feralnego pliku przypuśćmy.
void test(QString tekst){ this->ui->leTyp->setText(tekst); }; // wstawienie stringa do jakiegoś obiektu QLineEdit
  1. Na końcu robię takie połączenia:
Kopiuj
 
    for(int i = 0; i < 3; i++){
        connect(&pb[i],SIGNAL(clicked()),this,SLOT(pbclicked()));
        connect(this,SIGNAL(clicked(QString)),this,SLOT(test(QString)));
    }

To działa, ale nie wiem... może da się to zrobić jakoś ładniej?

MasterBLB
  • Rejestracja:około 19 lat
  • Ostatnio:12 dni
  • Lokalizacja:Warszawa
  • Postów:1454
0

Da się.
Na dzień dobry wszystkie te QStringi zdefiniuj jako const QString& dzięki czemu unikniesz kopiowania obiektów.


"Sugeruję wyobrazić sobie Słońce widziane z orbity Merkurego, a następnie dupę tej wielkości. W takiej właśnie dupie specjalista ma teksty o wspaniałej atmosferze, pracy pełnej wyzwań i tworzeniu innowacyjnych rozwiązań. Pracuje się po to, żeby zarabiać, a z resztą specjalista sobie poradzi we własnym zakresie, nawet jeśli firma mieści się w okopie na granicy obu Korei."
-somekind,
konkretny człowiek-konkretny przekaz :]
MarekR22
Moderator C/C++
  • Rejestracja:około 17 lat
  • Ostatnio:3 minuty
0

cały pomysł jest zły (najlepiej zawsze opisywać co chcesz uzyskać, a dopiero w drugim kroku opisać jak próbujesz to uzyskać).
Potrzebujesz delegata, który będzie tworzył przycisk dla danej komórki i zmieniał stan MODELU danych w momencie, gdy coś się ma zmienić.
Patrz:


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 4x, ostatnio: MarekR22
HO
Warto dodać, że proponowane w Twoim poście rozwiązania wymagałyby zastosowania QTableView zamiast QTableWidget.
grzesiek51114
grzesiek51114
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad 4 lata
  • Postów:2442
0

Dziękuję za odpowiedź. Z delegatami u mnie jeszcze jest ciężko. Jeszcze tego nie rozumiem ale wgryzę się w temat. Na razie wiem tylko tyle, że jest to coś takiego jak wskaźnik na funkcję :)

MarekR22
mylisz to z delegatami z C#.
grzesiek51114
grzesiek51114
To czym właściwie jest delegat w C++? Z przykładu, który mi wysłałeś wynika, że jest to klasa, która rysuje przycisk i nic więcej. Trochę tego nie rozumiem właśnie.
MarekR22
niestety słowo delegat jest różnie używane przez różne firmy: w .Net jest to wskaźnik na metodę obiektu (w użyciu bardzo podobne do sygnałów z Qt), w iOS są to wskaźniki na coś co implementuje określony protokół (interfejs), a tu to jest coś co odpowiada, za wygląd i zachowanie elementu widoku.
grzesiek51114
grzesiek51114
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad 4 lata
  • Postów:2442
0

Zrobiłem!

Nie robiłem do tego delegatów ale obszedłem to przez rzutowanie wskaźnika.
Do sygnału clicked() obiektu QPushButton zrobiłem slot

Kopiuj
void pbTabWcisniety()

o takim ciele:

Kopiuj
 
void OknoGlowne::pbTabWcisniety(){
    QPushButton *pb = qobject_cast<QPushButton *>(sender());
    pb->setText("TRAF!");
}

W tym momencie wskaźnik 'caller' wie, który przycisk został wciśnięty i o to mi chodziło, bo mogę już wykorzystać sobie jego nazwę do poparsowania sobie nazwy pliku z obrazkiem:)

Do tego taka realizacja połączeń (długość pętli oczywiście określona przez listę w programie i ilość przycisków w jednym rzędzie):

Kopiuj
for(int i = 0; i < this->lista.length(); i++){
    for(int j = 0; j < 2; j++){
        connect(&this->pbTab[i][j],SIGNAL(clicked()),this,SLOT(pbTabWcisniety()));
    }
}

Niestety nie rozumiem jeszcze delegatów i musiałem pogłówkować w trochę inny sposób.

Pozdrawiam
Grzegorz

edytowany 3x, ostatnio: grzesiek51114
HO
Na wszelki wypadek proponowałbym w slocie po użyciu castowania dodać if( pb ) a w nim operację na pb - gydyby się okazało że podepnie się slot pod nieodpowiedni obiekt.
grzesiek51114
grzesiek51114
Na pewno trzeba? Zwróć uwagę, że połączenie slot - sygnał gwarantuje, że senderem będzie właśnie push button. Chyba, że jest coś o czym nie wiem.:-)
HO
A gdy np. zmienisz pushbuttony na toolbuttony bo stwierdzisz że są fajniejsze i zapomnisz o castowaniu to w slocie wyląduje NULL i program zacznie się wykrzaczać. Nie ma gwarancji, że od razu będzie jasne gdzie i przez co jest naruszenie pamięci. Jeśli slot będzie miał if to jeśli będzie NULL wtedy nic się nie stanie. Duża szansa, że wpadnie się wtedy na pomysł by sprawdzić slot. Poza tym sprawdzenie wskaźnika czy jest poprawny jest po prostu standardem przyzwoitego kodowania - warto wyrobić sobie taki nawyk.
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)