.ext:key 按键移动窗体源代码

本文回顾了大学生活的点点滴滴,从青春的舞台到技术的成长之路,探讨了友情与爱情的意义,并以一段文字祭奠逝去的学生时代。
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="yidongtest.aspx.cs" Inherits="admin_commonpage_yidongtest" %>

<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 

<head id="Head1" runat="server">
    <title>KeyNav - Ext.NET Examples</title>
    <style type="text/css">
        .center
        {
             text-align:center;
             color:Purple;
        }
       
    </style>
    <script type="text/javascript">
        var isCenter = true;
        
        var move = function (win, dir) {
            var el = win.getEl();

//            if (!isCenter) {
//                el.alignTo(document, 'c-c', [0,0], true);
//                isCenter = true;
//                return;
//            }

            switch (dir) {
                case "left":
                    el.alignTo(document, "l", [0, -el.getHeight() / 2], true);
                    isCenter = false;
                    break;
                    
      
                    
                case "right":
                    el.alignTo(document, "r", [-el.getWidth(), -el.getHeight() / 2], true);
                    isCenter = false;
                    break;
                    
          

                case "up":
                    el.alignTo(document, "t", [-el.getWidth() / 2, 0], true);
                    isCenter = false;
                    break;
           

                case "down":
                    el.alignTo(document, "b", [-el.getWidth() / 2, -el.getHeight()], true);
                    isCenter = false;
                    break;
                    
         

                case "home":
                    el.center();
                    isCenter = true;               
                    break;
                    
         
            }
        }
    </script>
</head>
<body>
    <ext:ResourceManager ID="ResourceManager1" runat="server" />
    
    <ext:Window ID="Window1" runat="server" Width="450" Height="280" Closable="false" Title="Move Window" Padding="6">
        <Content>
            <ul>
             <li class="center">明月曾照半湖东
<li class="center">楔子</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;光阴似面,岁月如锅,一晃我们就在相遇的地点开始相互道别了。在这青春的日子里,我们有过憧憬,也有过迷茫;有过感动,也有过冲动;有过欢笑,也有过泪水。最后,当毕业的时节如约而至,我们都只能无奈地感慨一声,似水往昔浮流年。</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;大学,究竟是我们展现青春的舞台,还是埋葬青春的坟墓?回忆,究竟是成熟取代懵懂留下的印记,还是时间强奸过去留下的孽种?</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;或许,一些错过的人,一些做错的事,会在我们内心深处扎下一个死结。但请不要抱怨悔不当初,也不要回想如果当时。就让这个死结一直伴随着我们以后的道路,蓦然回首,你会发现,这也未尝不是一种人生的财富。</li>
   <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;关于友情,关于爱情,每个人都有自己的感悟。种了什么因,就会结什么果。驶过什么样的航线,就会到达什么样的彼岸。年少轻狂没有关系,无所作为也没有关系。关键是我们在笑过,哭过之后,都能够成长起来,这样就足够了。</li>    
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;当时明月在,曾照半湖东。在这里,我们每个人都能找到属于自己的影子。</li>
   <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;最后,谨以此文祭奠我们死去的学生时代。</li>
            </ul>
        </Content>            
    </ext:Window>
    <ext:KeyMap ID="KeyMap1" runat="server" Target="={document.body}">
        <ext:KeyBinding>
            <Keys>
                <ext:Key Code="A" />
            </Keys>
            <Listeners>
                <Event Handler="move(Window1, 'left');" />
            </Listeners>
        </ext:KeyBinding>    
        
        <ext:KeyBinding>
            <Keys>
                <ext:Key Code="D" />
            </Keys>
            <Listeners>
                <Event Handler="move(Window1, 'right');" />
            </Listeners>
        </ext:KeyBinding>
        
        <ext:KeyBinding>
            <Keys>
                <ext:Key Code="W" />
            </Keys>
            <Listeners>
                <Event Handler="move(Window1, 'up');" />
            </Listeners>
        </ext:KeyBinding>
        
        <ext:KeyBinding>
            <Keys>
                <ext:Key Code="S" />
            </Keys>
            <Listeners>
                <Event Handler="move(Window1, 'down');" />
            </Listeners>
        </ext:KeyBinding>
        
          <ext:KeyBinding>
            <Keys>
                <ext:Key Code="SPACE"/>
            </Keys>
            <Listeners>
                <Event Handler="move(Window1, 'home');" />
            </Listeners>
        </ext:KeyBinding>
    </ext:KeyMap>
    <ext:KeyNav ID="KeyNav1" runat="server" Target="={document.body}">
        <Left Handler="move(Window1, 'left');" />
        <Right Handler="move(Window1, 'right');" />
        <Up Handler="move(Window1, 'up');" />
        <Down Handler="move(Window1, 'down');" />
        <Home Handler="move(Window1, 'home');" />
        
    </ext:KeyNav>
            
    <%--<script type="text/javascript">
        var COLOUMN2 = function (value) { 
            return String.format('<img src="article_image.aspx?id={0}" id="myID" />', value);
        } 
    </script>--%>
