一步步打造无frame的Qt自定义界面

Qt QFrame详解 QFrame继承QWidget,QFrame类是具有框架的小部件的基类,例如QLabel、QTextEdit,这些直接或间接继承QFrame类,都拥有框架。主要有下面几个作用:2.1设置框架矩形 2.2设置框架阴影 2.3设置框架形状 2.4设置样式 2.5设置线宽 2.6设置中线宽 以下是组合效果图下面展示了4种不一样的边框样式源码:... 阅读详情

一步步打造无frame的Qt自定义界面

标签(空格分隔): Qt frameless 无边框


Qt的一大优势就是QSS样式表,不过在用的时候界面还是有些不太舒服的地方,比如丑陋的标题栏。这里记录下改造Qt界面的步骤。

平台

Qt5.7.0 Dialog空白工程

无边框化

既然标题栏很丑,那么就直接去掉算了。

    setWindowFlags( Qt::FramelessWindowHint );

拖动和缩放

无边框之后会造成新问题–界面拖动不了,而且本来可以缩放的界面也不能拖动缩放了。解决方法很多,对我等小白来说最简单的是用第三方类NcFramelessHelper,3句代码就可以完美解决问题。下载链接最后附上。

    #include "NcFramelessHelper.h"
//.....
    Dialog w;//
    w.setWindowFlags( Qt::FramelessWindowHint );
    NcFramelessHelper* fh = new NcFramelessHelper;
    fh->activateOn(&w);

效果是这样的

标题栏

取消了默认的标题栏不代表不需要标题栏,为了实现较为时髦的标题栏,可以从QWidgets派生一个,再添加到界面上去。
这里继续用第三方类State_Button

    State_Button* minBtn = new State_Button(this);
    minBtn->set_pixmap(QPixmap(":/min.png"));
    State_Button* maxBtn = new State_Button(this);
    maxBtn->set_pixmap(QPixmap(":/max.png"));
    State_Button* clostBtn = new State_Button(this);
    clostBtn->set_pixmap(QPixmap(":/close.png"));



    QHBoxLayout* btnGroupLayout = new QHBoxLayout;
    QHBoxLayout* titleLayout = new QHBoxLayout;

    btnGroupLayout->addWidget(minBtn, 0, Qt::AlignTop);
    btnGroupLayout->addWidget(maxBtn, 0, Qt::AlignTop);
    btnGroupLayout->addWidget(clostBtn, 0, Qt::AlignTop);

    titleLayout->addLayout(btnGroupLayout);

    setLayout(titleLayout);

效果是这样的

和普通标题栏有点像了,但位置还不对,另外还缺少左侧的icon、对话框标题,下面一个个加进去。
修改如下代码

    QLabel*icon = new QLabel();
    icon->setPixmap(QPixmap(":/icon.png"));
    icon->setFixedSize(16, 16);
    icon->setScaledContents(true);

    QLabel*title = new QLabel("这是标题栏文字");

    State_Button* minBtn = new State_Button(this);
    minBtn->set_pixmap(QPixmap(":/min.png"));
    State_Button* maxBtn = new State_Button(this);
    maxBtn->set_pixmap(QPixmap(":/max.png"));
    State_Button* clostBtn = new State_Button(this);
    clostBtn->set_pixmap(QPixmap(":/close.png"));

    QHBoxLayout* titleLayout = new QHBoxLayout;

    titleLayout->addWidget(icon, 0, Qt::AlignTop);
    titleLayout->addSpacing(5);

    titleLayout->addWidget(title, 0, Qt::AlignTop);
    titleLayout->addStretch();
    titleLayout->addWidget(minBtn, 0, Qt::AlignTop);
    titleLayout->addWidget(maxBtn, 0, Qt::AlignTop);
    titleLayout->addWidget(clostBtn, 0, Qt::AlignTop);

    setLayout(titleLayout);

运行效果是这样

