PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : QTimer refresh bringt Probleme



doitux
23-11-2004, 21:26
Hallo Leute

Ich sitze jetzt schon seit einer woche an diese Kopfnuss und hoffe mal wieder auf einen Denkanstoß von euch.
Es geht um dieses Programm --> http://umn.dl.sourceforge.net/sourceforge/quideorec/quideorec-0.2.tar.gz

Mit der Funktion liste_aufbauen() wird das /tmp Verzeichnis nach zuvor generierten Shell-Scripts durchsucht, die Dateinamen zerschnippelt und die Schnipsel in eine QListView eingetragen. mit der Funktion remove_file() wird ein markiertes QListViewItem und die dazugehörige /tmp/script-datei über den Button "löschen" gelöscht. Damit das Programm nicht mit einem Speicherzugriffsfehler endet wenn man den "löschen" Button ohne ein markiertes QListViewItem drückt hab ich in der Funktion liste_aufbauen() am Ende immer das erste QListViewItem in der QListView markieren lassen.

Das Problem ist folgendes. Jetzt wollte ich die Funktion liste_aufbauen() über einen QTimer jede Sekunde neu aufrufen. Wenn ich aber nun mit der Maus ein QListViewItem in einer Liste mit mehreren Items markiere wird die Markierung immer nach einer Sekunde wieder auf das erste Item gesetzt.

Jetzt ist die Frage was kann man machen um dieses Verhalten zu umgehen. Ich hab schon überlegt den QTimer einfach auf 5 Sekunden oder höher zu setzen damit genug Zeit bleibt um ein Item zu markieren und den löschen-Button zu klicken. Das kommt mir aber reichlich quick&dirty vor. Hat jemand noch ne andere Idee?

Vielen Dank schon mal für Eure Tips.
Gruß
Felix

p.s. wer das Programm mal testen will --> einfach "qmake, make und make install" machen ;)

peschmae
23-11-2004, 21:44
Wie wärs wenn du in dem Slot der mit dem Löschen-Button verknüpft ist einfach testest ob nicht etwa ein Item der Liste ausgewählt ist?
Oder einfach das Item von
QListView::selectedItem ()
nehmen, das ist 0 wenn leer.

Oder hab ich da was falsch verstanden?

MfG Peschmä

doitux
23-11-2004, 23:30
stimmt. Um den Speicherzugriffsfehler zu verhindern werd ich das auf jeden Fall mit einbauen.
Ich hab jetzt aber leider auch feststellen müssen, dass jedes Mal wenn ich die funktion liste_aufbauen aufrufe, also die Liste neu aufbaue, die Markierung gelöscht wird. Sie wird jetzt nicht mehr auf das erste Item gesetzt (das hab ich rausgenommen) aber sie wird einfach gelöscht.

Ich hab schon nach einer Möglichkeit gesucht, mit der man die Position des markierten Items zwischenspeichern kann. Mit ItemPos() kann man zwar die Position als int zwischenspeichern. Aber ich weiß nicht wie man die das Item an genau dieser Stelle später wieder markiert.
Oder gibt es dafür noch eine viel einfachere Lösung?

anda_skoa
24-11-2004, 02:03
Damit das Programm nicht mit einem Speicherzugriffsfehler endet wenn man den "löschen" Button ohne ein markiertes QListViewItem drückt hab ich in der Funktion liste_aufbauen() am Ende immer das erste QListViewItem in der QListView markieren lassen.


Das klingt schwer nach Hack.
Wieso sollte es einen Speicherzugriffsfehler geben, wenn ein Button gedrückt wird?
Da ist sicher was im zugehörigen Slot nicht optimal, könntest du den vielleicht direkt posten?

Ciao,
_

doitux
24-11-2004, 09:17
Diese Funktion wird beim Button-löschen ausgeführt.


void Quideorec::remove_file()
{
QListViewItem* remove_item = listView1->selectedItem();
QString tmpcolumn1 = remove_item->text(1);
QString tmpcolumn2 = remove_item->text(2);
QString tmpcolumn3 = remove_item->text(3);
QString tmpcolumn4 = remove_item->text(4);
QString tmpcolumn5 = remove_item->text(5);
QString spc = "_";
QString start ="videorectimer";
QString rmfile = start+spc+tmpcolumn1+spc+tmpcolumn2+spc+tmpcolumn3 +spc+tmpcolumn4+spc+tmpcolumn5;
QFile rm_file;
QDir::setCurrent( "/tmp" );
rm_file.setName( rmfile );
rm_file.remove();

liste_aufbauen();
}

