Russian Qt Forum

Qt => Вопросы новичков => Тема начата: koldun90 от Май 04, 2014, 19:59



Название: переопределение mouse press event
Отправлено: koldun90 от Май 04, 2014, 19:59
Для проекта требуется переопределить mouse press event подскажите собственно как.
Я создал свой собственный класс. Класс унаследовал соответственно от QTreeView.
Затем собственно подключил mytreeview.h в mainwindow.h. Проблема заключается что соответственно когда я начинаю переопределять mouse press event то у меня просто не находит метод button()... Так вот подскажите как правильно реализовать переопределение?
mytreeview.h
Код:
#ifndef MYTREEVIEW_H
#define MYTREEVIEW_H
#include <QTreeView>
#include <QMessageBox>
class mytreeview : public QTreeView
{
public:
    mytreeview();
protected:
    void mousePressEvent( QMouseEvent * event );


};

#endif // MYTREEVIEW_H
mytreeview.cpp
Код:
void MyWindow::mousePressEvent(QMouseEvent *event)   // Для проверки реализации   button()-- не подцепляется button
{
    if(event->button() == Qt::LeftButton)
        std::cout << "left mouse click " << std::endl;   // doesn't work
    else if (event->button() == Qt::RightButton)
        std::cout << "right mouse click " << std::endl;  // does work
    else if (event->button() == Qt::MidButton)
        std::cout << "middle mouse click " << std::endl;   /// does work
}


Название: Re: переопределение mouse press event
Отправлено: Serr500 от Май 04, 2014, 22:06
#include <QMouseEvent> в mytreeview.cpp есть?


Название: Re: переопределение mouse press event
Отправлено: gil9red от Май 05, 2014, 09:00
Оффтоп.
koldun90, оформляйте в тэг код  :)


Название: Re: переопределение mouse press event
Отправлено: koldun90 от Май 05, 2014, 15:55
Serr500

да добавил как вы написали все компилируется. Но есть одно но вот допустим реализация метода + моя программа.
Я его переопределил а как мне его использовать в mainwindow.cpp?

mytreeview.h
Код:
#ifndef MYTREEVIEW_H
#define MYTREEVIEW_H
#include <QTreeView>
#include <QMessageBox>
#include <QMouseEvent>
class mytreeview : public QTreeView
{
public:
    mytreeview();
protected:
    void mousePressEvent( QMouseEvent * event );

public:

    QMessageBox msg;

};

#endif // MYTREEVIEW_H

mytreeview.cpp
Код:
#include "mytreeview.h"

mytreeview::mytreeview()
{
}
void mytreeview::mousePressEvent(QMouseEvent *event)
{

    if (event->button() == Qt::RightButton) {
        // здесь обрабатываем левую кнопку мыши
        msg.setText("pravay");
        msg.exec();
    }
    else
    {
        // передаём остальные кнопки в базовый класс
        QTreeView::mousePressEvent(event);
    }
}
те кликая по правой кнопке на тривиев выводится сообщение

вот сам файл проекта в котором я реализую файл менеджер

mainwindow.h
Код:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "mytreeview.h"
#include <QMainWindow>
#include <QFileSystemModel>
#include <QMessageBox>
#include <QString>
#include <QStringListModel>
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT
   
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
   
private slots:
    void on_treeView_clicked(const QModelIndex &index);

    void on_treeView_2_clicked(const QModelIndex &index);

    void on_treeView_customContextMenuRequested(const QPoint &pos);

    void on_treeView_2_customContextMenuRequested(const QPoint &pos);

private:
    Ui::MainWindow *ui;
public:
    int r;
    int e;
    QFileSystemModel *model1;
    QFileSystemModel *model2;
    QMessageBox msg;
    QStringList path;
    QStringList path2;
    QStringListModel stringmodel;
    QStringListModel stringmodel2;
    QMenu *menu;
    QAction *kopirov;
    QAction *udalit;
    QAction *vyrezat;
    QAction *vstavit;
    QAction *pereim;
    QAction *sozd;
    QAction *prosmotr;
    QString str;
    mytreeview tt;
};

#endif // MAINWINDOW_H


mainwindow.cpp

