QT 主窗口和子窗口相互切换,并最大化显示的示例

本文通过一个具体的QT5项目实例,详细介绍了信号与槽机制的实现过程,包括信号的定义、发射与槽的连接及响应等关键环节。

我的使用的环境:使用的QT版本是QT5.6.1。电脑windows系统是win7旗舰版。

文件列表:在这里插入图片描述
subwidget.h

#ifndef SUBWIDGET_H
#define SUBWIDGET_H


#include <QtWidgets/QWidget>
#include <QtWidgets/QPushButton>

class SubWidget : public QWidget
{
    Q_OBJECT

public:
    explicit SubWidget(QWidget *parent = 0);
    ~SubWidget();

    void sendSlot();

signals:
    /**
     * 信号必须要signals关键字来声明
     * 信号没有返回值, 但可以有参数
     * 信号就是函数的声明, 无需定义
     * 使用: emit mySignal();
     * 信号可以被重载
     */
    void mySignal();
    void mySignalParm(int, QString);

public slots:

private:
    QPushButton * bt;
};


#endif // SUBWIDGET_H

subwidget.cpp

#include "subwidget.h"
#include "widget.h"


SubWidget::SubWidget(QWidget *parent)
    : QWidget(parent)
{
    this->setParent(parent);

    this->setWindowTitle(QString("小弟"));
    //this->resize(QSize(500, 500));

    bt = new QPushButton(this);
    bt->setText(QString("切换到主窗口"));
    bt->move(QPoint(50, 50));

    connect(bt, &QPushButton::clicked, this, &SubWidget::sendSlot);

    this->  showMaximized();
}


SubWidget::~SubWidget()
{
}

void SubWidget::sendSlot()
{
    emit mySignal();
    emit mySignalParm(300, QString("已经切换到主窗口"));
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QtWidgets/QWidget>
#include <QtWidgets/QPushButton>
#include <QtCore/QDebug>
#include "subwidget.h"

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

signals:

public slots:
    void myButtonReleasedSlot();
    void myChangeWin();
    void myDealSub();
    void myDealSubParm(int, QString);


private:
    Ui::Widget *ui;

    QPushButton * bt1;
    QPushButton * bt2;
    QPushButton * bt3;

    SubWidget * sw;
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
       
    ui->setupUi(this);


        this->setParent(parent);
        this->setWindowTitle(QString::fromUtf8("老大"));
        this->resize(QSize(500, 500));

        bt1 = new QPushButton(this);
        bt1->setText(QString("关闭窗口"));
        bt1->move(QPoint(50, 50));

        /**
         * bt1: 信号发出者, 指针类型
         * &QPushButton::pressed: 信号的发射  &发送者的类名::信号名字
         * this: 信号接受者, 指针类型
         * &Widget::close: 信号的处理  &接收的类名::槽名字
         *
         */
        connect(bt1, &QPushButton::pressed, this, &Widget::close);

        bt2 = new QPushButton(this);
        bt2->setText(QString("隐藏关闭窗口按钮以及改变自身文本内容"));
        bt2->move(QPoint(100, 100));

        /**
         * Qt5: 槽和普通的C++成员函数几乎是一样的
         * 可以是虚函数,可以被重载,可以是public slots、protected slots、private slots,可以被其他C++成员函数直接调用
         * 唯一不同的是:槽还可以和信号连接在一起,在这种情况下,信号被发射时,会自动调用这个槽
         * 槽不需要信号传过来的参数时,可以不要参数;但槽函数一旦要参数,其参数个数,类型,顺序必须要和对应的信号保持一致。另外,槽函数的参数不能有缺省值。
         * 由于信号的返回值为void, 槽必须和信号的返回值保持一致, 因此槽的返回值为void
         *
         */
        connect(bt2, &QPushButton::released, this, &Widget::myButtonReleasedSlot);
        connect(bt2, &QPushButton::released, bt1, &QPushButton::hide);

        bt3 = new QPushButton(this);
        bt3->setText(QString("切换到子窗口"));
        bt3->move(QPoint(150, 150));

        sw = new SubWidget();
        connect(bt3, &QPushButton::released, this, &Widget::myChangeWin);

        void (SubWidget::*funSignal)() = &SubWidget::mySignal;
        void (SubWidget::*funSignalParm)(int, QString) = &SubWidget::mySignalParm;
        void (Widget::*funSlot)() = &Widget::myDealSub;
        void (Widget::*funSlotParm)(int, QString) = &Widget::myDealSubParm;
        connect(sw, funSignal, this, funSlot);
        connect(sw, funSignalParm, this, funSlotParm);

        /**
         * Lambda 表达式, 匿名函数对象
         * C++11 新增加的特性, 编译时需要添加参数C++11
         * Qt配合信号一起使用, 非常方便
         */
        QPushButton *bt4 = new QPushButton(this);
        bt4->setText(QString("Lambda表达式并统计次数"));
        bt4->move(QPoint(200, 200));
        int cout = 0;
        connect(bt4, &QPushButton::clicked, this,
            // = : 把外部所有局部变量、类中所有成员以值传递方式
            // this : 类中所有成员以值传递方式
            // & : 把外部所有局部变量, 引用符号
            [=](bool isCheck) mutable {
                cout++;
                bt4->setText(QString("点击次数: ") + QString::number(cout));
                qDebug() << QString("这是一个Lambda表达式测试输出").toStdString().c_str();
                qDebug() << QString("打印参数: ").toStdString().c_str() << isCheck;
            });

}

Widget::~Widget()
{
    //delete ui;
}


void Widget::myButtonReleasedSlot()
{
    if (bt2 != nullptr)
    {
        bt2->setText(QString("发送信号, 槽处理完成 ..."));
    }
}

