C++ 显示不对焦的Qt窗口
我如何使用Qt创建一个用户可以交互的窗口(即,单击窗口中的按钮),但不会改变或聚焦 用例:我有一个C++ 显示不对焦的Qt窗口,c++,qt,C++,Qt,我如何使用Qt创建一个用户可以交互的窗口(即,单击窗口中的按钮),但不会改变或聚焦 用例:我有一个QLineEdit,我想在QLineEdit获得焦点时显示一个额外的“操纵器”弹出窗口。此操纵器弹出窗口可能包括用于转换为大写/小写等任务的按钮 如果我将操纵器的所有子窗口小部件的焦点策略设置为Qt::NoFocus,我就可以让它工作,但这感觉有点奇怪,因为我必须对它们进行迭代 我想知道是否有一种方法可以完全禁用小部件的焦点,比如setEnabled()将禁用/启用所有子小部件 以下是迄今为止的一些
QLineEdit
,我想在QLineEdit
获得焦点时显示一个额外的“操纵器”弹出窗口。此操纵器弹出窗口可能包括用于转换为大写/小写等任务的按钮
如果我将操纵器的所有子窗口小部件的焦点策略设置为Qt::NoFocus
,我就可以让它工作,但这感觉有点奇怪,因为我必须对它们进行迭代
我想知道是否有一种方法可以完全禁用小部件的焦点,比如setEnabled()
将禁用/启用所有子小部件
以下是迄今为止的一些调查结果
QCompleter
QCompleter
执行与QLineEdit
非常类似的操作,显示一个QListView
弹出窗口。它通过将QListView
的父项设置为0,使其成为一个窗口,并设置Qt::Popup
窗口标志,使其无框架来实现。最后,它设置focusPolicy(Qt::NoFocus)
以防止它从相关的QLineEdit
中接管焦点
这很简单,因为只有一个小部件需要将其焦点策略设置为Qt::NoFocus
QDateTimeEdit
在
QDateTimeEdit
中,执行类似操作。然而,那里的弹出窗口实际上会聚焦。没有现成的小部件。但是,可以这样做:
头文件:
#include <QObject>
#include <QWidget>
#include <QLineEdit>
#include <QBoxLayout>
#include <QPushButton>
#include <QFocusEvent>
class LineEdit : public QLineEdit
{
Q_OBJECT
public:
LineEdit(QWidget *parent) : QLineEdit(parent)
{ }
void focusInEvent(QFocusEvent *event) override
{
QLineEdit::focusInEvent(event);
emit focusIn();
}
void focusOutEvent(QFocusEvent *event) override
{
QLineEdit::focusOutEvent(event);
emit focusOut();
}
signals:
void focusIn();
void focusOut();
};
class ExtendedLineEdit : public QWidget
{
Q_OBJECT
public:
explicit ExtendedLineEdit(QWidget *parent = nullptr);
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
private:
void setupWidget();
LineEdit *lineEdit;
QWidget *showableWidget;
QPushButton *toUppercaseButton;
QPushButton *toLowercaseButton;
QWidget *parent;
};
#include "ExtendedLineEdit.h"
#include <QPoint>
ExtendedLineEdit::ExtendedLineEdit(QWidget *parent)
: QWidget(parent)
, parent(parent)
{
setupWidget();
}
bool ExtendedLineEdit::eventFilter(QObject *obj, QEvent *event)
{
Q_UNUSED(obj)
if (event->type() == QEvent::MouseButtonRelease ||
event->type() == QEvent::MouseButtonPress ||
event->type() == QEvent::MouseButtonDblClick)
{
lineEdit->setFocus();
}
return false;
}
void ExtendedLineEdit::setupWidget()
{
auto mainLayout = new QBoxLayout(QBoxLayout::Direction::TopToBottom, this);
this->setLayout(mainLayout);
lineEdit = new LineEdit(this);
mainLayout->addWidget(lineEdit);
showableWidget = new QWidget(parent);
showableWidget->setAutoFillBackground(true);
showableWidget->setPalette(QPalette(QPalette::Background, Qt::white));
showableWidget->hide();
auto bottomLayout = new QBoxLayout(QBoxLayout::Direction::LeftToRight, showableWidget);
showableWidget->setLayout(bottomLayout);
toUppercaseButton = new QPushButton("to uppercase", this);
toUppercaseButton->installEventFilter(this);
connect(toUppercaseButton, &QPushButton::clicked,
this, [&]{
lineEdit->setText(lineEdit->text().toUpper());
});
toLowercaseButton = new QPushButton("to lowercase", this);
toLowercaseButton->installEventFilter(this);
connect(toLowercaseButton, &QPushButton::clicked,
this, [&]{
lineEdit->setText(lineEdit->text().toLower());
});
bottomLayout->addWidget(toUppercaseButton);
bottomLayout->addWidget(toLowercaseButton);
connect(lineEdit, &LineEdit::focusIn,
this, [&]{
auto size = lineEdit->size();
auto position = QWidget::mapTo(parent, lineEdit->pos());
showableWidget->setGeometry(position.x(),
position.y() + size.height(),
size.width(),
40);
showableWidget->show();
});
connect(lineEdit, &LineEdit::focusOut,
showableWidget, &QWidget::hide);
}
#包括
#包括
#包括
#包括
#包括
#包括
类LineEdit:公共QLineEdit
{
Q_对象
公众:
LineEdit(QWidget*父项):QLineEdit(父项)
{ }
无效焦点事件(QFocusEvent*事件)覆盖
{
QLineEdit::focusInEvent(事件);
发射聚焦素();
}
无效focusOutEvent(QFocusEvent*事件)覆盖
{
QLineEdit::focusOutEvent(事件);
发射focusOut();
}
信号:
无效聚焦素();
void focusOut();
};
类ExtendedLineEdit:publicqwidget
{
Q_对象
公众:
显式ExtendedLineEdit(QWidget*parent=nullptr);
受保护的:
布尔事件过滤器(QObject*obj,QEvent*event)覆盖;
私人:
void setupWidget();
LineEdit*LineEdit;
QWidget*showableWidget;
QPushButton*ToupperCase按钮;
QPushButton*toLowercaseButton;
QWidget*父母;
};
源文件:
#include <QObject>
#include <QWidget>
#include <QLineEdit>
#include <QBoxLayout>
#include <QPushButton>
#include <QFocusEvent>
class LineEdit : public QLineEdit
{
Q_OBJECT
public:
LineEdit(QWidget *parent) : QLineEdit(parent)
{ }
void focusInEvent(QFocusEvent *event) override
{
QLineEdit::focusInEvent(event);
emit focusIn();
}
void focusOutEvent(QFocusEvent *event) override
{
QLineEdit::focusOutEvent(event);
emit focusOut();
}
signals:
void focusIn();
void focusOut();
};
class ExtendedLineEdit : public QWidget
{
Q_OBJECT
public:
explicit ExtendedLineEdit(QWidget *parent = nullptr);
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
private:
void setupWidget();
LineEdit *lineEdit;
QWidget *showableWidget;
QPushButton *toUppercaseButton;
QPushButton *toLowercaseButton;
QWidget *parent;
};
#include "ExtendedLineEdit.h"
#include <QPoint>
ExtendedLineEdit::ExtendedLineEdit(QWidget *parent)
: QWidget(parent)
, parent(parent)
{
setupWidget();
}
bool ExtendedLineEdit::eventFilter(QObject *obj, QEvent *event)
{
Q_UNUSED(obj)
if (event->type() == QEvent::MouseButtonRelease ||
event->type() == QEvent::MouseButtonPress ||
event->type() == QEvent::MouseButtonDblClick)
{
lineEdit->setFocus();
}
return false;
}
void ExtendedLineEdit::setupWidget()
{
auto mainLayout = new QBoxLayout(QBoxLayout::Direction::TopToBottom, this);
this->setLayout(mainLayout);
lineEdit = new LineEdit(this);
mainLayout->addWidget(lineEdit);
showableWidget = new QWidget(parent);
showableWidget->setAutoFillBackground(true);
showableWidget->setPalette(QPalette(QPalette::Background, Qt::white));
showableWidget->hide();
auto bottomLayout = new QBoxLayout(QBoxLayout::Direction::LeftToRight, showableWidget);
showableWidget->setLayout(bottomLayout);
toUppercaseButton = new QPushButton("to uppercase", this);
toUppercaseButton->installEventFilter(this);
connect(toUppercaseButton, &QPushButton::clicked,
this, [&]{
lineEdit->setText(lineEdit->text().toUpper());
});
toLowercaseButton = new QPushButton("to lowercase", this);
toLowercaseButton->installEventFilter(this);
connect(toLowercaseButton, &QPushButton::clicked,
this, [&]{
lineEdit->setText(lineEdit->text().toLower());
});
bottomLayout->addWidget(toUppercaseButton);
bottomLayout->addWidget(toLowercaseButton);
connect(lineEdit, &LineEdit::focusIn,
this, [&]{
auto size = lineEdit->size();
auto position = QWidget::mapTo(parent, lineEdit->pos());
showableWidget->setGeometry(position.x(),
position.y() + size.height(),
size.width(),
40);
showableWidget->show();
});
connect(lineEdit, &LineEdit::focusOut,
showableWidget, &QWidget::hide);
}
#包括“ExtendedLineEdit.h”
#包括
ExtendedLineEdit::ExtendedLineEdit(QWidget*父项)
:QWidget(父项)
,家长(家长)
{
setupWidget();
}
bool ExtendedLineEdit::eventFilter(QObject*obj,QEvent*event)
{
Q_未使用(obj)
如果(事件->类型()==QEvent::MouseButtonRelease||
事件->类型()==QEvent::MouseButtonPress||
事件->类型()==QEvent::MouseButtonDblClick)
{
lineEdit->setFocus();
}
返回false;
}
void ExtendedLineEdit::setupWidget()
{
auto Main布局=新的QBoxLayout(QBoxLayout::Direction::TopToBottom,this);
此->设置布局(主布局);
lineEdit=新建lineEdit(此);
mainLayout->addWidget(lineEdit);
showableWidget=新的QWidget(父项);
showableWidget->setAutoFillBackground(真);
showableWidget->setPalette(Qpalete(Qpalete::Background,Qt::white));
showableWidget->hide();
自动底部布局=新的QBoxLayout(QBoxLayout::Direction::LeftToRight,showableWidget);
showableWidget->setLayout(底部布局);
toUppercaseButton=新的QPushButton(“到大写”,this);
toUppercaseButton->installEventFilter(此);
连接(toUppercaseButton,&QPushButton::单击,
这个,[&]{
lineEdit->setText(lineEdit->text().toUpper());
});
toLowercaseButton=新的QPushButton(“to lowercase”,this);
toLowercaseButton->installEventFilter(此选项);
连接(toLowercaseButton,&QPushButton::单击,
这个,[&]{
lineEdit->setText(lineEdit->text().toLower());
});
bottomLayout->addWidget(toUppercaseButton);
底部布局->添加小部件(toLowercaseButton);
连接(lineEdit,&lineEdit::focusIn,
这个,[&]{
自动大小=行编辑->大小();
auto position=QWidget::mapTo(父级,lineEdit->pos());
showableWidget->setGeometry(position.x(),
position.y()+size.height(),
size.width(),
40);
showableWidget->show();
});
连接(lineEdit,&lineEdit::focusOut,
showableWidget,&QWidget::hide);
}
结果:
#include <QObject>
#include <QWidget>
#include <QLineEdit>
#include <QBoxLayout>
#include <QPushButton>
#include <QFocusEvent>
class LineEdit : public QLineEdit
{
Q_OBJECT
public:
LineEdit(QWidget *parent) : QLineEdit(parent)
{ }
void focusInEvent(QFocusEvent *event) override
{
QLineEdit::focusInEvent(event);
emit focusIn();
}
void focusOutEvent(QFocusEvent *event) override
{
QLineEdit::focusOutEvent(event);
emit focusOut();
}
signals:
void focusIn();
void focusOut();
};
class ExtendedLineEdit : public QWidget
{
Q_OBJECT
public:
explicit ExtendedLineEdit(QWidget *parent = nullptr);
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
private:
void setupWidget();
LineEdit *lineEdit;
QWidget *showableWidget;
QPushButton *toUppercaseButton;
QPushButton *toLowercaseButton;
QWidget *parent;
};
#include "ExtendedLineEdit.h"
#include <QPoint>
ExtendedLineEdit::ExtendedLineEdit(QWidget *parent)
: QWidget(parent)
, parent(parent)
{
setupWidget();
}
bool ExtendedLineEdit::eventFilter(QObject *obj, QEvent *event)
{
Q_UNUSED(obj)
if (event->type() == QEvent::MouseButtonRelease ||
event->type() == QEvent::MouseButtonPress ||
event->type() == QEvent::MouseButtonDblClick)
{
lineEdit->setFocus();
}
return false;
}
void ExtendedLineEdit::setupWidget()
{
auto mainLayout = new QBoxLayout(QBoxLayout::Direction::TopToBottom, this);
this->setLayout(mainLayout);
lineEdit = new LineEdit(this);
mainLayout->addWidget(lineEdit);
showableWidget = new QWidget(parent);
showableWidget->setAutoFillBackground(true);
showableWidget->setPalette(QPalette(QPalette::Background, Qt::white));
showableWidget->hide();
auto bottomLayout = new QBoxLayout(QBoxLayout::Direction::LeftToRight, showableWidget);
showableWidget->setLayout(bottomLayout);
toUppercaseButton = new QPushButton("to uppercase", this);
toUppercaseButton->installEventFilter(this);
connect(toUppercaseButton, &QPushButton::clicked,
this, [&]{
lineEdit->setText(lineEdit->text().toUpper());
});
toLowercaseButton = new QPushButton("to lowercase", this);
toLowercaseButton->installEventFilter(this);
connect(toLowercaseButton, &QPushButton::clicked,
this, [&]{
lineEdit->setText(lineEdit->text().toLower());
});
bottomLayout->addWidget(toUppercaseButton);
bottomLayout->addWidget(toLowercaseButton);
connect(lineEdit, &LineEdit::focusIn,
this, [&]{
auto size = lineEdit->size();
auto position = QWidget::mapTo(parent, lineEdit->pos());
showableWidget->setGeometry(position.x(),
position.y() + size.height(),
size.width(),
40);
showableWidget->show();
});
connect(lineEdit, &LineEdit::focusOut,
showableWidget, &QWidget::hide);
}
考虑到你在回答问题时付出的巨大努力,我真的有点难过。。。然而,距离我的初衷还有一分钟。我要找的是一个小弹出窗口,当它获得焦点时会显示在行编辑旁边(比如
QCompleter
)。例如,如果将行编辑合并到项目视图中(作为代理),也可以这样做。@Kamajii-没问题,我喜欢在这里写答案。答案略有改变。如果您仍然对解决这个问题感兴趣,您可以在任何地方使用该示例(因为它显然是“原始的”)。