Код:
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    model1=new QFileSystemModel();
    model2=new QFileSystemModel();
    model1->setRootPath(QDir::currentPath());
    model1->setFilter(QDir::AllDirs | QDir::Files |QDir::NoDotAndDotDot);
    ui->treeView->setModel(model1);
    ui->treeView->hideColumn(2);
    ui->treeView->setAcceptDrops(true);
    ui->treeView->setDragEnabled(true);
    ui->treeView->setDragDropMode(QAbstractItemView::DragDrop);
    ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);


    model2->setRootPath(QDir::currentPath());
    model2->setFilter(QDir::AllDirs | QDir::Files |QDir::NoDotAndDotDot);
    ui->treeView_2->setModel(model2);
    ui->treeView_2->hideColumn(2);
    ui->treeView_2->setAcceptDrops(true);
    ui->treeView_2->setDragEnabled(true);
    ui->treeView_2->setDragDropMode(QAbstractItemView::DragDrop);
    ui->treeView_2->setContextMenuPolicy(Qt::CustomContextMenu);

    menu=new QMenu;
    kopirov= new QAction(QString::fromLocal8Bit("Копировать"),this);
    vyrezat=new QAction(QString::fromLocal8Bit("Вырезать"),this);
    vstavit=new QAction(QString::fromLocal8Bit("Вставить"),this);
    udalit=new QAction(QString::fromLocal8Bit("Удалить"),this);
    pereim=new QAction(QString::fromLocal8Bit("Переименовать"),this);
    sozd=new QAction(QString::fromLocal8Bit("Создать"),this);
    //prosmotr=new QAction(QString::fromLocal8Bit("Просмотр"),this);
    menu->addAction(kopirov);
    menu->addAction(udalit);
    menu->addAction(vyrezat);
    menu->addAction(vstavit);
    menu->addAction(pereim);
    menu->addAction(sozd);
    //menu->addAction(prosmotr);
    vstavit->setVisible(false);

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_treeView_clicked(const QModelIndex &index)
{


    bool q=model1->isDir(index);   // В случае если объект папка
    if (q)
    {
         //int i;
         str=model1->fileInfo(index).absoluteFilePath();  // взятие абсолютного пути
         if (!path.contains(str))     // в случае если путь не содержитьсся в списке
         {
            path<<str;    // то добавляем его
         }
         else
         {
             for (int i=0;i<path.size();i++)
             {
                 if (path[i]==str)
                 {
                     path.removeAt(i);
                 }
             }
         }
         r=path.size();     // определения количества элементов в списке
         stringmodel.setStringList(path);
         ui->listView->setModel(&stringmodel);

     }
}

void MainWindow::on_treeView_2_clicked(const QModelIndex &index)
{

    bool q=model2->isDir(index);   // В случае если объект папка
    if (q)
    {

         QString str=model2->fileInfo(index).absoluteFilePath();  // взятие абсолютного пути
         if (!path2.contains(str))     // в случае если путь не содержитьсся в списке
         {
            path2<<str;    // то добавляем его
         }
         else
         {
             for (int i=0;i<path2.size();i++)
             {
                 if (path2[i]==str)
                 {
                      path2.removeAt(i);
                 }
             }
         }
         e=path2.size();     // определения количества элементов в списке
         stringmodel2.setStringList(path2);
         ui->listView_2->setModel(&stringmodel2);


     }
}

void MainWindow::on_treeView_customContextMenuRequested(const QPoint &pos)
{

    menu->exec(QCursor::pos());
   // path<<str;



    //path.clear();
}

void MainWindow::on_treeView_2_customContextMenuRequested(const QPoint &pos)
{

    menu->exec(QCursor::pos());
    //path2.clear();
}



Название: Re: переопределение mouse press event
Отправлено: koldun90 от Май 05, 2014, 16:02
Serr500
если я правильно понял то чтобы вызвать метод другого класса нужно сделать вот так допустим

Код:
void MainWindow::on_treeView_customContextMenuRequested(const QPoint &pos)
{
    mytreeview hh;   // создаем объект класса
    hh.mousePressEvent(QMouseEvent *event);   // вызываем переопределенный метод
    menu->exec(QCursor::pos());   // показываем меню
 
}

