Qt 界面开发问题汇总

目录

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

  • 全屏显示与还原

  • 隐藏任务栏显示

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

  • Qt设置窗体透明

  • 设置应用程序的字体

  • Qt 无边框窗口的两种实现

  • Qt设置活动窗口

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

  • 窗口关闭时释放内存

  • Qt捕捉窗口关闭事件

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

  • Enter退出问题

  • Esc退出问题

  • QWidget设置控件的层次关系

  • 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(); // 窗口显示返回truebool 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");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蝈蝈(GuoGuo)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值