Qt Demo(3) 之 deepseek 帮我写的关于图像显示的小界面

Qt Demo(3) 之 deepseek 帮我写的关于图像显示的小界面

  • 一个完整的图像浏览器实现,支持缩放、拖拽和坐标显示功能。
  • 实现提供了一个功能完整、界面美观的图像浏览器,展示了 QGraphicsView、QGraphicsScene 和 QGraphicsPixmapItem 的核心功能和使用方法。
  • 界面如下图所示:

在这里插入图片描述

界面功能介绍

在这里插入图片描述

  • 关键实现细节

在这里插入图片描述

具体实现代码

  • imageviewer.h
#ifndef IMAGEVIEWER_H
#define IMAGEVIEWER_H

#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsPixmapItem>
#include <QWheelEvent>
#include <QMouseEvent>
#include <QPointF>

class ImageViewer : public QGraphicsView
{
    Q_OBJECT

public:
    explicit ImageViewer(QWidget* parent = nullptr);

    // 图像操作
    bool loadImage(const QString& fileName);
    void setImage(QImage& qimage);
    void clearImage();

    // 视图操作
    void zoomIn();
    void zoomOut();
    void resetView();
    void fitToWindow();

    // 获取当前状态
    bool hasImage() const;
    double scaleFactor() const;

signals:
    // 坐标变化信号
    void mousePositionChanged(const QPointF& scenePos);

protected:
    // 事件处理
    void wheelEvent(QWheelEvent* event) override;
    void mousePressEvent(QMouseEvent* event) override;
    void mouseMoveEvent(QMouseEvent* event) override;
    void mouseReleaseEvent(QMouseEvent* event) override;

private:
    // 初始化设置
    void setupView();

    // 缩放控制
    void scaleView(double factor);

    // 成员变量
    QGraphicsScene* scene;
    QGraphicsPixmapItem* pixmapItem;
    double currentScale;
    bool isDragging;
    QPoint lastDragPos;
};

#endif // IMAGEVIEWER_H
  • imageviewer.cpp
#include "imageviewer.h"
#include <QGraphicsScene>
#include <QGraphicsPixmapItem>
#include <QWheelEvent>
#include <QMouseEvent>
#include <QFileDialog>
#include <QMessageBox>
#include <QScrollBar>
#include <QtMath>

ImageViewer::ImageViewer(QWidget* parent)
    : QGraphicsView(parent), scene(nullptr), pixmapItem(nullptr),
    currentScale(1.0), isDragging(false)
{
    // 创建场景
    scene = new QGraphicsScene(this);
    setScene(scene);

    // 设置视图属性
    setupView();
}

void ImageViewer::setupView()
{
    // 设置渲染提示
    setRenderHint(QPainter::Antialiasing, true);
    setRenderHint(QPainter::SmoothPixmapTransform, true);
    setRenderHint(QPainter::TextAntialiasing, true);

    // 设置视图属性
    setDragMode(QGraphicsView::ScrollHandDrag);
    setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
    setResizeAnchor(QGraphicsView::AnchorUnderMouse);
    setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    setFrameShape(QFrame::NoFrame);

    // 设置背景
    setBackgroundBrush(QBrush(QColor(50, 50, 50)));
}

bool ImageViewer::loadImage(const QString& fileName)
{
    // 加载图像
    QPixmap pixmap(fileName);
    if (pixmap.isNull()) {
        return false;
    }

    // 清除现有内容
    clearImage();

    // 创建新的图像项
    pixmapItem = scene->addPixmap(pixmap);
    scene->setSceneRect(pixmap.rect());

    // 重置视图
    resetView();

    return true;
}

void ImageViewer::setImage(QImage& qimage)
{
    // 清除现有内容
    clearImage();

    QPixmap pixmap = QPixmap::fromImage(qimage);

    // 创建新的图像项
    pixmapItem = scene->addPixmap(pixmap);
    scene->setSceneRect(pixmap.rect());

    // 重置视图
    resetView();
}

void ImageViewer::clearImage()
{
    // 清除场景
    scene->clear();
    pixmapItem = nullptr;
    currentScale = 1.0;
}

void ImageViewer::zoomIn()
{
    scaleView(1.2);
}

void ImageViewer::zoomOut()
{
    scaleView(1.0 / 1.2);
}

void ImageViewer::resetView()
{
    // 重置变换
    //resetTransform();
    fitToWindow();
    currentScale = 1.0;

    // 如果存在图像,居中显示
    if (pixmapItem) {
        centerOn(pixmapItem);
    }
}

