PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : QTable QComboTableItem QCheckTableItem Doppelklicken?



Gartenzwerg
10-04-2004, 14:49
hi,
ich habe mit Hilfe von Qt eine QTable erstellt und wenn ich eine neue Reihe mit QCheckTableItems sowie QComboTableItems erstelle, wird beim ersten Klick nur das entsprechende Item markiert und beim zweiten Klick wird dann erst das entsprechende Item ausgewählt. Welche Ursache kann das haben?

Tschau Gartenzwerg

tuxipuxi
10-04-2004, 15:33
Hi,

die Beschreibung ist nicht so ganz verständlich.
Du hast also eine QTable mit Check und Combo Items und möchtest eine Combobox öffnen, die öffnet sich aber erst beim zweiten Klick?

Ich vermute mal, dass du mit dem ersten Klick die Zelle aktivierst und erst mit dem zweiten die Combobox aktivierst. Ist das ein Problem für dich?

Michael.

Gartenzwerg
10-04-2004, 15:40
hi,
ok blöde Erklärung, ich versuch es nochmal:
Das Problem tritt bei den ComboItems sowie den CheckItems auf.
Bei den ComboItems:
Reihe wird erstellt -> Klick aufs ComboItem -> öffnet sich -> ich wähle einen Eintrag -> es schließt sich und zu sehen ist wieder nur eine leere Combobox -> erneuter Klick -> öffnet sich -> erneute Eintragswahl -> Eintrag ist gewählt
Von nun an funktioniert es wie gewünscht, jedesmal wenn ich einen Eintrag auswähle, bleibt dieser bestehen
Bei den CheckItems:
Reihe wird erstellt -> Klick aufs CheckItem -> Hintergrund des Items färbt sich kurz -> aber keine Statusveränderung -> erneuterer Klick -> Status ändert sich
Von nun an kann man wieder mit einem Klick den Status ändern.
Dieses Phänomen tritt auch immer nur nach dem ersten Klick auf die Reihe auf. Wieso?

Hoffe ich habe mich jetzt besser ausgedrückt.

Tschau Gartenzwerg

Gartenzwerg
10-04-2004, 16:17
hi,
ok, ich konnte das Problem weitereingrenzen:
Es liegt irgendwie an folgenden zwei Funktionen. Immer wenn in die letzte Reihe der Tabelle geschrieben wird, erstelle ich eine neue Reihe. Doch diese scheint den Status der Combo- und der CheckItems aus der vorherigen Reihe zu "vergessen". Die Funktionen:


// Funktion zum Einfügen einer neuen Reihe:
void CategoryTable::InsertRow(int prev_row)
{
insertRows(prev_row, 1);

for(int i=0; i<numCols(); ++i)
{
// Ist die entsprechende Commonbox eine Combobox?
if(mCategory.GetCommonboxIdentity(i)==Commonbox::C OMBOBOX)
{
QStringList list=mCategory.GetCommonboxContent(i);
list.insert(list.begin(), 1, "");
setItem(prev_row, i, new QComboTableItem(this, list));
}
// Ist die entsprechende Commonbox eine Checkbox?
else if(mCategory.GetCommonboxIdentity(i)==Commonbox::C HECKBOX)
{
QString content=mCategory.GetCommonboxContent(i).join("");
QCheckTableItem *ctItem=new QCheckTableItem(this, "");

if(content=="CHECKED"||content=="checked"||content=="Checked")
{
ctItem->setChecked(true);
}
else
{
ctItem->setChecked(false);
}

setItem(prev_row, i, ctItem);
}
}
}

// Slot, der aufgerufen wird, wenn sich Werte einer Zelle ändern
void CategoryTable::DataChangedSlot(int row, int col)
{
QString Text="";

// Ist die entsprechende Commonbox eine Checkbox?
if(mCategory.GetCommonboxIdentity(col)==Commonbox: :CHECKBOX)
{
QTableItem *Item=item(row, col);

// Ist QTableItem eine QCheckbox?
if(Item->rtti()==2)
{
// QCheckTableItem erstellen
QCheckTableItem *citem = dynamic_cast<QCheckTableItem * > (Item);

// Zustand festellen und in Text umwandeln
if(citem->isChecked())
{
Text = "checked";
}
else
{
Text = "free";
}
}
}
else
{
Text=text(row, col);
}

// wenn die Zelle nicht leer ist und es sich um die letzte Zeile handelt,
// muss eine neue Zeile angehängen werden
if((!Text.isEmpty())&&(row==numRows()-1))
{
InsertRow(numRows());
}
}

Was verursacht diesen Effekt?

Tschau Gartenzwerg

anda_skoa
13-04-2004, 18:18
Kannst du mal über einen Debugoutput nachsehen, ob der Slot schon beim ersten Auswählen aufgerufen wird?

Ciao,
_

Gartenzwerg
13-04-2004, 20:54
hi,
ja der Slot wird immer korrekt aufgerufen. Habe ihn jetzt mal etwas verändert:


