作为一个跨平台的图形界面开发框架,Qt拥有强大的窗体开发能力。无论是小型工具还是大型应用程序,熟练运用Qt窗体类都能让你码出漂亮易用的GUI。今天,就让我们一同揭开Qt窗体开发的神秘面纱!


1、窗体基类QWidget

所有Qt窗体类都直接或间接地继承自QWidget。通过设置QWidget的各种属性和重写虚函数,我们就能自定义窗体的外观和行为。下面是一个简单的示例:

#include <QApplication>
#include <QWidget>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv); 
    QWidget window;
    window.resize(300, 200); // 设置初始大小
    window.setWindowTitle("Hello Qt!"); // 设置标题
    window.show(); // 显示窗体
    return app.exec();
}

2、控制窗体大小

除了在代码中设置窗体大小,我们还可以设置窗体的最小/最大尺寸、固定尺寸、以及在用户调整大小时的行为:

window.setMinimumSize(200,100); // 最小尺寸
window.setMaximumSize(800,600); // 最大尺寸
window.setFixedSize(400,300);   // 固定尺寸

// 调整大小时保持长宽比
window.setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);

3、窗体位置和背景颜色

新建的普通窗体默认会在屏幕中心显示,我们可以通过move()或geometry()方法改变其位置。另外,QWidget还提供了setPalette()方法来设置背景颜色等调色板:

window.move(100,100); // 移动窗体位置
window.setGeometry(50,50,400,300); // 设置窗体位置和大小

QPalette pal = palette(); 
pal.setColor(QPalette::Background, Qt::yellow); // 设置背景颜色
window.setPalette(pal);

4、无边框窗体

QWidget默认带有标题栏和边框,如果我们想创建无边框窗体,可以设置Qt::FramelessWindowHint标志:

window.setWindowFlags(Qt::FramelessWindowHint); // 无边框
window.setWindowFlags(Qt::WindowStaysOnTopHint); // 置顶显示

无边框窗体通常需要自己实现拖动、调整大小等操作,可以重写QWidget的鼠标事件处理函数来实现:
void MyWindow::mousePressEvent(QMouseEvent *event)
{
    // 鼠标左键按下,记录下鼠标的全局位置和窗体位置
    if (event->button() == Qt::LeftButton) {  
        m_dragPosition = event->globalPos() - frameGeometry().topLeft();
        event->accept();
    }
}

void MyWindow::mouseMoveEvent(QMouseEvent *event)
{
    // 鼠标移动时,拖动窗体
    if (event->buttons() & Qt::LeftButton) {
        move(event->globalPos() - m_dragPosition);
        event->accept();
    }
}

5、标题栏定制

Qt窗体的标题栏上默认有最小化、最大化和关闭按钮,我们可以通过setWindowFlags()来控制这些按钮的显示与否,也可以自定义标题栏的内容。

先移除默认按钮:

window.setWindowFlags(Qt::Window | Qt::CustomizeWindowHint);
window.setWindowFlags(window.windowFlags() & ~Qt::WindowMaximizeButtonHint);

然后在窗体上添加自定义控件作为标题栏,当鼠标在这些控件上点击并拖动时,就可以改变窗体位置了。

class TitleBar : public QWidget {
    Q_OBJECT
    ...
    QHBoxLayout *m_layout;

protected:
    void mousePressEvent(QMouseEvent *event) {
        // 实现窗体拖动
        m_dragPosition = event->globalPos() - window()->frameGeometry().topLeft();
        ...
    }

    void mouseMoveEvent(QMouseEvent *event) {
        // 根据鼠标移动位置调整窗体位置
        window()->move(event->globalPos() - m_dragPosition);
    }
};

6、窗体之间的交互

Qt应用程序中可能需要多个窗体,不同窗体之间可以通过信号-槽机制连接进行交互。比如下面的示例:

#include <QApplication>
#include <QWidget>
#include <QPushButton>

class ChildWindow : public QWidget {
    Q_OBJECT

public:
    ChildWindow(QWidget *parent = nullptr) 
        : QWidget(parent)  { ... }

signals:
    void showMainWindow();

private slots:
    void onClick() {
        emit showMainWindow();
        this->close();        
    }

private:
    QPushButton *m_button;
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    QWidget mainWindow;
    ChildWindow childWindow;

    QObject::connect(&childWindow, &ChildWindow::showMainWindow,
                     &mainWindow, &QWidget::show);
    childWindow.show();

    return app.exec();
}

7、字体和图标

最后,Qt提供了跨平台的字体和图标支持,我们可以在窗体上应用这些视觉效果:

QFont font("Microsoft YaHei", 12, QFont::Bold); 
window.setFont(font); // 设置字体

QPixmap pixmap(":/images/app_icon.png");
window.setWindowIcon(QIcon(pixmap)); // 设置图标

8、更多探索

以上只是Qt窗体编程的基础内容,如果你想进一步发挥Qt窗体的强大功能,还需深入探索:

  • 布局管理和自适应大小调整
  • 窗体层次结构和MDI多窗口
  • 使用QSS自定义窗体样式
  • 声明式UI与QPainter绘图

窗体编程是Qt的核心功能,掌握了这些技能就等于打开了Qt编程的大门。期待你在这个广阔的领域大展拳脚,开发出漂亮实用的应用程序!


03-21 01:51