void ImageViewer::fitToWindow()
{
    if (pixmapItem) {
        // 适应窗口大小
        fitInView(scene->sceneRect(), Qt::KeepAspectRatio);

        // 更新当前缩放比例
        QTransform transform = this->transform();
        currentScale = transform.m11();
    }
}

bool ImageViewer::hasImage() const
{
    return pixmapItem != nullptr;
}

double ImageViewer::scaleFactor() const
{
    return currentScale;
}

void ImageViewer::scaleView(double factor)
{
    // 应用缩放
    scale(factor, factor);
    currentScale *= factor;
}

void ImageViewer::wheelEvent(QWheelEvent* event)
{
    if (pixmapItem) {
        // 计算缩放因子
        double factor = qPow(1.2, event->angleDelta().y() / 240.0);
        scaleView(factor);
        event->accept();
    }
    else {
        QGraphicsView::wheelEvent(event);
    }
}

void ImageViewer::mousePressEvent(QMouseEvent* event)
{
    if (event->button() == Qt::LeftButton && pixmapItem) {
        // 开始拖拽
        setCursor(Qt::ClosedHandCursor);
        lastDragPos = event->pos();
        isDragging = true;
        event->accept();
    }
    else {
        QGraphicsView::mousePressEvent(event);
    }
}

void ImageViewer::mouseMoveEvent(QMouseEvent* event)
{
    if (pixmapItem) {
        // 获取场景坐标
        QPointF scenePos = mapToScene(event->pos());

        // 发射坐标变化信号
        emit mousePositionChanged(scenePos);

        // 处理拖拽
        if (isDragging && (event->buttons() & Qt::LeftButton)) {
            // 计算移动距离
            QPoint delta = event->pos() - lastDragPos;
            lastDragPos = event->pos();

            // 移动滚动条
            horizontalScrollBar()->setValue(horizontalScrollBar()->value() - delta.x());
            verticalScrollBar()->setValue(verticalScrollBar()->value() - delta.y());

            event->accept();
        }
        else {
            QGraphicsView::mouseMoveEvent(event);
        }
    }
    else {
        QGraphicsView::mouseMoveEvent(event);
    }
}

void ImageViewer::mouseReleaseEvent(QMouseEvent* event)
{
    if (event->button() == Qt::LeftButton && isDragging) {
        // 结束拖拽
        setCursor(Qt::ArrowCursor);
        isDragging = false;
        event->accept();
    }
    else {
        QGraphicsView::mouseReleaseEvent(event);
    }
}
  • mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QStatusBar>
#include <QLabel>
#include "imageviewer.h"

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget* parent = nullptr);
    ~MainWindow();

private slots:
    void openImage();
    void updateStatusBar(const QPointF& scenePos);

private:
    void setupUI();
    void setupConnections();

    ImageViewer* imageViewer;  //图像显示
    QStatusBar* statusBar;    //状态栏
    QLabel* coordLabel;     //显示坐标
    QLabel* scaleLabel;     //显示缩放尺度

    // 工具栏动作
    QAction* openAction;      //打开图像
    QAction* zoomInAction;    //缩小
    QAction* zoomOutAction;   //放大
    QAction* resetViewAction; //恢复视野
    QAction* fitToWindowAction;   //适应窗口大小
};

#endif // MAINWINDOW_H
  • mainwindow.cpp
#include "mainwindow.h"
#include <QToolBar>
#include <QFileDialog>
#include <QMessageBox>

MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent)
{
    setupUI();
    setupConnections();
    setWindowTitle("Image Browser");
    resize(1000, 700);
}

MainWindow::~MainWindow()
{
}