void CategoryTable:: DataChangedSlot(int row, int col)
{
QString Text="";

// Ist die entsprechende Commonbox eine Checkbox?
if(mCategory.GetCommonboxIdentity(col)==Commonbox: :CHECKBOX)
{
QTableItem *Item=item(row, col);

// Ist QTableItem eine QCheckbox?
if(Item->rtti()==2)
{
// QCheckTableItem erstellen
QCheckTableItem *citem = dynamic_cast<QCheckTableItem * > (Item);

// Zustand festellen und in Text umwandeln
if(citem->isChecked())
{
Text = "checked";
cout << "ChangedDataSlot: Row: " << row << " Col: " << col << " Item: checked "<< endl;
}
else
{
Text = "free";
cout << "ChangedDataSlot: Row: " << row << " Col: " << col << " Item: free "<< endl;
}
}
}
else
{
Text=text(row, col);
}

// wenn die Zelle nicht leer ist und es sich um die letzte Zeile handelt,
// muss eine neue Zeile angehängen werden
if((!Text.isEmpty())&&(row==numRows()-1))
{
InsertRow(numRows());
}

// nur zu Testzwecken:
// eigenartiges Ergebnis: nach Aufruf von InsertRow ist die Checkbox wieder free,
// wenn sie vorher checked war
if(mCategory.GetCommonboxIdentity(col)==Commonbox: :CHECKBOX)
{
QTableItem *Item=item(row, col);

// Ist QTableItem eine QCheckbox?
if(Item->rtti()==2)
{
// QCheckTableItem erstellen
QCheckTableItem *citem = dynamic_cast<QCheckTableItem * > (Item);

// Zustand festellen und in Text umwandeln
if(citem->isChecked())
{
cout << "ChangedDataSlot: Row: " << row << " Col: " << col << " Item: checked "<< endl;
}
else
{
cout<< "ChangedDataSlot: Row: " << row << " Col: " << col << " Item: free "<< endl;
}
}
}
}

Es scheint definitiv an dem InsertRow zu liegen, denn vorher ist die Checkbox als checked markiert und danach hat sie ihren Zustand "vergessen". Warum?

Tschau Gartenzwerg

Gartenzwerg
14-04-2004, 17:16
hi,
ich könnte nun ja, da ich vor InsertRow sowieso den Status abfrage diesen nach InsertRow wieder herstellen. Das ist sicher nicht im Sinne des Erfinders aber funktionstüchtig. Hat nicht irgendjemand eine Idee, wie man das anders beheben kann?

Tschau Gartenzwerg

anda_skoa
14-04-2004, 19:38
Vielleicht löst das InserRow ein Signal aus, auf das du reagierst und dass dann den Status ändert

Ciao,
_

Gartenzwerg
14-04-2004, 20:26
hi,
die einzigen Signale, die ich selbst behandele sind folgende:


QObject::connect(this, SIGNAL(contextMenuRequested(int, int, const QPoint &)), this,
SLOT(OpenPopupMenu(int, int, const QPoint &)));
QObject::connect(this, SIGNAL(valueChanged(int, int)), this, SLOT(DataChangedSlot(int, int)));
QObject::connect(this, SIGNAL(currentChanged(int, int)), this, SLOT(CurrentChangedSlot(int, int)));

Außer dem Behandeln von valueChanged(int,int) dürfte da nichts die Checkbox beeinflussen und in DataChangedSlot(int, int) rufe ich insertRow auf und das löscht mir dir Zustände. Wie kann ich das beheben? Langsam dreh ich durch. Woran liegt das? :mad:

Tschau Gartenzwerg

Gartenzwerg
17-04-2004, 17:42
hi,
hab den Fehler jetzt wie folgt umgangen:


void CategoryTable::DataChangedSlot(int row, int col)
{
QString Text="";

// Ist die entsprechende Commonbox eine Checkbox?
if(mCategory.GetCommonboxIdentity(col)==Commonbox: :CHECKBOX)
{
QTableItem *Item=item(row, col);

// Ist QTableItem eine QCheckbox?
if(Item->rtti()==2)
{
// QCheckTableItem erstellen
QCheckTableItem *citem = dynamic_cast<QCheckTableItem * > (Item);

// Zustand festellen und in Text umwandeln
if(citem->isChecked())
{
Text = "checked";
}
else
{
Text = "free";
}
}
}
else
{
Text=text(row, col);
}

// wenn die Zelle nicht leer ist und es sich um die letzte Zeile handelt,
// muss eine neue Zeile angehängen werden
if((!Text.isEmpty())&&(row==numRows()-1))
{
InsertRow(numRows());

// eigenartiges Ergebnis: nach Aufruf von InsertRow ist die Checkbox wieder free, wenn sie vorher checked war
// deshalb diese zusätzlich Konstruktion
if(mCategory.GetCommonboxIdentity(col)==Commonbox: :CHECKBOX)
{
QTableItem *Item=item(row, col);

// Ist QTableItem eine QCheckbox?
if(Item->rtti()==2)
{
// QCheckTableItem erstellen
QCheckTableItem *citem = dynamic_cast<QCheckTableItem * > (Item);

// TODO: nicht sehr schön, aber erstmal funktionsfähig - warte noch auf Lösung
if(Text=="checked")
{
citem->setChecked(true);
}
else
{
citem->setChecked(false);
}
}
}
}
}

Weiß jemand eine elegantere Lösung o.ä.?

Tschau Gartenzwerg

anda_skoa
17-04-2004, 18:27
Vielleicht ist es einfach eine Folge des Tableupdates nach dem Hinzufügen.



setUpdatesEnabled(false)
InsertRow
setUpdatesEnabled(true);

könnte dann vielleicht helfen.

Ciao,
_

Gartenzwerg
17-04-2004, 18:51
setUpdatesEnabled(false)
InsertRow
setUpdatesEnabled(true);

behebt das Problem leider nicht.

Tschau Gartenzwerg