Qt 界面开发问题汇总(持续更新)

窗口的最小化、最大化按钮自定义

setWindowFlags(Qt::CustomizeWindowHint);
setWindowFlags(Qt::WindowCloseButtonHint); // 只要关闭按钮
setWindowFlags(Qt::WindowFlags type)

全屏显示与还原

1、遮挡任务栏

// 这两个都可以!
showFullScreen(); // 设置窗口全屏显示
showMaximized(); // 设置窗口最大化显示

2、不遮挡任务栏

void showMaximize()
{
    // 若已经最大化
    if(is_max)
    {
        // 恢复界面位置,并设置按钮图标为最大化图标,提示“最大化”
        this->setGeometry(location);
        max_button->setIcon(QIcon("maxbtn"));
        max_button->setToolTip(tr("max"));
    } 
    else 
    {
        // 设定当前界面的位置,还原时使用
        location = this->geometry();
        // 获取桌面位置,设置为最大化,并设置按钮图标为还原图标,提示“还原”
        QDesktopWidget *desk = QApplication::desktop();
        this->setGeometry(desk->availableGeometry());
        max_button->setIcon(QIcon("restorbtn"));
        max_button->setToolTip(tr("restor"));
    }
    is_max = !is_max;
}

注:窗口既然可以最大化,当然还要进行还原,is_max 为一个 bool 值变量,表示窗口是否最大化,初始值为 false。location 为桌面的位置,每次最大化开始先记录当前的位置,等待还原时候使用。

扩展:

isFullScreen(); // 判断窗口当前是处于全屏状态还是非全屏状态
showNormal(); // 设置窗口恢复原来显示

隐藏任务栏显示

setWindowFlags(Qt::Tool | Qt::X11BypassWindowManagerHint);

绘制背景图片并且实现圆角效果

void paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QBrush brush;
    brush.setTextureImage(QImage(background_image)); // 背景图片
    painter.setBrush(brush);
    painter.setPen(Qt::black);  // 边框色
    painter.drawRoundedRect(this->rect(), 5, 5); // 圆角5像素
}

Qt设置窗体透明

1、全透明

setWindowOpacity(double value)。该函数用来设置窗体透明度,有效范围从 1.0 到 0.0,并且会影响子控件。默认情况下,此属性的值是 1.0(不透明)。

this->setWindowOpacity(0.7);

2、子控件透明

使用 Qt 样式表,background:rgba(r, g, b, opacity),rgb 是颜色值,opacity 是设置为半透明的透明度,有效范围从 1.0 到 0.0。使用样式表设置一张背景图,以及 widget 和 label 的透明度(设置透明度要指定对象,避免影响其他控件)

//子控件透明
this->setStyleSheet("#centralWidget{border-image:url(://timg.jpg);}"
"#label{background:rgba(255,255,0,0.4);}"
"#widget{background:rgba(255,0,0,0.3);}");

3、父窗口透明

情况一:背景无图片。设置属性 Qt::WA_TranslucentBackground 将 MainWindow 变为全透明,在 windows 上这个属性需配合 Qt::FramelessWindowHint 使用。然后设置 centralWidget 样式中的 opacity 调节父窗口的透明度并设置子控件不透明。

this->setWindowFlags(Qt::FramelessWindowHint);//需要去掉标题栏
this->setAttribute(Qt::WA_TranslucentBackground);
this>setStyleSheet("#centralWidget{background:rgba(0,255,255,0.4);}"
"#label{background:rgba(255,255,0,1);}"
"#widget{background:rgba(0,255,255,1);}");

情况二:背景有图片。仍然使用属性 Qt::WA_TranslucentBackground 将 MainWindow 变为全透明。然后在 paintevent 中将图片绘制在窗体上,并设置透明度。

void MainWindow::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    QPixmap pix("://timg.jpg");
    QPixmap scalePix = pix.scaled(this->width(), this->height(),
        Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    painter.setOpacity(0.4);
    painter.drawPixmap(0, 0, scalePix);
}

注:若设置背景属性失败,可尝试设置该属性解决:setAttribute(Qt::WA_StyledBackground);


设置应用程序的字体

QFont font("Courier", 10, QFont::Normal, false);
QApplication::setFont(font);

Qt 无边框窗口的两种实现

setWindowFlags(Qt::CustomizeWindowHint);
setWindowFlags(Qt::FramelessWindowHint);

两个函数都可以去掉标题栏,区别是第一个可以鼠标缩放窗口。


Qt设置活动窗口

遇到一个 Qt 窗口问题记录下,已经显示的窗口被其他窗口遮挡。再调用 show 无法将窗口激活显示到最前面。解决方式如下:

if(!this->isActiveWindow()) //判断是否是活动窗口
{
    this->activateWindow(); //设置成活动窗口
}