void MainWindow::setupUI()
{
    // 创建图像查看器
    imageViewer = new ImageViewer(this);
    setCentralWidget(imageViewer);

    // 创建状态栏
    statusBar = new QStatusBar();
    setStatusBar(statusBar);

    coordLabel = new QLabel("Coordinates: (0, 0)");
    scaleLabel = new QLabel("Scale: 100%");
    statusBar->addPermanentWidget(coordLabel);
    statusBar->addPermanentWidget(scaleLabel);

    // 创建工具栏
    QToolBar* toolBar = new QToolBar("Main Toolbar");
    addToolBar(Qt::TopToolBarArea, toolBar);

    // 创建动作
    openAction = new QAction("Open", this);
    zoomInAction = new QAction("Zoom In", this);
    zoomOutAction = new QAction("Zoom Out", this);
    resetViewAction = new QAction("Reset View", this);
    fitToWindowAction = new QAction("Fit to Window", this);

    // 添加到工具栏
    toolBar->addAction(openAction);
    toolBar->addAction(zoomInAction);
    toolBar->addAction(zoomOutAction);
    toolBar->addAction(resetViewAction);
    toolBar->addAction(fitToWindowAction);

    // 设置样式
    setStyleSheet(R"(
        QMainWindow {
            background-color: #2b2b2b;
        }
        QToolBar {
            background-color: #3c3c3c;
            color: #ffffff;
            border: none;
            spacing: 3px;
            padding: 3px;
        }
        QToolButton {
            background-color: #4c4c4c;
            color: #ffffff;
            border: 1px solid #5c5c5c;
            border-radius: 3px;
            padding: 5px;
        }
        QToolButton:hover {
            background-color: #5c5c5c;
        }
        QStatusBar {
            background-color: #3c3c3c;
            color: #ffffff;
        }
        QLabel {
            color: #ffffff;
        }
    )");
}

void MainWindow::setupConnections()
{
    connect(openAction, &QAction::triggered, this, &MainWindow::openImage);
    connect(zoomInAction, &QAction::triggered, imageViewer, &ImageViewer::zoomIn);
    connect(zoomOutAction, &QAction::triggered, imageViewer, &ImageViewer::zoomOut);
    connect(resetViewAction, &QAction::triggered, imageViewer, &ImageViewer::resetView);
    connect(fitToWindowAction, &QAction::triggered, imageViewer, &ImageViewer::fitToWindow);
    connect(imageViewer, &ImageViewer::mousePositionChanged, this, &MainWindow::updateStatusBar);
}

void MainWindow::openImage()
{
    QString fileName = QFileDialog::getOpenFileName(this,
        "Open Image", "", "Image Files (*.png *.jpg *.jpeg *.bmp *.tif)");

    if (!fileName.isEmpty())
    {
        // 加载图像
        QImage qimage(fileName);
        if (qimage.isNull()) 
        {
            QMessageBox::warning(this, "Error", "Cannot load image file.");
        }
        else {
            imageViewer->setImage(qimage);
        }

       /* if (!imageViewer->loadImage(fileName)) {
            QMessageBox::warning(this, "Error", "Cannot load image file.");
        }*/
    }
}

void MainWindow::updateStatusBar(const QPointF& scenePos)
{
    // 更新坐标显示
    coordLabel->setText(QString("Coordinates: (%1, %2)").arg(scenePos.x()).arg(scenePos.y()));

    // 更新缩放比例显示
    int scalePercent = static_cast<int>(imageViewer->scaleFactor() * 100);
    scaleLabel->setText(QString("Scale: %1%").arg(scalePercent));
}
  • main.cpp
#include "mainwindow.h"
#include <QApplication>