</body>
</html>
# -*- coding: utf-8 -*- """ Word助手 - 基于 PyQt6 的批量 Word 处理工具 功能: 1. 批量 Word → PDF 2. 多个 Word 合并为一个 PDF 3. 统计页码 4. 提取总目录(含/不含页码) 运行前提: - 安装 Microsoft Word(2007+) - pip install pywin32 PyQt6 PyPDF2 """ import os import sys import threading from datetime import datetime # ============= PyQt6 Import =============== from PyQt6.QtCore import Qt, QTimer from PyQt6.QtGui import QPixmap, QBrush, QColor from PyQt6.QtWidgets import ( QApplication, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QLineEdit, QToolButton, QListWidget, QFileDialog, QMessageBox, QTableWidget, QTableWidgetItem, QCheckBox, QSpacerItem, QSizePolicy ) # 初始化 COM(用于调用 Word) import pythoncom from win32com.client import Dispatch, constants, gencache from PyPDF2 import PdfFileReader, PdfFileMerger # ==================== tools/common.py ==================== def getfilenames(filepath="", filelist_out=None, file_ext='all'): if filelist_out is None: filelist_out = [] try: for filename in os.listdir(filepath): fullpath = os.path.join(filepath, filename) if os.path.isdir(fullpath): getfilenames(fullpath, filelist_out, file_ext) else: _, ext = os.path.splitext(filename) if file_ext == '.doc': if ext.lower() in ['.doc', '.docx']: filelist_out.append(fullpath) elif file_ext == 'all' or ext == file_ext: filelist_out.append(fullpath) except Exception as e: print(f"遍历出错: {e}") # 排序:按“第X章”中的数字排序 filelist_out.sort(key=lambda x: extract_chapter_number(x)) return filelist_out def extract_chapter_number(path): import re match = re.search(r"第(\d+)章", os.path.basename(path)) return int(match.group(1)) if match else float('inf') # ==================== 核心功能模块 ==================== def word_to_pdf_batch(filelist, target_dir): """批量转换Word为PDF""" result = [] os.makedirs(target_dir, exist_ok=True) try: pythoncom.CoInitialize() gencache.EnsureModule('{00020905-0000-0000-C000-000000000046}', 0, 8, 4) word = Dispatch("Word.Application") word.Visible = False for path in filelist: base_name = os.path.splitext(os.path.basename(path))[0] pdf_path = os.path.join(target_dir, f"{base_name}.pdf") try: doc = word.Documents.Open(path, ReadOnly=1) doc.ExportAsFixedFormat( pdf_path, constants.wdExportFormatPDF, Item=constants.wdExportDocumentWithMarkup, CreateBookmarks=constants.wdExportCreateHeadingBookmarks ) doc.Close() result.append(pdf_path) except Exception as e: print(f"转换失败 {path}: {e}") word.Quit() except Exception as e: print("Word COM 初始化失败:", e) return -1 return result def get_pdf_page_count(pdf_path): """获取PDF页数""" try: with open(pdf_path, "rb") as f: reader = PdfFileReader(f) return reader.getNumPages() except Exception as e: print(f"读取页数失败: {e}") return 0 def merge_pdfs(pdf_list, output_path, add_bookmarks=True): """合并多个PDF""" merger = PdfFileMerger() for pdf in pdf_list: try: with open(pdf, 'rb') as f: reader = PdfFileReader(f) if reader.isEncrypted: continue short_name = os.path.splitext(os.path.basename(pdf))[0] merger.append(reader, bookmark=short_name if add_bookmarks else None) except Exception as e: print(f"跳过文件 {pdf}: {e}") merger.write(output_path) merger.close() def extract_outline_from_pdf(pdf_path, output_docx, include_page=True): """从PDF提取大纲写入Word""" try: pythoncom.CoInitialize() gencache.EnsureModule('{00020905-0000-0000-C000-000000000046}', 0, 8, 4) word_app = Dispatch("Word.Application") word_app.Visible = True doc = word_app.Documents.Add() with open(pdf_path, "rb") as f: reader = PdfFileReader(f) outlines = reader.getOutlines() items = [] def traverse(obj): if isinstance(obj, list): for item in obj: traverse(item) elif hasattr(obj, '/Title'): title = obj['/Title'] page_num = str(obj.get('/Page', 0) + 1) if include_page else "" line = f"{title}\t\t{page_num}" if include_page else title items.append(line + "\n") for item in outlines: traverse(item) for line in items: doc.Content.InsertAfter(line) doc.SaveAs(output_docx) doc.Close() word_app.Quit() return output_docx except Exception as e: print(f"提取目录失败: {e}") return None # ==================== 主窗体 ==================== class MainWindow(QWidget): def __init__(self): super().__init__() self.setWindowTitle("Word助手") self.resize(600, 400) self.setMaximumSize(600, 400) layout = QVBoxLayout() # 背景提示 tip = QLabel("欢迎使用 Word助手\n\n" "本程序会自动调用 Microsoft Word\n" "请先保存并关闭所有打开的 Word 文档") tip.setAlignment(Qt.AlignmentFlag.AlignCenter) tip.setStyleSheet("font-size: 14px; color: #333;") layout.addWidget(tip) # 按钮区 btn_layout = QHBoxLayout() self.btn_transform = QPushButton("Word转PDF") self.btn_page = QPushButton("统计页码") self.btn_list = QPushButton("提取总目录") self.btn_transform.clicked.connect(self.open_transform) self.btn_page.clicked.connect(self.open_page) self.btn_list.clicked.connect(self.open_list) btn_layout.addWidget(self.btn_transform) btn_layout.addWidget(self.btn_page) btn_layout.addWidget(self.btn_list) layout.addLayout(btn_layout) self.setLayout(layout) def open_transform(self): self.tw = TransformWindow() self.tw.show() def open_page(self): self.pw = PageWindow() self.pw.show() def open_list(self): self.lw = ListWindow() self.lw.show() # ==================== 子窗体:Word转PDF ==================== class TransformWindow(QWidget): def __init__(self): super().__init__() self.filelist = [] self.init_ui() def init_ui(self): self.setWindowTitle("Word转PDF") self.resize(800, 600) layout = QVBoxLayout() # 源目录 h1 = QHBoxLayout() h1.addWidget(QLabel("Word文档所在目录:")) self.src_edit = QLineEdit() self.src_btn = QToolButton() self.src_btn.setText("...") self.src_btn.clicked.connect(self.browse_source) h1.addWidget(self.src_edit) h1.addWidget(self.src_btn) layout.addLayout(h1) self.list_word = QListWidget() layout.addWidget(QLabel("待转换文件:")) layout.addWidget(self.list_word) # 目标目录 h2 = QHBoxLayout() h2.addWidget(QLabel("PDF保存目录:")) self.dst_edit = QLineEdit() self.dst_btn = QToolButton() self.dst_btn.setText("...") self.dst_btn.clicked.connect(self.browse_target) h2.addWidget(self.dst_edit) h2.addWidget(self.dst_btn) layout.addLayout(h2) # 操作按钮 op_layout = QHBoxLayout() op_layout.addSpacerItem(QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)) self.batch_btn = QPushButton("批量转换") self.merge_btn = QPushButton("合为一个PDF") self.batch_btn.clicked.connect(self.do_batch) self.merge_btn.clicked.connect(self.do_merge) op_layout.addWidget(self.batch_btn) op_layout.addWidget(self.merge_btn) layout.addLayout(op_layout) self.result_list = QListWidget() layout.addWidget(QLabel("转换结果:")) layout.addWidget(self.result_list) self.setLayout(layout) def browse_source(self): dir_ = QFileDialog.getExistingDirectory(self, "选择Word文档目录", "") if dir_: self.src_edit.setText(dir_) self.filelist = getfilenames(dir_, [], '.doc') self.list_word.clear() self.list_word.addItems([os.path.basename(f) for f in self.filelist]) def browse_target(self): dir_ = QFileDialog.getExistingDirectory(self, "选择PDF保存目录", "") if dir_: self.dst_edit.setText(dir_) def do_batch(self): if not self.filelist: QMessageBox.warning(self, "警告", "未选择任何Word文档!") return dst = self.dst_edit.text() if not dst or not os.path.exists(dst): QMessageBox.warning(self, "警告", "请选择有效的保存路径!") return def task(): results = word_to_pdf_batch(self.filelist, dst) self.result_list.clear() if results != -1: self.result_list.addItems(results) QMessageBox.information(self, "完成", f"成功生成 {len(results)} 个PDF文件。") else: QMessageBox.critical(self, "错误", "转换过程中发生COM错误。") threading.Thread(target=task, daemon=True).start() def do_merge(self): if not self.filelist: QMessageBox.warning(self, "警告", "未选择任何Word文档!") return dst = self.dst_edit.text() if not dst or not os.path.exists(dst): QMessageBox.warning(self, "警告", "请选择有效的保存路径!") return temp_dir = os.path.join(dst, "temp_pdfs") os.makedirs(temp_dir, exist_ok=True) def task(): pdfs = word_to_pdf_batch(self.filelist, temp_dir) if pdfs == -1: return merged = os.path.join(dst, "merged.pdf") merge_pdfs(pdfs, merged) # 清理临时文件 for p in pdfs: try: os.remove(p) except: pass self.result_list.clear() self.result_list.addItem(merged) QMessageBox.information(self, "完成", "已合并为 merged.pdf") threading.Thread(target=task, daemon=True).start() # ==================== 子窗体:统计页码 ==================== class PageWindow(QWidget): def __init__(self): super().__init__() self.filelist = [] self.init_ui() def init_ui(self): self.setWindowTitle("统计Word文档页码") self.resize(700, 500) layout = QVBoxLayout() h = QHBoxLayout() h.addWidget(QLabel("Word文档所在目录:")) self.src_edit = QLineEdit() self.src_btn = QToolButton() self.src_btn.setText("...") self.src_btn.clicked.connect(self.browse_source) h.addWidget(self.src_edit) h.addWidget(self.src_btn) layout.addLayout(h) self.list_word = QListWidget() layout.addWidget(QLabel("文档列表:")) layout.addWidget(self.list_word) self.table = QTableWidget(0, 2) self.table.setHorizontalHeaderLabels(["文件名", "页码"]) self.table.horizontalHeader().setStretchLastSection(True) layout.addWidget(self.table) foot = QHBoxLayout() foot.addWidget(QLabel("合计页码:")) self.total_label = QLabel("0") foot.addWidget(self.total_label) foot.addSpacerItem(QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)) self.exec_btn = QPushButton("开始统计") self.exec_btn.clicked.connect(self.start_count) foot.addWidget(self.exec_btn) layout.addLayout(foot) self.setLayout(layout) def browse_source(self): dir_ = QFileDialog.getExistingDirectory(self, "选择Word文档目录", "") if dir_: self.src_edit.setText(dir_) self.filelist = getfilenames(dir_, [], '.doc') self.list_word.clear() self.list_word.addItems([os.path.basename(f) for f in self.filelist]) def start_count(self): if not self.filelist: QMessageBox.warning(self, "警告", "没有可统计的文档!") return def task(): total = 0 result = [] temp_dir = os.path.join(os.path.dirname(self.filelist[0]), f"temp_{int(datetime.now().timestamp())}") os.makedirs(temp_dir, exist_ok=True) for fp in self.filelist: pdf_path = os.path.join(temp_dir, os.path.splitext(os.path.basename(fp))[0] + ".pdf") if word_to_pdf_batch([fp], temp_dir) and os.path.exists(pdf_path): pages = get_pdf_page_count(pdf_path) result.append((os.path.basename(fp), str(pages))) total += pages os.remove(pdf_path) try: os.rmdir(temp_dir) except: pass self.table.setRowCount(len(result)) for i, (name, p) in enumerate(result): self.table.setItem(i, 0, QTableWidgetItem(name)) self.table.setItem(i, 1, QTableWidgetItem(p)) self.total_label.setText(str(total)) QMessageBox.information(self, "完成", "页码统计完成!") threading.Thread(target=task, daemon=True).start() # ==================== 子窗体:提取目录 ==================== class ListWindow(QWidget): def __init__(self): super().__init__() self.filelist = [] self.generated_docx = "" self.init_ui() def init_ui(self): self.setWindowTitle("提取总目录") self.resize(700, 400) layout = QVBoxLayout() h = QHBoxLayout() h.addWidget(QLabel("Word文档所在目录:")) self.src_edit = QLineEdit() self.src_btn = QToolButton() self.src_btn.setText("...") self.src_btn.clicked.connect(self.browse_source) h.addWidget(self.src_edit) h.addWidget(self.src_btn) layout.addLayout(h) self.list_word = QListWidget() layout.addWidget(QLabel("文档列表:")) layout.addWidget(self.list_word) self.chk_page = QCheckBox("包含页码") self.chk_page.setChecked(True) layout.addWidget(self.chk_page) btn_h = QHBoxLayout() btn_h.addSpacerItem(QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)) self.extract_btn = QPushButton("开始提取") self.open_btn = QPushButton("打开文件") self.extract_btn.clicked.connect(self.extract) self.open_btn.clicked.connect(self.open_file) btn_h.addWidget(self.extract_btn) btn_h.addWidget(self.open_btn) layout.addLayout(btn_h) self.result_label = QLabel("还未提取...") layout.addWidget(QLabel("目录文件保存位置:")) layout.addWidget(self.result_label) self.setLayout(layout) def browse_source(self): dir_ = QFileDialog.getExistingDirectory(self, "选择Word文档目录", "") if dir_: self.src_edit.setText(dir_) self.filelist = getfilenames(dir_, [], '.doc') self.list_word.clear() self.list_word.addItems([os.path.basename(f) for f in self.filelist]) def extract(self): if not self.filelist: QMessageBox.warning(self, "警告", "未选择文档!") return src = self.src_edit.text() temp_pdf_dir = os.path.join(src, "temp_merge") os.makedirs(temp_pdf_dir, exist_ok=True) def task(): # Step 1: 转为PDF pdfs = word_to_pdf_batch(self.filelist, temp_pdf_dir) if not pdfs: return # Step 2: 合并 merged_pdf = os.path.join(temp_pdf_dir, "merged.pdf") merge_pdfs(pdfs, merged_pdf) # Step 3: 提取大纲 output_docx = os.path.join(src, f"总目录_{datetime.now().strftime('%H%M%S')}.docx") success = extract_outline_from_pdf(merged_pdf, output_docx, self.chk_page.isChecked()) # 清理 for p in pdfs: try: os.remove(p) except: pass try: os.remove(merged_pdf) os.rmdir(temp_pdf_dir) except: pass if success: self.generated_docx = success self.result_label.setText(success) QMessageBox.information(self, "完成", "目录已提取!") threading.Thread(target=task, daemon=True).start() def open_file(self): if not self.generated_docx or not os.path.exists(self.generated_docx): QMessageBox.warning(self, "警告", "尚未生成目录文件!") return os.startfile(self.generated_docx) # ==================== 主程序入口 ==================== if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec()) 把这两张图放进代码里面
10-14
内容概要:本文详细介绍了“秒杀商城”微服务架构的设计与实战全过程,涵盖系统从需求分析、服务拆分、技术选型到核心功能开发、分布式事务处理、容器化部署及监控链路追踪的完整流程。重点解决了高并发场景下的超卖问题,采用Redis预减库存、消息队列削峰、数据库乐观锁等手段保障数据一致性,并通过Nacos实现服务注册发现与配置管理,利用Seata处理跨服务分布式事务,结合RabbitMQ实现异步下单,提升系统吞吐能力。同时,项目支持Docker Compose快速部署和Kubernetes生产级编排,集成Sleuth+Zipkin链路追踪与Prometheus+Grafana监控体系,构建可观测性强的微服务系统。; 适合人群:具备Java基础和Spring Boot开发经验,熟悉微服务基本概念的中高级研发人员,尤其是希望深入理解高并发系统设计、分布式事务、服务治理等核心技术的开发者;适合工作2-5年、有志于转型微服务或提升架构能力的工程师; 使用场景及目标:①学习如何基于Spring Cloud Alibaba构建完整的微服务项目;②掌握秒杀场景下高并发、超卖控制、异步化、削峰填谷等关键技术方案;③实践分布式事务(Seata)、服务熔断降级、链路追踪、统一配置中心等企业级中间件的应用;④完成从本地开发到容器化部署的全流程落地; 阅读建议:建议按照文档提供的七个阶段循序渐进地动手实践,重点关注秒杀流程设计、服务间通信机制、分布式事务实现和系统性能优化部分,结合代码调试与监控工具深入理解各组件协作原理,真正掌握高并发微服务系统的构建能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值