到这里标题栏样式就差不多了,但没有按钮点击事件啊,继续添加代码,同时按照C++封装的思想,将标题栏封装成类。代码如下

//无边框界面标题栏类
class Title_Bar: public QWidget
{
    Q_OBJECT
public:
    Title_Bar(QWidget *parent = NULL);
    ~Title_Bar();

    QString get_text(){return title->text();}
    void set_text(const QString& text){title->setText(text);}
    bool is_window_maximized() const {return is_maxed;}
protected:
    void init();
private slots:
    void show_small();
    void show_max_restore();
    void close_window();

protected:
    void mousePressEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseDoubleClickEvent(QMouseEvent *event);

private:
    QHBoxLayout*    titleLayout;
    QLabel*         icon;
    QLabel*         title;
    State_Button*   menu_button;
    State_Button*   min_button;
    State_Button*   max_button;
    State_Button*   close_button;
    QRect           normal_rect;
    QPoint          click_pos;      //
    bool            left_pressed;   //left mouse pressed
    bool            is_maxed;       //window Maximized
};

Title_Bar::Title_Bar( QWidget* parent )
    :QWidget(parent)
    ,left_pressed(false)
    ,is_maxed(false)
{
    titleLayout     = new QHBoxLayout(this);

    icon            = new QLabel(this);
    title           = new QLabel(this);

    menu_button     = new State_Button(this);
    min_button      = new State_Button(this);
    max_button      = new State_Button(this);
    close_button    = new State_Button(this);

    //设置name以方便使用 CSS
    icon->setObjectName("title_bar_icon");
    title->setObjectName("title_bar_text");

    menu_button->setObjectName("title_bar_menu");
    min_button->setObjectName("title_bar_min");
    max_button->setObjectName("title_bar_max");
    close_button->setObjectName("title_bar_close");

    init();
}

Title_Bar::~Title_Bar()
{
}


void Title_Bar::init()
{
    //标题栏
    title->setText("这是标题栏");

    // 标题栏高度
    int titlebar_height = style()->pixelMetric(QStyle::PM_TitleBarHeight);
    setFixedHeight(titlebar_height);

    const int frame_width = 5;

    //layout
    titleLayout->addWidget(icon, 0, Qt::AlignVCenter);
    titleLayout->addSpacing(frame_width);
    titleLayout->addWidget(title, 0, Qt::AlignVCenter);
    titleLayout->addStretch();
    titleLayout->addWidget(menu_button, 0, Qt::AlignTop);
    titleLayout->addWidget(min_button, 0, Qt::AlignTop);
    titleLayout->addWidget(max_button, 0, Qt::AlignTop);
    titleLayout->addWidget(close_button, 0, Qt::AlignTop);

    titleLayout->setSpacing(1);
    titleLayout->setMargin(1);

    //icon
    icon->setPixmap(QPixmap(":/icon.png"));
    icon->setFixedSize(16, 16);
    icon->setScaledContents(true);


    //windows taskbar icon
    window()->setWindowIcon(QPixmap(":/icon.png"));
    //
    menu_button->set_pixmap(QPixmap(":/menu.png"));
    min_button->set_pixmap(QPixmap(":/min.png"));
    max_button->set_pixmap(QPixmap(":/max.png"));
    close_button->set_pixmap(QPixmap(":/close.png"));

    //
    setLayout(titleLayout);

    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

    //
    connect(min_button, SIGNAL(clicked()), this, SLOT(show_small()));
    connect(max_button, SIGNAL(clicked()), this, SLOT(show_max_restore()));
    connect(close_button, SIGNAL(clicked()), this, SLOT(close_window()));

}

void Title_Bar::show_max_restore()
{
    if (is_maxed)
    {
        is_maxed = false;
        window()->setGeometry(normal_rect);
        max_button->set_pixmap(QPixmap(":/max.png"));
    } else {
        is_maxed = true;
        normal_rect = window()->geometry();
        window()->setGeometry(QApplication::desktop()->availableGeometry());
        max_button->set_pixmap(QPixmap(":/restore.png"));
    }
}

