у меня есть QMainWindow
который содержит циркуляр QWidget
внутри него. Для того, чтобы иметь круглую форму QWidget
Я использую QWidget::setMask
, Предполагаемое поведение приложения при нажатии мыши внутри MainWindow зависит от области, в которой нажата мышь.
class MyMainWindow: public QMainWindow
{
public:
MyMainWindow():QMainWindow()
{
}
void mousePressEvent( QMouseEvent * event )
{
qDebug()<<"Clicked on MainWindow";
}
};
class CircularWidget: public QWidget
{
public:
CircularWidget( QWidget * parent ):QWidget( parent )
{
}
void paintEvent(QPaintEvent * event)
{
QRegion circularMask( QRect( pos(), size() ), QRegion::Ellipse );
setMask( circularMask );
setStyleSheet("background-color:black;");
QWidget::paintEvent( event );
}
void mousePressEvent( QMouseEvent * event )
{
qDebug()<<"Clicked on Circular Widget";
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QMainWindow w;
w.resize( 400, 400 );
CircularWidget circularWidget( &w );
circularWidget.show();
w.setCentralWidget( &circularWidget );
w.show();
return a.exec();
}
В настоящее время, когда я нажимаю внутри круговой области, я получаю событие в своем виджете. Но все события нажатия мыши за пределами круга теряются. Я видел в документации Qt, что: Masked widgets receive mouse events only on their visible portions
, Есть ли способ передать другие события щелчка мышью (события в серой области на рисунке) в родительский виджет?
Причина, по которой вы не получили события мыши в вашем MyMainWindow
класс, потому что в вашей функции main () вы создаете объект главного окна класса QMainWindow
вместо.
Для обработки событий щелчка мышью на круговом виджете я бы использовал здесь механизм сигнал / слот. То есть пусть круговой виджет излучает сигнал каждый раз, когда на него нажимают. Любой другой получатель будет обрабатывать его как свой собственный. Например:
class MyMainWindow: public QMainWindow
{
Q_OBJECT
[..]
public slots:
void handleMouseClick(const QPoint &) {}
};
class CircularWidget: public QWidget
{
Q_OBJECT
public:
[..]
void mousePressEvent( QMouseEvent * event )
{ emit mouseClicked(event->pos()); }
signals:
void mouseClicked(const QPoint &);
};
И, наконец, установить связь. С этим в MyMainWindow
В классе вы сможете обрабатывать события щелчка мышью как из кругового виджета, так и из самого главного окна.
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyMainWindow w; // <-------- This should be MyMainWindow instead of QMainWindow
CircularWidget circularWidget( &w );
w.setCentralWidget( &circularWidget );
QObject::connect(&circularWidget, SIGNAL(mouseClicked(const QPoint &)),
&w, SLOT(handleMouseClick(const QPoint &));
return a.exec();
}
Правильным решением является отклонение события нажатия мыши, если указатель находится за пределами области, поэтому он должен выглядеть примерно так:
void mousePressEvent( QMouseEvent * event )
{
QRegion circularMask( QRect( pos(), size() ), QRegion::Ellipse ); // it would be nice to make it a class field
if (!circularMask.contains(event->pos()) {
event->ignore();
}
}
Увидеть документация:
Событие мыши содержит специальный флаг принятия, который указывает,
получатель хочет событие. Вы должны вызвать ignore (), если мышь
событие не обрабатывается вашим виджетом. Событие мыши распространяется вверх
родительская цепочка виджетов, пока виджет не примет ее с помощью accept () или
фильтр событий потребляет его.