Но если я так пишу в программе то выдает ошибку
C:\Qt\project\managermay-build-desktop-Qt___mingw48_32_________\..\managermay\mainwindow.cpp:118: ошибка: expected primary-expression before '*' token


Название: Re: переопределение mouse press event
Отправлено: Serr500 от Май 05, 2014, 20:17
Вам нужно теперь создавать объекты типа mytreeview, а не QTreeView. Вызывать метод mousePressEvent явно не нужно - он виртуальный и Qt вызовет его самостоятельно при возникновении события мыши.

Код:
hh.mousePressEvent(QMouseEvent *event);
Ну, а это даже комментировать не хочется. Почитайте что-нибудь по основам C++.


Название: Re: переопределение mouse press event
Отправлено: koldun90 от Май 05, 2014, 22:35
Вам нужно теперь создавать объекты типа mytreeview, а не QTreeView. Вызывать метод mousePressEvent явно не нужно - он виртуальный и Qt вызовет его самостоятельно при возникновении события мыши.

я не совсем понял что это значит. Те как бы должен добавить на форму не qtreeview а mytreeview?
Но как же это сделать ведь дизайнер добавляет только базовый класс qtreeview.


Название: Re: переопределение mouse press event
Отправлено: Bepec от Май 05, 2014, 22:37
Promote to... в дизайнере. А потом пишете название своего класса, соблюдая регистр. После чего всё должно заработать.


Название: Re: переопределение mouse press event
Отправлено: koldun90 от Май 05, 2014, 22:45
Bepec
а можно по подробнее это нужно что то в свойстве базового treeview поменять?


Название: Re: переопределение mouse press event
Отправлено: koldun90 от Май 05, 2014, 22:51
а это пункт меню пкм "Преобразовать в "?


Название: Re: переопределение mouse press event
Отправлено: Bepec от Май 05, 2014, 23:44
Да да, рашен едишен. "Преобразовать в..."


Название: Re: переопределение mouse press event
Отправлено: koldun90 от Май 06, 2014, 09:19
собственно выбрал преобразовать в -> указал mytreeview
но после пересборки проекта у меня

C:\Qt\project\managermay-build-desktop-Qt___mingw48_32_________\ui_mainwindow.h:49: ошибка: no matching function for call to 'mytreeview::mytreeview(QWidget*&)'

вот на этой строке
Цитировать
treeView = new mytreeview(centralWidget);

Цитировать
treeView_2 = new mytreeview(centralWidget);
в чем может быть проблема?


Название: Re: переопределение mouse press event
Отправлено: Old от Май 06, 2014, 09:24
В том, что конструктор вашего класса не принимает никаких параметров.