void Title_Bar::mousePressEvent( QMouseEvent *e )
{
    QRect r = rect();
    r.adjust(5, 5, -5, -5);
    if (r.contains(e->pos()))   //5:边框大小,边框用来拉伸改变窗口大小
    {
        if (e->button() == Qt::LeftButton)
        {
            left_pressed = true;
            click_pos = mapToParent(e->pos());
            e->accept();
            return;
        }
    }

    e->ignore();
}

void Title_Bar::mouseMoveEvent( QMouseEvent *e )
{
    if (left_pressed && !is_maxed)
    {
        window()->move(e->globalPos() - click_pos);
        e->accept();
    }else{
        e->ignore();
    }
}

void Title_Bar::mouseReleaseEvent( QMouseEvent *e )
{
    left_pressed = false;
    e->ignore();
}

void Title_Bar::show_small()
{
    window()->showMinimized();
}
void Title_Bar::close_window()
{
    window()->close();
}
void Title_Bar::mouseDoubleClickEvent( QMouseEvent *e )
{
    show_max_restore();
    left_pressed = false;
}

效果如图,最小化、最大化、关闭、菜单、双击标题栏最大化最小化都可以实现

主题

下面继续美化,终于可以祭出Qt的大绝招–QSS了。还是从网上找到的资源。添加到项目里去

    QFile file(":/dark.qss");
    file.open(QFile::ReadOnly | QFile::Text);
    QTextStream stream(&file);
    setStyleSheet(stream.readAll());

好了,初步的美化就有了。

加几个Qss美化的控件吧。

    QGridLayout* gridLayout = new QGridLayout;
    gridLayout->setMargin(10);

    QLabel* label = new QLabel("sdf");
    label->setFont(QFont("微软雅黑",12));
    gridLayout->addWidget(label,0,0);

    QPushButton* btn = new QPushButton("sdf");
    btn->setFont(QFont("微软雅黑",12));
    gridLayout->addWidget(btn,0,1);

    QCheckBox* check = new QCheckBox("615651651");
    check->setFont(QFont("微软雅黑",12));
    check->setChecked(true);
    gridLayout->addWidget(check,0,2);

    QComboBox* combo = new QComboBox;
    combo->setFont(QFont("微软雅黑",12));
    combo->addItem("sfsfsd");
    combo->addItem("234234");
    combo->addItem("78678");
    gridLayout->addWidget(combo,0,3);

    QLineEdit* line = new QLineEdit;
    line->setFont(QFont("微软雅黑",12));
    line->setText("LineText");
    gridLayout->addWidget(line,0,4);

    QListWidget *listWidget = new QListWidget(this);
    listWidget->setFont(QFont("微软雅黑",12));

    listWidget->insertItem(0,"列表1");
    listWidget->insertItem(1,"列表2");
    listWidget->insertItem(2,"列表3");
    listWidget->insertItem(3,"列表4");
    listWidget->insertItem(4,"列表5");
    listWidget->setAlternatingRowColors(true);
    gridLayout->addWidget(listWidget,1,0,2,2);

    QGroupBox *groupBox = new QGroupBox(tr("按钮组"));

    QRadioButton *radio1 = new QRadioButton(tr("&Radio button 1"));
    QRadioButton *radio2 = new QRadioButton(tr("R&adio button 2"));
    QRadioButton *radio3 = new QRadioButton(tr("Ra&dio button 3"));

    radio1->setChecked(true);
    QVBoxLayout *vbox = new QVBoxLayout;
    vbox->addWidget(radio1);
    vbox->addWidget(radio2);
    vbox->addWidget(radio3);
    vbox->addStretch(1);
    groupBox->setLayout(vbox);
    gridLayout->addWidget(groupBox,1,2,3,1);

    QTableWidget *table = new QTableWidget(3,2);
    table->setFont(QFont("微软雅黑",12));
    table->setAlternatingRowColors(true);
    table->setWindowTitle("VIP List");
    QStringList headerList;
    headerList << "No." << "姓名" ;
    table->setHorizontalHeaderLabels(headerList);
    //table->verticalHeader()->setVisible(false);
    table->horizontalHeader()->setStretchLastSection(true);


    table->setItem(0,0,new QTableWidgetItem("0"));
    table->setItem(1,0,new QTableWidgetItem("1"));
    table->setItem(2,0,new QTableWidgetItem("2"));


    table->setItem(0,1,new QTableWidgetItem("小王"));
    table->setItem(1,1,new QTableWidgetItem("小龙"));
    table->setItem(2,1,new QTableWidgetItem("小李"));
    gridLayout->addWidget(table,1,3,4,2);

    layout->addLayout(gridLayout);
    setLayout(layout);

