我正在使用Qt创建一个应用程序,它包含一个用作应用程序背景的小部件,以及一个浮动在上面的用户控制界面。
类似的例子是谷歌地图,地图在背景上,控件位于背景之上。
但问题是背景小部件可以更改为不同的小部件(有一个显示地图的小部件,另一个显示视频输入的小部件,......)
对于用户控制界面中的按钮也会发生同样的事情,它们与当前背景没有直接关系,可以通过dinamically进行更改。
我尝试过使用QStackedLayout,使用两个层,即后台小部件和用户控制界面。但是您无法与背景图层进行交互,因为前面的窗口小部件会阻止所有点击。
有什么建议吗?
答案 0 :(得分:2)
您可以使用QObject::installEventFilter()
函数将事件流的过滤器放置到接口窗口小部件,并拦截所有传入的鼠标单击事件。捕获这些事件后,使用过滤器功能将它们委派给后台窗口小部件,或将它们传递到前端接口按钮。您很可能必须使用鼠标单击的(x,y)坐标来确定事件是应该转到后台窗口小部件还是其中一个前景按钮窗口小部件。
另一种选择是从QAbstractButton
(或者你用于按钮的任何QWidget)创建一个派生类,并重新实现事件函数,以便在该窗口小部件上单击鼠标(即{{1等等)。当鼠标点击到达时,检查鼠标是否在按钮上,如果不是,请通过信号或QAbstractButton::mousePressEvent()
将事件发送到后台小部件。
答案 1 :(得分:1)
您的问题过于通用,无法给出具体答案,但最明显的解决方案是为系统的每个可能组件实现从QWidget继承的类。在您的示例中,我可以可视化2个不同的组件:背景和控件。背景将存储所有图像数据,如地图和视频,而控件将具有与系统交互的按钮。您甚至可以将背景分成不同的类来管理图像或视频。我建议使用继承自QObject的中央GUIController类来管理所有接口交互,例如连接信号/插槽或实现任何动画,这样您就可以添加/管理多个小部件而无需通过不同的.cpp。
编辑:根据您的评论,您的主要问题似乎是您的鼠标事件没有按预期传播到您的小部件。可能原因是您没有在组件之间设置父/子关系。确保在上面的自定义窗口小部件类中调用默认的QWidget构造函数:
CustoWidget(QWidget *parent = 0, Qt::WFlags flags = 0) : QWidget(parent, flags)
{
//your code here
}
创建Controller类时,设置组件之间的正确关系。在你的系统环境中,我认为所有组件都将作为Background子项添加,所以它看起来如下所示:
class Controller : public QObject
{
public:
Controller(QObject *parent = 0, Qt::WFlags flags = 0) : QObject(parent, flags)
{
wdg_back_= new BackWidget(this);
wdg_control_ = new Controls(wdg_back);
wdg_1_ = new GenericWidget(wdg_back);
//connect your signals/slots, etc
}
private:
BackWidget *wdg_back_;
Controls *wdg_control_;
GenericWidget *wdg_1_;
}
答案 2 :(得分:0)
好的,我终于找到了解决问题的方法。
我使用QStackedWidget的方法是错误的,背景上的小部件并不是可点击的,即使它可能已经完成,但它并不是我想要的。
最后,这就是我所做的:
QWidget *centralWidget = new QWidget(this);
setCentralWidget(centralWidget);
MapView *backgroundWidget = new MapView(centralWidget);
backgroundWidget->setMinimumSize(1024,600);
QGridLayout *controlsLayout = new QGridLayout(centralWidget);
MyControlWidget *control1 = new MyControlWidget(centralWidget);
control1->setMinimumSize(140,140);
control1->show();
controlsLayout->addWidget(control1,2,0);
所以我创建了一个QWidget,centralWidget,它将是背景和前景的父级。将背景设置为全屏,并在QGridLayout中组织控件,这不会影响backgroundWidget。
如果我点击一个控件,该控件将处理该事件,但点击一个空格会触发backgroundWidget上的鼠标事件,这就是我需要的。
我会测试一段时间,如果工作正常,我会关闭这个问题。