Seite 1 von 1

Qt4.2.3 und ListView / QMouseEvent sowie QDirModel

Verfasst: 23. April 2007 11:58
von andy72
Habe ein Problem festgestellt, und weiss nicht, ob das am Qt liegt, oder ich einfach einen Fehler gemacht habe:

Habe eine einfache QListView im IconMode mit dem einem QAbstractListModel erstellt und wollte per connect() nun das Signal clicked(const QModelIndex &) vom QListView benutzen und mit einem eigenen Slot (const QModelIndex &) versehen. Das clicked() wird von der QListView nicht aufgerufen, jedoch wenn ich die QListView in eine eigene Klasse implementiere, das mousePressedEvent(QMouseEvent *e) abfange, und direkt an QListView::mousePressed(e) übergebe, wird das clicked()-Signal plötzlich ausgeführt. Hat Trolltech vergessen, das Ereignis zu implementieren, oder ist das in der QListView so vorgesehen ?

Das nächste Problem bezieht sich auf QDirModel und QIconProvider:
Übergibt man dem QDirModel einen neuen IconProvider, so geht das komischerweise auch nicht: QDirModel holt sich alle Icons aus dem QStyle, was mich nervt: das verhindert die Erweiterungsfähigkeit der Icons um nützliche Dinge wie zB XdgMime - Ich habe also derzeit ein neues QDirModel in Arbeit, das mit XdgMime zusammen passt ;)

LG
Andy

Verfasst: 23. April 2007 16:34
von caligano
Also bei mir wird das clicked-Signal ausgelöst:

Mal zum Testen was ganz simples:

main.cpp

Code: Alles auswählen

#include <QApplication>

#include "test.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    Test test;
    test.show();
    return app.exec();
}
test.h

Code: Alles auswählen

#ifndef TEST_H
#define TEST_H

#include <QWidget>

class QListView;
class QDirModel;


class Test : public QWidget
{
    Q_OBJECT

public:
    Test();

private slots:
    void click();
    

private:
   QListView *listView;
   QDirModel *model;
};

#endif
test.cpp

Code: Alles auswählen

#include <QtGui>

#include "test.h"

Test::Test()
{
    model = new QDirModel(this);
    listView = new QListView(this);
    listView->setModel(model);
    listView->resize(400, 400);
    connect(listView, SIGNAL(clicked (const QModelIndex&)), this, SLOT(click()));
}

void Test::click()
{
   QMessageBox::warning(this, "Test", "clicked()");
}

Verfasst: 23. April 2007 16:53
von andy72
Kann ich leider SO nicht nachvollziehen, da ich QListView ableiten musste: Ich hatte das Problem, dass ich unter Qt4.3.2 kein Model mit setModel() zuweisen konnte - Der Fehler war "QListView::setModel(const QAbstractListModel &) is protected" *kopfkratz*. Meine abgeleitete QListView weist eh ein merkwürdiges Verhalten auf: Ich kann ein Model zuweisen, aber es schaltet nicht mehr auf Deatils um, wenn ich das normale QDirModel nutze. Somit ist das ganze schon etwas verworren,dabei wollte ich nur einen FileExplorer programmieren :|

Verfasst: 23. April 2007 16:55
von caligano
Wenn du korrekt abgeleitet hast, sollte clicked ebenfalls ausgelöst werden; aber ohne Einsicht in den Quelltext kann man nur spekulieren...

Verfasst: 24. April 2007 10:25
von andy72
Habe die QListView so abgleitet:

class MyListView: public QListView {
}

also müssen mir alle Funktionen zur Verfügung stehen, die "öffentlich" sind. setModel(QAbstractItemModel &) aus QAbstractItemView ist auch public, jedoch meckert die QListView bei mir, dass die Funktion protected ist. Spielt auch keine Rolle, da ich die Click-Events eh abfangen muss, da ich auf DoppelKlick einen Slot ausführe, genau so wie auf Context-Click und muss also QListView so oder so ableiten ;)

Verfasst: 24. April 2007 12:53
von upsala
setModel() ist public und wird auch public bleiben, außer du leitest falsch ab. Und das clicked()-Signal kann nur generiert werden, wenn QListView auch das mousePressEvent() bearbeiten darf.

Verfasst: 24. April 2007 13:10
von andy72
Eben, und DA fängt es an:
Ich musste das mousePressEvent mit neu definieren, da ich ja auf Rechts-/Links-Klick reagieren möchte. Ich kann natürlich ein "emit clicked(modelindex)" machen, aber QListView soll noch den Rest erledigen.

Soll heissen, meine mousePressEvent-Methode sieht SO aus:

Code: Alles auswählen

void MyClass:mousePressEvent(QMouseEvent *e) {
  e->accept();
  if( e->button() == Qt::LeftButton && e->type() == QEvent::MouseDblClick ) {
    // meine Funktion
  }
  else
    QListView::mousePressEvent( e );
}
Das Problem ist nun, dass QListView::mousePressEvent(e) ausgeführt wird, mein eigener Code davor jedoch nicht. Lasse ich QListView nix ausführen, funktioniert zwar mein Code wieder, jedoch hab ich dann
keinerlei Funktionalität mehr in der ListView - sprich keine visuelle Selection der Icons mehr etc (der Code "unter der Haube" funktioniert trotzdem)

Verfasst: 24. April 2007 20:59
von upsala
Dann probiers mal so:

Code: Alles auswählen

void MyClass:mousePressEvent(QMouseEvent *e) { 
  QListView::mousePressEvent( e ); 
  if( e->button() == Qt::LeftButton && e->type() == QEvent::MouseDblClick ) { 
  // meine Funktion 
  e->accept(); 
  }      
}