效果是这样的

最后附上全部代码和资源

转载请注明出处

【Qt笔记】QFrame控件详解 QFrame是Qt框架中一个重要的控件类,主要用于在图形用户界面(GUI)中创建具有边框的框架。它不仅提供了丰富的边框样式、阴影效果和线宽设置,还允许开发者通过子类化来创建自定义的框架样式。 阅读详情

相关推荐

Qt与OpenCV集成开发:从环境配置到实时视频处理应用实战

在桌面应用开发中,图形用户界面(GUI)与底层图像处理能力的结合是构建高效工具的关键。Qt框架以其强大的跨平台GUI能力著称,而OpenCV则是计算机视觉领域的事实标准库,专注于图像处理、视频分析和机器学习。通过将两者集成,开发者可以构建出既能提供友好交互界面,又能执行复杂视觉计算的应用,如工业质检、安防监控和视频编辑软件。其技术价值在于实现了界面逻辑与数据处理逻辑的解耦,通过多线程架构(如生产者-消费者模型)确保UI流畅性与处理实时性。应用场景广泛覆盖需要实时图像流处理的领域。本文聚焦于**环境搭建**与

weixin_34205826的博客 386

Qt之自定义界面(窗体缩放-跨平台终极版)

简述 通过上一节内容,我们实现了窗体的缩放,功能很不错,但是很遗憾-不支持跨平台!如果对于多平台来说,这是一个硬伤,所以,我们急需要一个能够支持跨平台的实现方案。 在网上看到过很多不同的实现方式,多多少少会存在一些问题-要么融合度太高、要么不能很好地进行移动、缩放。基于前人的分享与总结,最后,我花了很长时间来完善。独乐乐不如众乐乐,...

weixin_34061555的博客 896

Qt+FFmpeg+OpenGL视频播放器:C++类封装与多线程架构设计

视频播放器是现代多媒体应用的核心组件,其底层原理涉及音视频数据的解封装、解码与渲染流水线。通过FFmpeg实现高效的媒体解码,结合OpenGL进行高性能图形渲染,是构建跨平台播放器的常见技术方案。在工程实践中,合理的架构设计能显著提升代码的可维护性与扩展性。本文聚焦于如何将FFmpeg API与OpenGL渲染逻辑封装成职责清晰的C++类,并利用Qt的信号槽机制实现**多线程同步**与**资源管理**,解决播放卡顿、内存泄漏等典型问题,为开发稳定流畅的桌面端视频播放应用提供实践参考。

germmy-神一样的开发 351

JS组件系列——自己动手封装bootstrap-treegrid组件

前言:最近产品需要设计一套相对完整的组织架构的解决方案,由于组织架构涉及到层级关系,在表格里面展示层级关系,自然就要用到所谓的treegrid。可惜的是,一些轻量级的表格组件本身并没有自带树形表格的功能,比如bootstrapTable就没有这个功能,怎么办呢?如果是jqgrid、easyUI的表格,treegrid的效果可以说是轻而易举就能解决,而项目目前用的就是bootstrapTable,不...

