Qt 一直 将视频播放到窗口C 中时,则需要半透明透明窗口D非C的子窗口。窗口C 才可正常播放。如果想要 一个无论如何移动或者改变大小C窗口,半透明窗口D都可以悬浮于窗口C,当C被其他窗口遮挡时,D也不会展现。即就好像D是C的子窗口一样,Qt Cpp 源码如何实现?
时间: 2023-07-19 17:03:53 浏览: 78
你可以通过以下步骤实现:
1. 创建一个 QWidget 类型的窗口,命名为 C 窗口,并设置它为视频播放器。
2. 创建一个 QWidget 类型的窗口,命名为 D 窗口,并将其设置为半透明。
3. 将 D 窗口设置为 C 窗口的子窗口,这样 D 窗口就可以悬浮在 C 窗口上方了。
```
D->setParent(C, Qt::Dialog);
```
4. 在 C 窗口的 paintEvent 事件中绘制视频。
5. 在 D 窗口的 paintEvent 事件中绘制半透明效果。
6. 为了让 D 窗口始终保持在 C 窗口的顶部,你可以在 C 窗口的 resizeEvent 和 moveEvent 事件中重新设置 D 窗口的位置和大小。
```
void C::resizeEvent(QResizeEvent *event)
{
D->resize(event->size());
}
void C::moveEvent(QMoveEvent *event)
{
D->move(event->pos());
}
```
7. 如果 C 窗口被其他窗口遮挡,D 窗口也不会展现,这是由于它们属于同一个父窗口。你可以将 D 窗口设置为顶层窗口,这样它就不会被其他窗口遮挡了。
```
D->setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
D->show();
```
相关问题
Qt 已知 将视频播放到窗口C 中时,且一定不可以将半透明窗口D设置为C的子窗口。窗口C 才可正常播放。如果想要 一个无论如何移动或者改变大小C窗口,半透明窗口D都可以悬浮于窗口C,当C被其他窗口遮挡时,D也不会展现。即就好像D是C的子窗口一样,Qt Cpp 源码如何实现?
实现这个功能,可以使用Qt的Graphics View Framework。具体步骤如下:
1. 创建一个QGraphicsView对象作为窗口C,设置其背景为黑色(或者其他颜色),并将其设置为透明。
2. 创建一个QGraphicsScene对象,并将其设置为QGraphicsView的场景。
3. 在场景中添加一个QGraphicsPixmapItem对象,用于显示视频。
4. 创建一个QWidget对象作为窗口D,设置其背景为半透明的白色(或者其他颜色),并将其设置为透明。
5. 将QWidget对象添加到场景中,并设置其Z值,使其位于QGraphicsPixmapItem之上。
6. 在QGraphicsView中重写mousePressEvent、mouseMoveEvent和mouseReleaseEvent三个事件函数,实现窗口C的拖拽和缩放功能。
7. 在QGraphicsPixmapItem中重写boundingRect函数,返回其在场景中的边界矩形,从而使得窗口D可以自动跟随QGraphicsPixmapItem的位置和大小变化。
8. 在QWidget中重写paintEvent函数,绘制窗口D的内容。
下面是示例代码:(假设视频文件为test.mp4)
```
#include <QtWidgets>
#include <QtMultimedia>
class VideoPlayer : public QGraphicsView {
public:
VideoPlayer(QWidget *parent = nullptr) : QGraphicsView(parent) {
setStyleSheet("background-color: black"); // 设置背景为黑色
setWindowFlags(Qt::FramelessWindowHint); // 去掉边框
setAttribute(Qt::WA_TranslucentBackground); // 设置为透明
setDragMode(QGraphicsView::ScrollHandDrag); // 设置拖拽模式
setRenderHint(QPainter::Antialiasing); // 抗锯齿
QGraphicsScene *scene = new QGraphicsScene(this);
QGraphicsPixmapItem *item = new QGraphicsPixmapItem();
item->setPixmap(QPixmap(":/test.mp4")); // 加载视频
scene->addItem(item);
setScene(scene);
QWidget *widget = new QWidget();
widget->setStyleSheet("background-color: rgba(255, 255, 255, 128)"); // 设置半透明白色背景
widget->setAttribute(Qt::WA_TranslucentBackground); // 设置为透明
widget->setFixedSize(200, 100); // 设置固定大小
widget->move(10, 10); // 设置初始位置
widget->installEventFilter(this); // 安装事件过滤器
scene->addWidget(widget);
widget->raise(); // 将窗口D置于顶层
}
protected:
void mousePressEvent(QMouseEvent *event) override {
if (event->button() == Qt::LeftButton) {
m_lastPos = event->pos();
setCursor(Qt::ClosedHandCursor);
}
}
void mouseMoveEvent(QMouseEvent *event) override {
if (event->buttons() & Qt::LeftButton) {
QPoint delta = event->pos() - m_lastPos;
translate(delta.x(), delta.y());
m_lastPos = event->pos();
}
}
void mouseReleaseEvent(QMouseEvent *event) override {
if (event->button() == Qt::LeftButton) {
setCursor(Qt::ArrowCursor);
}
}
QRectF boundingRect() const override {
return sceneRect();
}
bool eventFilter(QObject *obj, QEvent *event) override {
if (event->type() == QEvent::Paint) {
QPainter painter((QWidget*) obj);
painter.setRenderHint(QPainter::Antialiasing);
painter.setPen(Qt::NoPen);
painter.setBrush(QBrush(QColor(255, 0, 0, 128))); // 绘制红色半透明矩形
painter.drawRect(10, 10, 180, 80);
return true;
}
return QGraphicsView::eventFilter(obj, event);
}
private:
QPoint m_lastPos;
};
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
VideoPlayer player;
player.resize(640, 480);
player.show();
return app.exec();
}
```
Qt 用一个半透明 顶级窗口B 附着在 窗口A的窗口位置,要保证A在移动的时候B一直在A上方
可以通过以下步骤实现:
1. 创建顶级窗口B,并设置其透明度为半透明。
2. 获取窗口A的位置和大小。
3. 将窗口B的位置设置为窗口A的位置,这样窗口B就会附着在窗口A的上方。
4. 监听窗口A的移动事件,当窗口A移动时,将窗口B的位置设置为窗口A的位置。
以下是示例代码:
```cpp
#include <QtWidgets>
class MainWindow : public QMainWindow
{
public:
MainWindow(QWidget *parent = nullptr) : QMainWindow(parent)
{
// 创建窗口A
QWidget *widgetA = new QWidget(this);
widgetA->setGeometry(100, 100, 300, 200);
widgetA->setStyleSheet("background-color: white;");
// 创建窗口B
QWidget *widgetB = new QWidget(this);
widgetB->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
widgetB->setAttribute(Qt::WA_TranslucentBackground);
widgetB->setGeometry(widgetA->geometry());
widgetB->setStyleSheet("background-color: rgba(255, 255, 255, 128);");
// 监听窗口A的移动事件
connect(widgetA, &QWidget::move, [=]() {
widgetB->move(widgetA->geometry().topLeft());
});
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
```
在上面的代码中,我们创建了一个主窗口,其中包含了两个子窗口widgetA和widgetB。widgetA是我们要附着的窗口,widgetB是半透明的顶级窗口。在widgetA的move事件中,我们将widgetB的位置设置为widgetA的位置,这样就能保证widgetB一直在widgetA上方。
阅读全文