Results 1 to 5 of 5

Thread: QDirModel and QTreeView cut and paste

  1. #1
    Join Date
    Jun 2007
    Posts
    56
    Thanks
    6
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11

    Default QDirModel and QTreeView cut and paste

    I'm using the examples of the simple file manager using QDirModel and TreeView mentioned in this post.
    Qt Code:
    1. #include <QtGui>
    2.  
    3. class MainWindow : public QMainWindow
    4. {
    5. Q_OBJECT
    6.  
    7. public:
    8. MainWindow( QWidget *parent = 0 ) : QMainWindow( parent)
    9. {
    10. splitter = new QSplitter( this );
    11.  
    12. model = new QDirModel( this );
    13. model->setReadOnly( false );
    14.  
    15. tree = new QTreeView;
    16. tree->setModel( model );
    17. tree->setRootIndex( model->index( QString( "/home/randy" ) ) );
    18.  
    19. model1 = new QDirModel( this );
    20. model1->setReadOnly( false );
    21.  
    22. righttree = new QTreeView;
    23. righttree->setModel( model1 );
    24. righttree->setRootIndex( model1->index( QString( "/tmp" ) ) );
    25.  
    26. tree->setDragEnabled( true );
    27. tree->setAcceptDrops( true );
    28. tree->setDropIndicatorShown( true );
    29. tree->setDragDropOverwriteMode( false );
    30.  
    31. righttree->setDragEnabled( true );
    32. righttree->setAcceptDrops( true );
    33. righttree->setDropIndicatorShown( true );
    34. righttree->setDragDropOverwriteMode( false );
    35.  
    36. splitter->addWidget( tree );
    37. splitter->addWidget( righttree );
    38.  
    39. timer = new QTimer( this );
    40.  
    41.  
    42. //QObject::connect( model, SIGNAL( layoutChanged( ) ), this, SLOT( refreshleft( ) ) );
    43. //QObject::connect( model1, SIGNAL( layoutChanged( ) ), this, SLOT( refreshright( ) ) );
    44. QObject::connect( timer, SIGNAL( timeout( ) ), this, SLOT( refreshleft( ) ) );
    45. QObject::connect( timer, SIGNAL( timeout( ) ), this, SLOT( refreshright( ) ) );
    46.  
    47. setCentralWidget( splitter );
    48. timer->start( 1000 );
    49.  
    50. }
    51.  
    52. private slots:
    53. void refreshleft ()
    54. {
    55. model->refresh( tree->rootIndex() );
    56. }
    57.  
    58. void refreshright ()
    59. {
    60. model1->refresh( righttree->rootIndex() );
    61. }
    62.  
    63.  
    64. private:
    65. QSplitter *splitter;
    66. QDirModel *model;
    67. QTreeView *tree;
    68. QDirModel *model1;
    69. QTreeView *righttree;
    70. QTimer *timer;
    71. };
    72.  
    73. int main( int argc, char *argv[] )
    74. {
    75. // a "file manager" at simplest :)
    76. QApplication a( argc, argv );
    77. MainWindow window;
    78. window.show();
    79. return a.exec( );
    80. }
    81.  
    82. #include "app.moc"
    To copy to clipboard, switch view to plain text mode 

    I am running into a problem when I do cut and paste in that when using the shift key modifier to indicate a true cut and paste (instead of a copy and paste), I see the new file has been inserted in the tree that received the drop, however the tree that initiated the drag still shows the file. I checked in the file system and the file has in fact been removed so the cut and paste worked, its just that since QDirModel uses a cache, it needs a refresh.

    Any ideas on how to force a QDirModel->refresh() upon successful cut and paste? (I would have thought the thing would have done it automatically.)

    I have a workaround by starting a 1 second timer that calls refresh on timeout but thats not exactly what I want.

    I tried connecting QDirModel->dataChanged to a slot that calls refresh on the QDirModel but that didn't work because that doesn't get emitted when new data is added.

    I then tried connecting QDirModel->layoutChanged to that slot but that caused the app to lock up.

  2. #2
    Join Date
    May 2008
    Location
    Kyiv, Ukraine
    Posts
    418
    Thanks
    1
    Thanked 29 Times in 27 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QDirModel and QTreeView cut and paste

    What if you call refresh( const QModelIndex & ) for the parents of files that have been "cut&pasted"? and then repaint for QTreeView?
    Last edited by wysota; 28th May 2008 at 20:10. Reason: Removed the quote, there is no point in quoting the whole post
    I'm a rebel in the S.D.G.

  3. #3
    Join Date
    Jun 2007
    Posts
    56
    Thanks
    6
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11

    Default Re: QDirModel and QTreeView cut and paste

    Quote Originally Posted by lyuts View Post
    What if you call refresh( const QModelIndex & ) for the parents of files that have been "cut&pasted"? and then repaint for QTreeView?
    I haven't subclassed QTreeView so I don't have access to the repaint. I'm trying to use the standard widgets if possible.

  4. #4
    Join Date
    Jun 2007
    Posts
    56
    Thanks
    6
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11

    Talking Re: QDirModel and QTreeView cut and paste

    I have a solution using an event filter shown below.

    One would think that one would be able to intercept an event of type QEvent;;Drop heading for the TreeViews but I was unable to detect one. Strange...Unless it is the MetaCall event it receives just after the drop. Since I could not make use of the information in the meta call event I can't know if it was the Drop event or not.

    At anyrate, the QEvent::ChildRemoved event type proved to work just as well. Perhaps even better since I should only get that when the model/view accepts the drop and I don't have to put in lots of ugly code to send the event and check its return to see if the drop was accepted or not.

    Enjoy...

    -Mic

    Qt Code:
    1. #include <QtGui>
    2.  
    3. class MainWindow : public QMainWindow
    4. {
    5. Q_OBJECT
    6.  
    7. public:
    8. MainWindow( QWidget *parent = 0 ) : QMainWindow( parent)
    9. {
    10. splitter = new QSplitter( this );
    11.  
    12. model = new QDirModel( this );
    13. model->setReadOnly( false );
    14.  
    15. tree = new QTreeView;
    16. tree->setModel( model );
    17. tree->setRootIndex( model->index( QString( "/home/randy" ) ) );
    18.  
    19. model1 = new QDirModel( this );
    20. model1->setReadOnly( false );
    21.  
    22. righttree = new QTreeView;
    23. righttree->setModel( model1 );
    24. righttree->setRootIndex( model1->index( QString( "/tmp" ) ) );
    25.  
    26. tree->setDragEnabled( true );
    27. tree->setAcceptDrops( true );
    28. tree->setDropIndicatorShown( true );
    29. tree->setDragDropOverwriteMode( false );
    30. tree->installEventFilter( this );
    31.  
    32. righttree->setDragEnabled( true );
    33. righttree->setAcceptDrops( true );
    34. righttree->setDropIndicatorShown( true );
    35. righttree->setDragDropOverwriteMode( false );
    36. righttree->installEventFilter( this );
    37.  
    38. splitter->addWidget( tree );
    39. splitter->addWidget( righttree );
    40.  
    41. setCentralWidget( splitter );
    42. }
    43.  
    44. bool eventFilter( QObject *target, QEvent *event )
    45. {
    46. if( target == tree && event->type() == QEvent::ChildRemoved ) {
    47. model->refresh( tree->rootIndex() );
    48. }
    49. else if( target == righttree && event->type() == QEvent::ChildRemoved ) {
    50. model1->refresh( righttree->rootIndex() );
    51. }
    52. return false;
    53. }
    54.  
    55. private:
    56. QSplitter *splitter;
    57. QDirModel *model;
    58. QTreeView *tree;
    59. QDirModel *model1;
    60. QTreeView *righttree;
    61. QTimer *timer;
    62. };
    63.  
    64. int main( int argc, char *argv[] )
    65. {
    66. // a "file manager" at simplest :)
    67. QApplication a( argc, argv );
    68. MainWindow window;
    69. window.show();
    70. return a.exec( );
    71. }
    72.  
    73. #include "app.moc"
    To copy to clipboard, switch view to plain text mode 

  5. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QDirModel and QTreeView cut and paste

    I admit I haven't read the whole thread, but based on the parts I did read I can say that you have to make sure you return Qt::MoveAction as the drop action (cut and paste is really another interface to drag&drop). Depending on how you handle the D&D mechanism (meaning if you do it in the model or in the view), there are different ways you can do it. Otherwise you'll have to detect the move action yourself and delete entries from the model as you probably did using the event filter.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.