如何判断一个窗口是否关闭

bool QWidget::isVisible(); // 窗口显示返回true

bool QWidget::isHidden(); // 窗口隐藏返回true

如果 widget 设置了 Qt::WA_DeleteOnClose 的话,widget 调用 close() 会被 delete,这种情况可以在外部用一个 flag 记录和判断。


窗口关闭时释放内存

当用户关闭窗口时,其默认行为是隐藏,所以还会保留在内存中,解决方法是在构造函数中加入这个一句:setAttribute(Qt::WA_DeleteOnClose);

Qt::WA_DeleteOnClose 属性是可以在 QWidget 上进行设置并影响这个窗口部件的行为的标记之一。


Qt捕捉窗口关闭事件

有时候我们希望在关闭窗口之前做一些操作,例如保存缓存数据或向用户提示是否关闭窗口等等。由于一般的窗口都是继承自 QWidget, 那么我们可以通过覆盖 QWidget 中的虚函数closeEvent(QCloseEvent* event);来达到这个目的。

void MainWindow::closeEvent(QCloseEvent *event)  
{  
	QMessageBox::StandardButton button;  
    button=QMessageBox::question(this,tr("退出程序"),QString(tr("确认退出程序")),QMessageBox::Yes|QMessageBox::No);  

    if(button==QMessageBox::No)  
    {  
        event->ignore(); // 忽略退出信号,程序继续进行  
    }  

    else if(button==QMessageBox::Yes)  
    {  
        event->accept(); // 接受退出信号,程序退出  
    }  

    // TODO: 在退出窗口之前,实现希望做的操作  
}

Qt5实现鼠标点击窗口外部关闭该窗口

方式一:重写窗口。该方式最简单,但是有一个弊病,需要为每个要实现该功能的窗口都重写该函数。

bool Form::event(QEvent *event)
{
    if (event->type() == QEvent::ActivationChange)
    {
        if(QApplication::activeWindow() != this)
        {
            this->close();
        }
    }
 
    return QWidget::event(event);
}

方式二:使用事件过滤器

步骤一:为每个要实现该功能的窗口安装事件过滤器,一般在构造函数里安装:

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    //f和f1都是窗口类实例
    f=new Form;
    f1=new Form1;
    f->installEventFilter(this);
    f1->installEventFilter(this);    
}

步骤二:重写事件过滤函数:

bool Widget::eventFilter(QObject *watched, QEvent *event)
{
    if (event->type() == QEvent::ActivationChange)
    {
        if(watched == f || watched == f1)//需要实现该功能的控件
        {
            if(QApplication::activeWindow() != watched)
            {
                QWidget *w=static_cast<QWidget *>(watched);
                w->close();
            }
        }
    }
    return QWidget::eventFilter(watched, event);
}

Enter退出问题

我新建了一个 QDialog 窗口,里面有多个 QLabel 和 QLineEdit 和一个 Exit 退出按钮,但是编辑完 QLineEdit 按回车后窗口就马上退出了,后来发现是按钮默认设置成了 StrongFocus 的原因。

解决方法:
设置窗口中的退出按钮的focusPolicy属性为NoFocus


Esc退出问题

需要重写 QDialog 的keyPressEvent():

#include <QKeyEvent>

void MyDialog::keyPressEvent(QKeyEvent *event)
{
    switch (event->key())
    {
    case Qt::Key_Escape:  // 按下的为Esc键
        break;  // 不做反应直接退出
    default:
        QDialog::keyPressEvent(event);
    }
}

QWidget设置控件的层次关系

设置控件置于父窗口的顶部:widget->raise();

设置控件层次:widget->stackUnder(other_widget);

设置控件置于父窗口的底部:widget->lower();


Qt去掉按钮等控件的虚线框

方法1:可以通过代码ui->pushButton->setFocusPolicy(Qt::NoFocus)或在 Qt Creator 的属性列表中设置。

方法2:如果在嵌入式设备中需要通过按键切换控件,最简单的方法就是通过控件的 focus 来实现,就不能使用方法1了。此时可以通过 qss 样式表来去掉虚线框,代码如下所示:

ui->pushButton->setStyleSheet("outline: none");  

方法3:也是通过qss样式表来实现,代码如下所示:

ui->pushButton->setStyleSheet("padding: -1"); 

参考:

Qt之界面实现技巧

Qt设置窗体透明

QT5实现鼠标点击窗口外部关闭该窗口

Qt捕捉窗口关闭事件

Qt按回车键和Esc键窗口退出问题

Qt:QWidget设置控件的层次关系

Qt如何去掉按钮等控件的虚线框(焦点框)(三种办法)


posted @ 2019-07-08 10:58  fengMisaka  阅读(2660)  评论(0编辑  收藏  举报