weixin_34320159的博客 294

Python GUI开发进阶:从Tkinter定制到PyQt5实战,打造现代桌面应用

图形用户界面(GUI)是连接用户与软件功能的重要桥梁,其核心在于通过视觉元素和交互逻辑提供直观的操作体验。在Python生态中,Tkinter作为标准库提供了基础的GUI构建能力,而PyQt5等第三方库则凭借其丰富的控件和强大的渲染引擎,实现了更专业、更现代的界面表现。掌握GUI开发不仅能提升脚本的易用性,更是构建独立桌面应用、数据可视化工具及跨平台解决方案的关键技术。通过样式定制、布局管理和事件驱动编程,开发者可以高效实现从基础工具到商业级软件的界面需求。本文聚焦于**Tkinter深度定制**与**Py

weixin_34112181的博客 290

Python桌面宠物开发实战:从零打造可交互的蓝色大肥鱼桌宠

桌面宠物(Desktop Pet)是一种运行在操作系统桌面上的小型动画程序,它通过图形界面技术实现卡通形象的展示与交互。其核心原理在于利用GUI框架创建无边框透明窗口,并结合精灵动画与状态机来模拟生物行为,为用户提供趣味性的桌面陪伴体验。在技术价值上,这类项目不仅能够提升开发者的图形编程与事件处理能力,更是将编程创意转化为可视化成果的绝佳实践。常见的应用场景包括工作专注提醒、桌面美化装饰以及轻量级娱乐工具等。本文以Python为开发语言,结合PyQt5图形库,详细解析如何构建一个具备动画播放、鼠标拖拽交互及

weixin_33768481的博客 487

Qt优秀开源项目之七:Qt实现无边框窗口FramelessWindow

推荐公司同事ericzh开源的FramelessHelper,github地址:https://github.com/qtdevs/FramelessHelper 如图所示,FramelessHelper实现了Windows系统上的Qt Quick和Qt Widgets无窗口,欢迎Fork、Star和Issue。

草上爬的博客 8944

PyQt5+Python打造工业级上位机:手把手教你实现数据读写功能

本文详细介绍了如何利用PyQt5和Python开发工业级上位机软件,重点讲解了数据读写功能的核心实现。内容涵盖自定义通信协议栈的设计、PyQt5界面架构的搭建以及多线程安全的数据交互,旨在帮助开发者构建稳定、高效的工业自动化监控系统。

m9n0o的博客 484

PyQT5,QTDesigner界面Frame布局设置方法(小白看)

PyQT设置布局(小白看)

weixin_63437585的博客 3167

基于YOLO26与PySide6的PCB缺陷智能检测系统实战指南

目标检测作为计算机视觉的核心技术,通过深度学习模型自动识别图像中的特定对象并定位其位置,其原理是让模型从大量标注数据中学习特征表达与空间关系。这项技术在工业自动化领域具有重要价值,能够大幅提升生产流程的智能化水平。在电子制造、精密加工等场景中,对产品进行高效、精准的质量检测是核心需求。本文聚焦于PCB(印刷电路板)缺陷检测这一具体应用,深入探讨如何利用YOLO26这一高效的目标检测模型,结合PySide6框架构建直观的图形界面,打造一个从数据准备、模型训练到系统集成的完整解决方案,以解决传统人工质检效率低、

weixin_34007906的博客 432

基于目标跟踪的半自动视频标注工具实战:告别逐帧手标

在计算机视觉领域,数据标注是模型训练的基础环节,而视频数据因其时间连续性,标注工作尤为繁重。传统手动逐帧标注效率低下,且难以保证目标在遮挡、进出场景下标注的一致性。多目标跟踪(MOT)技术为解决这一痛点提供了思路,其核心原理是通过在关键帧初始化目标,利用算法在后续帧中预测并关联目标轨迹,从而实现自动化或半自动化的标注。这项技术的工程价值在于,它能将标注人员从重复劳动中解放出来,专注于关键决策,极大提升数据集构建和算法迭代的效率。其应用场景广泛覆盖自动驾驶、行为分析、视频监控等需要大量时序标注数据的领域。本文