int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}
把”# -*- coding: utf-8 -*- import gradio as gr import requests import time import threading # 添加全局状态跟踪 server_status = { "last_check": 0, "is_online": False, "loading": False } def check_server_status(): """检查模型服务器状态""" try: # 尝试检查状态端点 resp = requests.get("http://127.0.0.1:5000/status", timeout=3) if resp.status_code == 200: data = resp.json() # 检查服务是否运行且模型已加载 server_status["is_online"] = data.get("model_loaded", False) and data.get("status") == "running" server_status["last_check"] = time.time() return server_status["is_online"] except Exception as e: print(f"状态检查错误: {str(e)}") server_status["is_online"] = False return server_status["is_online"] def chat_interface(user_input, history): """处理用户输入并获取模型响应""" # 每30秒检查一次服务器状态 if time.time() - server_status["last_check"] > 30: threading.Thread(target=check_server_status).start() # 显示服务器状态提示 if not server_status["is_online"]: return "[系统] 模型服务器未响应,请检查服务是否已启动", history try: server_status["loading"] = True start_time = time.time() # 构建包含历史记录的完整上下文 full_context = "\n".join([f"User: {h[0]}\nAI: {h[1]}" for h in history]) full_context += f"\nUser: {user_input}" response = requests.post( "http://127.0.0.1:5000/generate", json={ "prompt": full_context, "max_length": 1024 # 添加长度限制 }, timeout=180 # 更长超时时间 ) if response.status_code == 200: ai_response = response.json().get("response", "No response") response_time = time.time() - start_time formatted_response = f"{ai_response}\n\n⏱️ 响应时间: {response_time:.2f}秒" return formatted_response, history else: return f"[错误] 服务器返回状态码 {response.status_code}", history except requests.exceptions.Timeout: return "[超时] 模型响应时间过长,请稍后重试", history except Exception as e: return f"[错误] 发生异常: {str(e)}", history finally: server_status["loading"] = False # 创建聊天界面 with gr.Blocks(title="DeepSeek-7B Chat") as demo: gr.Markdown("# 🧠 DeepSeek-7B 对话系统") gr.Markdown("> 输入问题后按Enter提交,模型可能需要10-30秒响应") with gr.Row(): chatbot = gr.Chatbot(label="对话历史", height=500) with gr.Column(): gr.Markdown("### 使用说明") gr.Markdown("1. 输入问题后按Enter提交") gr.Markdown("2. 长回复可能需要30秒以上") gr.Markdown("3. 清除按钮会重置对话") server_status_box = gr.Textbox(label="服务状态", value="正在检测服务...", interactive=False) msg = gr.Textbox(label="输入消息", placeholder="输入您的问题...") with gr.Row(): submit_btn = gr.Button("发送") clear = gr.Button("清除对话") retry_btn = gr.Button("重试连接") # 更新服务器状态函数 def update_status(): is_online = check_server_status() status = "🟢 在线" if is_online else "🔴 离线" return f"{status} | 最后检查: {time.strftime(&#39;%H:%M:%S&#39;)}" # 响应处理函数 def respond(message, chat_history): bot_message, _ = chat_interface(message, chat_history) chat_history.append((message, bot_message)) return "", chat_history # 清除对话 def clear_chat(): return [] # 重试连接 def retry_connection(): is_online = check_server_status() status = "🟢 在线" if is_online else "🔴 离线" return f"{status} | 最后检查: {time.strftime(&#39;%H:%M:%S&#39;)}" # 组件交互 msg.submit(respond, [msg, chatbot], [msg, chatbot]) submit_btn.click(respond, [msg, chatbot], [msg, chatbot]) clear.click(clear_chat, outputs=[chatbot]) retry_btn.click(retry_connection, outputs=[server_status_box]) # 初始化检查 demo.load(update_status, outputs=[server_status_box]) if __name__ == "__main__": # 初始状态检查 check_server_status() # 添加连接测试 print("="*50) print("测试模型服务器连接...") try: test_resp = requests.get("http://127.0.0.1:5000/status", timeout=3) print(f"连接测试结果: 状态码 {test_resp.status_code}") if test_resp.status_code == 200: print(f"服务状态: {test_resp.json()}") except Exception as e: print(f"连接失败: {str(e)}") print("="*50) # 启动界面 demo.launch( server_port=7860, share=False, server_name="0.0.0.0" )“改成# model_server/simple_ui.py import sys import threading from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QSplitter, QTabWidget, QTextEdit, QPushButton, QComboBox, QSlider, QLabel, QGroupBox) from PyQt5.QtCore import Qt, QTimer from PyQt5.QtGui import QPixmap, QImage import requests import numpy as np import cv2 class AIStudioUI(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("AI 工作室") self.setGeometry(100, 100, 1200, 800) # 主布局 main_widget = QWidget() main_layout = QHBoxLayout() main_widget.setLayout(main_layout) self.setCentralWidget(main_widget) # 左侧控制面板 control_panel = self.create_control_panel() main_layout.addWidget(control_panel, 1) # 占1份宽度 # 右侧主内容区 splitter = QSplitter(Qt.Vertical) # 输入面板 input_panel = self.create_input_panel() splitter.addWidget(input_panel) # 输出面板 output_panel = self.create_output_panel() splitter.addWidget(output_panel) # 状态面板 status_panel = self.create_status_panel() splitter.addWidget(status_panel) splitter.setSizes([300, 400, 100]) # 设置各区域高度比例 main_layout.addWidget(splitter, 3) # 占3份宽度 # 定时更新状态 self.timer = QTimer() self.timer.timeout.connect(self.update_system_status) self.timer.start(2000) # 每2秒更新一次状态 # 后续定义各面板创建函数... 对吗?
08-13
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

明月醉窗台

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

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

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

打赏作者

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

抵扣说明:

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

余额充值