Название: Re: переопределение mouse press event
Отправлено: koldun90 от Май 06, 2014, 09:24
(http://i055.radikal.ru/1405/72/269b30d5f3bb.png)


Название: Re: переопределение mouse press event
Отправлено: koldun90 от Май 06, 2014, 09:26
Old
а что туда нужно передать?


Название: Re: переопределение mouse press event
Отправлено: koldun90 от Май 06, 2014, 09:28
я так понял что то нужно сюда прописать?

mytreeview.cpp
Цитировать
#include "mytreeview.h"

mytreeview::mytreeview(   ///ЧТО ТО ТУТ)
{
}


Название: Re: переопределение mouse press event
Отправлено: Old от Май 06, 2014, 09:29
Old
а что туда нужно передать?

Туда как раз что надо передают, а ваш конструктор ничего не принимает. :)
Что бы работать с Qt нужно знать С++. Без его знания, к Qt лучше не подходить.


Название: Re: переопределение mouse press event
Отправлено: Old от Май 06, 2014, 09:41
я так понял что то нужно сюда прописать?
Да. Посмотрите что за параметр передается в конструктор любого виджета и сделайте так же у себя.


Название: Re: переопределение mouse press event
Отправлено: koldun90 от Май 06, 2014, 17:40
Old
Я посмотрел сделал вот так

mytreeview.h


Код:
#ifndef MYTREEVIEW_H
#define MYTREEVIEW_H
#include <QTreeView>
#include <QMessageBox>
#include <QMouseEvent>
class mytreeview : public QTreeView
{
public:
    mytreeview(QWidget *parent);
protected:
    void mousePressEvent( QMouseEvent * event );


public:
    QMessageBox msg;

};

#endif // MYTREEVIEW_H

mytreeview.cpp

Код:
#include "mytreeview.h"

mytreeview::mytreeview(QWidget *parent)

{
}
void mytreeview::mousePressEvent(QMouseEvent *event)
{

    if (event->button() == Qt::RightButton) {
        // здесь обрабатываем левую кнопку мыши
        msg.setText("pravay");
        msg.exec();
    }
    else
    {
        // передаём остальные кнопки в базовый класс
        QTreeView::mousePressEvent(event);
    }
}


в итоге получилось как бы не правильно
(http://s57.radikal.ru/i158/1405/0a/5a3aa7ba8f5et.jpg) (http://radikal.ru/fp/94689b1c6a2743ac8043192eb166aa1f)


Название: Re: переопределение mouse press event
Отправлено: koldun90 от Май 06, 2014, 18:08
таким образом тривиев вообще слез с формы основной и создался в виде отдельной как бы а это не правильно....


Название: Re: переопределение mouse press event
Отправлено: Bepec от Май 06, 2014, 18:26
А вот тут надо понять куда сувать родителя :D


Название: Re: переопределение mouse press event
Отправлено: koldun90 от Май 06, 2014, 18:29
Bepec
Подскажите а то очень надо


Название: Re: переопределение mouse press event
Отправлено: koldun90 от Май 06, 2014, 18:32
сделал так

Код:
mytreeview::mytreeview(QWidget *parent)
    :QTreeView(parent)


{
}

но так вроде в первом окне тривиев появился но почему то создается второе окно (пустое окно)
(http://s61.radikal.ru/i171/1405/c1/f821e5e90668t.jpg) (http://radikal.ru/fp/c016503fd9f84d51803b3bfd6c66615d)
так как мне избавиться от второго пустого окна?


Название: Re: переопределение mouse press event
Отправлено: Old от Май 06, 2014, 18:53
так как мне избавиться от второго пустого окна?
Ну а как это можно сказать без вашего кода?
Показывайте. :)


Название: Re: переопределение mouse press event
Отправлено: Bepec от Май 06, 2014, 18:55
Код наше всё. Особенно в теге #code или архиве с проектом :)


Название: Re: переопределение mouse press event
Отправлено: koldun90 от Май 06, 2014, 19:06
и так выкладываю код:

mytreeview.h
Цитировать
#ifndef MYTREEVIEW_H
#define MYTREEVIEW_H
#include <QTreeView>
#include <QMessageBox>
#include <QMouseEvent>
class mytreeview : public QTreeView
{
public:
    mytreeview(QWidget *parent);
protected:
    void mousePressEvent( QMouseEvent * event );


public:
    QMessageBox msg;

};

#endif // MYTREEVIEW_H

mytreeview.cpp

Код:
#include "mytreeview.h"

mytreeview::mytreeview(QWidget *parent)
    :QTreeView(parent)


{
}
void mytreeview::mousePressEvent(QMouseEvent *event)
{

    if (event->button() == Qt::RightButton) {
        // здесь обрабатываем левую кнопку мыши
        msg.setText("pravay");
        msg.exec();
    }
    else
    {
        // передаём остальные кнопки в базовый класс
        QTreeView::mousePressEvent(event);
    }
}


mainwindow.h
Код:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "mytreeview.h"
#include <QMainWindow>
#include <QFileSystemModel>
#include <QMessageBox>
#include <QString>
#include <QStringListModel>
#include <QMouseEvent>
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT
    
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    
private slots:
    void on_treeView_clicked(const QModelIndex &index);

    void on_treeView_2_clicked(const QModelIndex &index);

    void on_treeView_customContextMenuRequested(const QPoint &pos);

    void on_treeView_2_customContextMenuRequested(const QPoint &pos);

private:
    Ui::MainWindow *ui;
public:
    int r;
    int e;
    QFileSystemModel *model1;
    QFileSystemModel *model2;
    QMessageBox msg;
    QStringList path;
    QStringList path2;
    QStringListModel stringmodel;
    QStringListModel stringmodel2;
    QMenu *menu;
    QAction *kopirov;
    QAction *udalit;
    QAction *vyrezat;
    QAction *vstavit;
    QAction *pereim;
    QAction *sozd;
    QAction *prosmotr;
    QString str;
    mytreeview tt;
};

#endif // MAINWINDOW_H


mainwindow.cpp

Код:
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    model1=new QFileSystemModel();
    model2=new QFileSystemModel();
    model1->setRootPath(QDir::currentPath());
    model1->setFilter(QDir::AllDirs | QDir::Files |QDir::NoDotAndDotDot);
    ui->treeView->setModel(model1);
    ui->treeView->hideColumn(2);
    ui->treeView->setAcceptDrops(true);
    ui->treeView->setDragEnabled(true);
    ui->treeView->setDragDropMode(QAbstractItemView::DragDrop);
    ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);


    model2->setRootPath(QDir::currentPath());
    model2->setFilter(QDir::AllDirs | QDir::Files |QDir::NoDotAndDotDot);
    ui->treeView_2->setModel(model2);
    ui->treeView_2->hideColumn(2);
    ui->treeView_2->setAcceptDrops(true);
    ui->treeView_2->setDragEnabled(true);
    ui->treeView_2->setDragDropMode(QAbstractItemView::DragDrop);
    ui->treeView_2->setContextMenuPolicy(Qt::CustomContextMenu);


    menu=new QMenu;
    kopirov= new QAction(QString::fromLocal8Bit("Копировать"),this);
    vyrezat=new QAction(QString::fromLocal8Bit("Вырезать"),this);
    vstavit=new QAction(QString::fromLocal8Bit("Вставить"),this);
    udalit=new QAction(QString::fromLocal8Bit("Удалить"),this);
    pereim=new QAction(QString::fromLocal8Bit("Переименовать"),this);
    sozd=new QAction(QString::fromLocal8Bit("Создать"),this);
    //prosmotr=new QAction(QString::fromLocal8Bit("Просмотр"),this);
    menu->addAction(kopirov);
    menu->addAction(udalit);
    menu->addAction(vyrezat);
    menu->addAction(vstavit);
    menu->addAction(pereim);
    menu->addAction(sozd);
    //menu->addAction(prosmotr);
    vstavit->setVisible(false);
    mytreeview *hh=new mytreeview;
    hh->show();




}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_treeView_clicked(const QModelIndex &index)
{


    bool q=model1->isDir(index);   // В случае если объект папка
    if (q)
    {
         //int i;
         str=model1->fileInfo(index).absoluteFilePath();  // взятие абсолютного пути
         if (!path.contains(str))     // в случае если путь не содержитьсся в списке
         {
            path<<str;    // то добавляем его
         }
         else
         {
             for (int i=0;i<path.size();i++)
             {
                 if (path[i]==str)
                 {
                     path.removeAt(i);
                 }
             }
         }
         r=path.size();     // определения количества элементов в списке
         stringmodel.setStringList(path);
         ui->listView->setModel(&stringmodel);

     }
}

void MainWindow::on_treeView_2_clicked(const QModelIndex &index)
{

    bool q=model2->isDir(index);   // В случае если объект папка
    if (q)
    {

         QString str=model2->fileInfo(index).absoluteFilePath();  // взятие абсолютного пути
         if (!path2.contains(str))     // в случае если путь не содержитьсся в списке
         {
            path2<<str;    // то добавляем его
         }
         else
         {
             for (int i=0;i<path2.size();i++)
             {
                 if (path2[i]==str)
                 {
                      path2.removeAt(i);
                 }
             }
         }
         e=path2.size();     // определения количества элементов в списке
         stringmodel2.setStringList(path2);
         ui->listView_2->setModel(&stringmodel2);


     }
}

void MainWindow::on_treeView_customContextMenuRequested(const QPoint &pos)
{

    menu->exec(QCursor::pos());
   // path<<str;



    //path.clear();
}

void MainWindow::on_treeView_2_customContextMenuRequested(const QPoint &pos)
{

    menu->exec(QCursor::pos());
    //path2.clear();
}