当前位置:   article > 正文

扩展屏中子控件(QWidget)全屏显示方法_让qwidget充满整个窗口

让qwidget充满整个窗口

开发环境: Qt5.12.3 + MSVC2017

问题背景

视频监控类软件或是视频播放类软件都有一个全屏播放的功能,可以全屏播放视频画面。主窗口可以分别用以下两个接口实现。

void QWindow::showFullScreen()
void QWidget::showFullScreen()

如果用户电脑接了第二块屏幕作为扩展屏,默认情况下,无论软件在哪一个屏幕上,子窗口全屏都只会显示在第一块屏幕上显示,即主窗口和子窗口不在同一个屏幕上显示。

解决方案

简单粗暴,先直接上代码。

class MainWidget : public QWidget
{
    Q_OBJECT
public:
    explicit MainWidget(QWidget *parent = nullptr);
    
public slots:
    void slotFullScreen();
    
protected:
    bool eventFilter(QObject *watched, QEvent *event);
    
private:
    QWidget         *subWidget  = nullptr; 
    Qt::WindowState screenState = Qt::WindowNoState;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
MainWidget::MainWidget(QWidget *parent) : QWidget(parent)
{
    subWidget = new QWidget(this);
    subWidget->installEventFilter(this);
}

bool MainWidget::eventFilter(QObject *watched, QEvent *event)
{
    /* ESC退出全屏 */
    if (watched == subWidget && event->type() == QEvent::KeyPress)
    {
        QKeyEvent *keyEvent = dynamic_cast<QKeyEvent*>(event);
        if (Qt::Key_Escape == keyEvent->key() && Qt::WindowFullScreen == screenState)
        {
            subWidget->setWindowFlags(Qt::Widget);
            subWidget->show();
            screenState = Qt::WindowNoState;
            return true;
        }
    }

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

void MainWidget::slotFullScreen()
{
    /* 获取当前子控件的绝对坐标,确定当前窗口所在的屏幕 */
    QPoint curPoint = subWidget->mapToGlobal(QPoint(0,0));
	QScreen *curScreen = QGuiApplication::screenAt(curPoint);
	
    subWidget->setWindowFlags(Qt::Window | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
    subWidget->setFocus();

	/* 先更新子控件的屏幕坐标,然后设置子控件全屏显示 */
    subWidget->setGeometry(curScreen->availableGeometry());
    subWidget->resize(curScreen->geometry().size());
    subWidget->show();
    screenState = Qt::WindowFullScreen;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

关键函数是下面这两个,设置子控件所在的屏幕坐标,然后设置为子窗口的尺寸为屏幕尺寸。这样设置后,子窗口就会根据主窗口所在的屏幕进行全屏。

subWidget->setGeometry(curScreen->availableGeometry());
subWidget->resize(curScreen->geometry().size());

上述设置完成后,子窗口并不会显示,需要我们手动显示子窗口。

subWidget->show();

原因如下:

windowFlags : Qt::WindowFlags
Window flags are a combination of a type (e.g. Qt::Dialog) and zero or more hints to the window system (e.g. Qt::FramelessWindowHint).
If the widget had type Qt::Widget or Qt::SubWindow and becomes a window (Qt::Window, Qt::Dialog, etc.), it is put at position (0, 0) on the desktop. If the widget is a window and becomes a Qt::Widget or Qt::SubWindow, it is put at position (0, 0) relative to its parent widget.
Note: This function calls setParent() when changing the flags for a window, causing the widget to be hidden. You must call show() to make the widget visible again…

所以在slotFullScreen()eventFilter() 两个函数中设置子窗口的标志后,都需要重新调用show()来显示子窗口。

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号