Da werd ich noch eine Prüfung einbauen ob eines der Item selected ist.

Was momentan aber viel nerviger ist:
Die Funktion liste_aufbauen() wird jede Sekunde aufgerufen. Damit wollte ich mir einen Liste-aktualisieren-Button ersparen. Nun wird aber bei jedem aktualisieren der Liste die aktuelle Markierung wieder gelöscht. Und ich weiß nicht wie ich die Markierungsposition abspeichern und nach liste_aufbauen() wieder an der gleichen Stelle wieder einfügen kann.


void Quideorec::liste_aufbauen()
{
listView1->clear();
dir = new QDir;
*dir = "/tmp" ;
tmpinhalt = new QStringList;
*tmpinhalt = dir->entryList( "videorectimer*" );
tmpinhalt->sort();
tmpinhalt->gres("videorectimer", "");

eintmpinhalt = new QStringList;
tmpit1 = new QStringList;
dateiitems = new int;
prodateiname = new int;
*dateiitems = 1;
*prodateiname = 1;

for ( QStringList::Iterator it1 = tmpinhalt->begin(); it1 != tmpinhalt->end(); ++it1 ) {

*eintmpinhalt = QStringList::split("_", (*it1));
QListViewItem* item = new QListViewItem(listView1);

QString number;
number.setNum(*prodateiname);
item->setText(0,number);
for ( QStringList::Iterator it2 = eintmpinhalt->begin(); it2 != eintmpinhalt->end(); ++it2 ) {

item->setText(*dateiitems,*it2);

*dateiitems = *dateiitems + 1;
if (*dateiitems>5) {*dateiitems=1;}
}
*prodateiname = *prodateiname + 1;
}

listView1->setAllColumnsShowFocus(TRUE);
listView1->setSelected(listView1->firstChild() ,TRUE);

if (listView1->childCount()==0)
pushButton1->setEnabled(false);
else
pushButton1->setEnabled(true);

}

pushButton1 ist der löschen-Button. Sorry wegen dem ganzen englisch-deutsch-Mix. Diese Funktionen stammen noch aus einer Zeit bevor ich das Kapitel saubere Programmierung gelesen habe ;) Wird aber alsbald bearbeitet.

anda_skoa
25-11-2004, 11:33
Diese Funktion wird beim Button-löschen ausgeführt.


void Quideorec::remove_file()
{
QListViewItem* remove_item = listView1->selectedItem();


Einfach nur prüfen, ob remove_item != 0 ist.



Die Funktion liste_aufbauen() wird jede Sekunde aufgerufen. Damit wollte ich mir einen Liste-aktualisieren-Button ersparen. Nun wird aber bei jedem aktualisieren der Liste die aktuelle Markierung wieder gelöscht. Und ich weiß nicht wie ich die Markierungsposition abspeichern und nach liste_aufbauen() wieder an der gleichen Stelle wieder einfügen kann.


Du arbeitest gern mit Pointern, hmm? :D

Ein paar Ideen:
- merk dir die Liste der vorhandenen Shellscripte. Wenn du beim Neueinlesen die selbe Liste bekommst, brauchst du den ListView nicht zu verändern

- wenn irgendeine Spalte des Views eindeutige Werte enthält, zb einen fortlaufenden Index oder den Dateinamen (Eindeutigkeit durch das Filesystem), dann merk die vor Löschung des Views diesen Wert aus dem selektiertem Item und selektiere dann das neue Item, das diesen Wert bekommt.

Ciao,
_

doitux
26-11-2004, 18:02
Du arbeitest gern mit Pointern, hmm? :D

ja ich mag die pfeile einfach lieber als die punkte ;)
nee quatsch. dieser teil des codes stammt aus einer zeit bevor ich gelernt habe dass man innerhalb einer klasse variablen funktionsübergreifend nutzen kann ohne sie jeder funktion einzeln übergeben zu müssen. diesem irrtum war ich lange erlegen ...
"wenn ich zeit hab" wird das überarbeitet.



- wenn irgendeine Spalte des Views eindeutige Werte enthält, zb einen fortlaufenden Index oder den Dateinamen (Eindeutigkeit durch das Filesystem), dann merk die vor Löschung des Views diesen Wert aus dem selektiertem Item und selektiere dann das neue Item, das diesen Wert bekommt.

Klasse! vielen dank dür diesen tip. das hat mir gefehlt.
Also nochmal: falls du mal irgendwann nach rostock ziehen solltest und ich immernoch da studiere ...

cu
doitux
_