weixin_34005042的博客 289

如何从零开始配置RPCS3:3步打造完美的PS3游戏模拟环境

想要在电脑上重温经典PS3游戏,却对模拟器配置一头雾水?别担心,这篇开源项目配置指南将带你轻松掌握RPCS3的核心配置技巧。作为全球首个免费开源的PlayStation 3模拟器,RPCS3让你能在Windows、Linux、macOS和FreeBSD系统上畅玩PS3游戏。我们将从基础配置到高级优化,一步步为你打造最佳游戏体验。 ## 场景引入:你的第一个PS3游戏之夜 想象一下,你刚刚下载了

gitblog_00014的博客 499

FramelessHelper:基于Qt的无框架窗口类,完整功能

无框助手 基于Qt的无框架窗口类,功能齐全。 需求:Qt 5.9.6 +

Qt调用FFmpeg实现视频批量截图:QProcess与命令行工具集成实战

在桌面应用开发中,进程间通信是扩展应用功能的重要手段。QProcess作为Qt框架中用于启动和管理外部进程的核心类,为GUI程序调用命令行工具提供了桥梁。通过信号槽机制实现异步交互,开发者可以保持界面响应性,同时利用外部工具的强大功能。这一技术方案在多媒体处理、文件批量操作等场景中具有重要价值,尤其适合与FFmpeg这类专业命令行工具结合。FFmpeg作为多媒体处理的瑞士军刀,通过QProcess调用其命令行接口,能够实现视频批量截图、格式转换等复杂任务。本文以视频批量截图工具为例,详细展示了如何通过QPr

weixin_34009794的博客 468

framelesshelper:Qt小部件和Qt Quick应用程序的无框架窗口。 支持Win32,X11,Wayland和macOS

framelesshelper:Qt小部件和Qt Quick应用程序的无框架窗口。 支持Win32,X11,Wayland和macOS

ALTERA MAX10 FPGA 串口远程升级实战:从原理到烧录的避坑指南

本文详细解析了ALTERA MAX10 FPGA如何通过串口实现远程升级。文章从工程师实战经验出发,深入剖析了MAX10片内Flash的双镜像备份原理、CONFIG_SEL引脚启动机制,并重点介绍了使用On-Chip Flash IP核进行擦写操作的核心流程。同时,提供了从Quartus工程配置、RPD文件生成、串口协议设计到驱动代码编写的完整避坑指南,旨在帮助开发者稳定、高效地完成远程升级功能部署。

weixin_29197699的博客 273

基于MC68HC908QT4的DiSEqC卫星开关设计:协议解析与嵌入式实现

在卫星通信与嵌入式系统领域,总线协议是实现设备间标准化通信的核心技术。DiSEqC(数字卫星设备控制)协议作为一种在同轴电缆上叠加数字控制命令的总线标准,其原理是通过22kHz载波进行脉宽调制或BPSK调制,实现接收机与室外单元(如LNB、开关)的可靠对话。该技术的核心价值在于解决了多星接收、设备兼容性等工程难题,广泛应用于卫星电视接收系统。本文聚焦于一个具体的工程实践案例:基于资源受限的Motorola MC68HC908QT4 8位微控制器,设计并实现一个兼容DiSEqC 1.0协议与老式模拟控制信号的

weixin_30808693的博客 666

箱式连续提升机

箱式连续提升机,是对具有高度差较大(>1500mm)的输送线之间进行连接,将箱式物资进行连续输送的提升(或下降)的输送设备,可根据输送线的具体输送要求作相应的参数设计。目前的箱式连续提升机种类比较多,常用的形式主要有Z型和C型,工作原理相同,只是入口和出口分别在两侧和同侧。

