当一个子控件有焦点的时候如何改变一个父控件的背景? [英] How to change a parent widget's background when a child widget has focus?

查看:220
本文介绍了当一个子控件有焦点的时候如何改变一个父控件的背景?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想突出显示一个QFrame,如果其中一个子窗口小部件具有焦点(所以用户知道在哪里查找游标; - )



使用一些东西

  ui-> frame-> setFocusPolicy(Qt :: StrongFocus); 
ui-> frame-> setStyleSheet(QFrame:focus {background-color:#FFFFCC;});

突出显示了当我点击它时的QFrame,但是一旦它的一个子部件

可能的方法:


  • 我可以 connect() QApplication :: focusChanged(old,now)并检查每个新对象是否是我的QFrame的子对象这会变得麻烦。我还可以子类化每个子部件并重新实现 focusInEvent() / focusOutEvent()并对此作出反应,但是有很多不同的小部件,这也是很多工作的。

  • >

    有没有更优雅的解决方案? 解决方案

code> QFrame 来让它监听子部件的焦点变化。
或者您也可以在子窗口小部件上安装一个事件过滤器来捕获 QFocusEvent



这是一个例如:

$ MyFrame.h

pre $ code > #ifndef MYFRAME_H
#define MYFRAME_H

#include< QFrame>
$ b class MyFrame:public QFrame
{
Q_OBJECT
$ b public:

显式MyFrame(QWidget * parent = 0, Qt :: WindowFlags f = 0);

void hookChildrenWidgetsFocus();
$ b保护:

bool eventFilter(QObject * object,QEvent * event);

private:

QString m_originalStyleSheet;
};

#endif // MYFRAME_H

MyFrame.cpp b

  #include< QEvent> 
#includeMyFrame.h

MyFrame :: MyFrame(QWidget * parent,Qt :: WindowFlags f)
:QFrame(parent,f)
{
m_originalStyleSheet = styleSheet();


void MyFrame :: hookChildrenWidgetsFocus()
{
foreach(QObject * child,children()){
if(child-> isWidgetType()){
child-> installEventFilter(this);



$ b bool MyFrame :: eventFilter(QObject * object,QEvent * event)
{
if(event- > type()== QEvent :: FocusIn){
setStyleSheet(background-color:#FFFFCC;);
} else if(event-> type()== QEvent :: FocusOut){
setStyleSheet(m_originalStyleSheet);
}

return QObject :: eventFilter(object,event);

MainWindow.cpp

  #include< QHBoxLayout> 
#include< QVBoxLayout>
#include< QLineEdit>
#includeMyFrame.h
#includemainwindow.h

MainWindow :: MainWindow(QWidget * parent):
QMainWindow(parent)
{
setWindowTitle(tr(Test));

MyFrame * frame1 = new MyFrame(this);
frame1-> setLayout(new QVBoxLayout());
frame1-> layout() - > addWidget(new QLineEdit());
frame1-> layout() - > addWidget(new QLineEdit());
frame1-> layout() - > addWidget(new QLineEdit());
frame1-> hookChildrenWidgetsFocus();

MyFrame * frame2 = new MyFrame(this);
frame2-> setLayout(new QVBoxLayout());
frame2-> layout() - > addWidget(new QLineEdit());
frame2-> layout() - > addWidget(new QLineEdit());
frame2-> layout() - > addWidget(new QLineEdit());
frame2-> hookChildrenWidgetsFocus();

QHBoxLayout * centralLayout = new QHBoxLayout();
centralLayout-> addWidget(frame1);
centralLayout-> addWidget(frame2);

QWidget * centralWidget = new QWidget();
centralWidget-> setLayout(centralLayout);

setCentralWidget(centralWidget);
}


I would like to highlight a QFrame, if one of it's child widgets has focus (so the users know where to look for the cursor ;-)

using something along

ui->frame->setFocusPolicy(Qt::StrongFocus);
ui->frame->setStyleSheet("QFrame:focus {background-color: #FFFFCC;}");

highlights the QFrame when I click on it, but it loses its focus once one of its child widgets is selected.

Possible approaches:

  • I could connect() QApplication::focusChanged(old,now) and check each new object if it is a child of my QFrame, but this gets messy.

  • I could also subclass each child widget and reimplement focusInEvent()/focusOutEvent() and react on that, but with a lot of different widgets, this is also a lot of work.

Is there a more elegant solution?

解决方案

Well, you can extend QFrame to make it listen on focus change of its children widgets. Or you can also install an event filter on children widgets to catch QFocusEvent.

Here is an example:

MyFrame.h

#ifndef MYFRAME_H
#define MYFRAME_H

#include <QFrame>

class MyFrame : public QFrame
{
    Q_OBJECT

public:

    explicit MyFrame(QWidget* parent = 0, Qt::WindowFlags f = 0);

    void hookChildrenWidgetsFocus();

protected:

    bool eventFilter(QObject *object, QEvent *event);

private:

    QString m_originalStyleSheet;
};

#endif // MYFRAME_H

MyFrame.cpp

#include <QEvent>
#include "MyFrame.h"

MyFrame::MyFrame(QWidget *parent, Qt::WindowFlags f)
    : QFrame(parent, f)
{
    m_originalStyleSheet = styleSheet();
}

void MyFrame::hookChildrenWidgetsFocus()
{
    foreach (QObject *child, children()) {
        if (child->isWidgetType()) {
            child->installEventFilter(this);
        }
    }
}

bool MyFrame::eventFilter(QObject *object, QEvent *event)
{
    if (event->type() == QEvent::FocusIn) {
        setStyleSheet("background-color: #FFFFCC;");
    } else if (event->type() == QEvent::FocusOut) {
        setStyleSheet(m_originalStyleSheet);
    }

    return QObject::eventFilter(object, event);
}

MainWindow.cpp

#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QLineEdit>
#include "MyFrame.h"
#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    setWindowTitle(tr("Test"));

    MyFrame *frame1 = new MyFrame(this);
    frame1->setLayout(new QVBoxLayout());
    frame1->layout()->addWidget(new QLineEdit());
    frame1->layout()->addWidget(new QLineEdit());
    frame1->layout()->addWidget(new QLineEdit());
    frame1->hookChildrenWidgetsFocus();

    MyFrame *frame2 = new MyFrame(this);
    frame2->setLayout(new QVBoxLayout());
    frame2->layout()->addWidget(new QLineEdit());
    frame2->layout()->addWidget(new QLineEdit());
    frame2->layout()->addWidget(new QLineEdit());
    frame2->hookChildrenWidgetsFocus();

    QHBoxLayout *centralLayout = new QHBoxLayout();
    centralLayout->addWidget(frame1);
    centralLayout->addWidget(frame2);

    QWidget *centralWidget = new QWidget();
    centralWidget->setLayout(centralLayout);

    setCentralWidget(centralWidget);
}

这篇关于当一个子控件有焦点的时候如何改变一个父控件的背景?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