void Widget::myChangeWin()
{
    this->hide();
    sw->show();
}

void Widget::myDealSub()
{
    this->show();
    sw->hide();
}

void Widget::myDealSubParm(int num, QString str)
{
    qDebug() << "num: " << num << " str: " << str.toUtf8().data();
    qDebug() << "num: " << num << " str: " << str.toStdString().c_str();

    qWarning() << "num: " << num << " str: " << str.toUtf8().data();
    qInfo() << "num: " << num << " str: " << str.toUtf8().data();
    //qFatal(str.toUtf8().data());
}

main.cpp

#include "widget.h"
#include <QApplication>


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    w.showMaximized();
    return a.exec();
}

subwidget.uiwidget.ui无需操作设计。
运行后:
在这里插入图片描述

在这里插入图片描述

参考:https://www.cnblogs.com/lsgxeva/p/7808906.html

<think>好的,用户想了解如何用Qt创建一个可以自动显示隐藏的窗口。首先,我需要明确用户的需求。他们可能希望主窗口窗口之间有某种交互,比如通过按钮点击或定时器来控制窗口显示隐藏。需要确定窗口的类型,是QWidget还是QDialog,因为不同的类型有不同的行为模式。 接下来,考虑如何实现自动显示隐藏。可能的实现方式包括使用定时器(QTimer)来周期性地切换窗口的可见性,或者通过事件触发,比如按钮点击。用户提到“自动”,所以定时器的可能性较大。需要演示如何创建窗口,设置其属性,通过信号槽机制连接定时器来控制显示隐藏。 然后,结构上需要分步骤说明。首先创建主窗口,添加触发按钮或设置定时器;然后创建窗口,确保其是独立窗口(设置Window标志);接着实现显示隐藏的逻辑,可能使用show()hide()方法;最后连接信号槽,比如按钮的clicked信号触发切换,或者定时器的timeout信号。 需要检查代码示例的正确性,确保使用Qt5或Qt6的语法,比如QWidget的构造函数是否需要父窗口参数。同时,提醒用户关于窗口类型的问题,比如使用Qt::Window标志使窗口独立,避免被主窗口的布局影响。可能还需要提到内存管理,如果窗口是动态创建的,需要适当管理其生命周期,防止内存泄漏。 另外,用户可能需要知道如何调整窗口的位置,比如相对于主窗口的位置,可以使用move()方法。或者是否需要模态对话框,但根据“自动显示隐藏”,可能不需要模态。还需要考虑多线程的情况,但一般情况下,使用定时器在主线程中处理即可,避免复杂化。 最后,总结关键点:使用QTimer、正确设置窗口标志、信号槽连接、显示隐藏方法。确保代码示例简洁,注释清晰,用户能够复制运行。可能还需要提醒一些常见问题,比如窗口显示可能是因为没有设置正确的父对象或窗口标志,或者信号槽没有正确连接。</think>在Qt中创建自动显示/隐藏的窗口,可以通过定时器或事件触发来实现。以下是详细实现步骤代码示例: --- ### 方法1:定时器自动控制(间隔切换) ```cpp #include <QApplication> #include <QMainWindow> #include <QWidget> #include <QTimer> #include <QPushButton> class SubWindow : public QWidget { public: SubWindow(QWidget* parent = nullptr) : QWidget(parent) { setWindowTitle("窗口"); resize(200, 150); } }; class MainWindow : public QMainWindow { public: MainWindow(QWidget* parent = nullptr) : QMainWindow(parent) { // 创建主界面 QPushButton* btn = new QPushButton("启动自动切换", this); setCentralWidget(btn); resize(400, 300); // 创建窗口(不设置父对象) subWindow = new SubWindow(); subWindow->setWindowFlags(Qt::Window); // 关键:设置为独立窗口 // 设置定时器(每2秒切换) timer = new QTimer(this); connect(timer, &QTimer::timeout, [this]{ subWindow->isVisible() ? subWindow->hide() : subWindow->show(); }); // 按钮点击触发定时器 connect(btn, &QPushButton::clicked, [this]{ timer->start(2000); // 2000ms = 2秒 }); } private: SubWindow* subWindow; QTimer* timer; }; int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); } ``` --- ### 方法2:事件触发控制(鼠标悬停) ```cpp // 在MainWindow类中添加: protected: void enterEvent(QEvent* event) override { subWindow->show(); QMainWindow::enterEvent(event); } void leaveEvent(QEvent* event) override { subWindow->hide(); QMainWindow::leaveEvent(event); } ``` --- ### 关键点说明: 1. **窗口独立性** ```cpp subWindow->setWindowFlags(Qt::Window); ``` 确保窗口作为独立窗口显示(带标题栏、可单独关闭) 2. **显示/隐藏方法** - `show()` 显示窗口 - `hide()` 隐藏窗口 - `close()` 关闭销毁窗口 3. **内存管理** 如果窗口需要长期存在,建议: ```cpp subWindow->setAttribute(Qt::WA_DeleteOnClose, false); // 默认行为 ``` 若设置为`true`,关闭窗口时会自动销毁对象 --- ### 效果演示: 1. 主窗口显示"启动自动切换"按钮 2. 点击按钮后,窗口每2秒自动切换显示/隐藏状态 3. 窗口可独立操作(移动、最大化、最小化) --- ### 扩展建议: - 调整位置使用`subWindow->move(x, y)` - 添加动画效果(使用`QPropertyAnimation`) - 通过`QSettings`保存窗口状态 可根据具体需求选择定时器控制或事件驱动方式实现自动显示隐藏效果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值