月生沧溟 1248

用Python Tkinter打造桌面天气预报应用:从API到打包全攻略

桌面应用开发是GUI编程与工程实践的经典结合。本文从桌面工具的基本需求出发,介绍如何利用Python内置的Tkinter构建轻量级桌面应用,并通过天气API完成实时数据获取与JSON解析。文章详细拆解了数据层、界面层与控制层的模块化设计,讲解如何用after机制实现定时刷新而不卡顿界面,同时涵盖请求超时、异常处理、配置管理等实用避坑经验。无论是想入门桌面开发,还是希望打造一个常驻桌面的天气信息工具,这套从API调用到界面渲染、再到打包发布的完整流程,都能帮助你快速落地自己的第一个实用GUI项目。

weixin_32642109的博客 271

学Simulink--特殊天气场景实例:基于Simulink的智能车辆雨天行驶仿真(感知与控制)

本文详细介绍了基于Simulink的智能车辆雨天行驶仿真系统。通过构建降雨-路面-传感器-控制全链路耦合模型,实现了雨天场景下的自适应控制。系统根据降雨强度动态调整路面附着系数和传感器性能参数,上层控制算法相应调整ACC安全距离、ESC增益等参数。仿真结果表明,系统能在不同降雨强度下自动降低车速、增大跟车距离,保持车辆稳定性。文章还提供了完整的Simulink建模流程、关键模型实现方法及工程实践要点,为全天候自动驾驶功能开发提供了有效的验证平台。

xiaoheshang_123的博客 167

信号与电源完整性5:轨道塌陷噪声/电源轨道噪声分析及降低解决方案

经过上一节关于串扰的分析,我们已经清楚,噪声问题不仅仅来源于信号网络;电源和地网络所产生的噪声,被反馈到其所在的元器件和信号网络时,其破坏力也是巨大的;本节所讨论的轨道塌陷噪声就是一个典型的实例。在经过电源的地网络的电流发生改变时,在电源和地之间的阻抗上将产生一个压降;由于该压降的产生,用电元件的电压将直接被拉低,甚至可能对电路产生功能性的错误。接下来硬小二将详细的分析电源轨道噪声和降低其的解决方法。...

fydar的博客 2241

C#与WPF打造半导体晶圆搬移上位机:通信、视觉与状态机实战

在工业自动化与半导体制造领域,设备上位机承担着调度控制、状态监控与数据追溯的关键角色。一套可靠的上位机系统,需要深入理解设备通信原理,掌握运动控制与视觉对位的协同机制,并借助状态机设计来保证复杂流程的稳定执行。C#与WPF凭借高效的异步处理能力和灵活的界面呈现,成为众多设备厂商构建国产化半导体装备控制软件的主流选择。从TCP粘包处理到坐标补偿算法,从ViewModel数据绑定到MES对接补传,这些工程实践直接影响产线稼动率与产品良率。本文基于真实晶圆与石墨岛搬移项目,系统梳理上位机在半导体设备中的落地路径,

weixin_34032621的博客 345

Unity3D实现自定义河流路径或泥石流路径

此工具是一个插件,插件很好用,可以根据地形编辑河流的走向以及宽度,也可以发挥想象编辑成其他的效果,比如泥石流效果,岩浆效果,小溪,或者大江或者大河等等博客将会介绍可以编辑河流的工具的使用。希望这篇博客对Unity的开发者有所帮助。大家好,我是心疼你的一切,不定时更新Unity开发技巧,觉得有用记得一键三连哦。提示:以下是本篇文章正文内容,下面案例可供参考本次总结的就是工具的使用, 有需要会继续增加功能不定时更新Unity开发技巧,觉得有用记得一键三连哦。么么哒!

心疼你的一切博客 5264
上一篇: OSG模型控制
下一篇: QCustomPlot鼠标跟随显示坐标值
洗洗睡去
博客等级 码龄19年 277粉丝 90原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值