4.8 也是抢在了 5.5 前面。。。现在 5.6 GPT6 都没个动静。 9 个帖子 - 7 位参与者 阅读完整话题
tp-c9uevf18t64vwx0thyhkfiahvd3pixslkuuxde9bbxbw0oiq 兼容 OpenAI 接口协议: https://token-plan-cn.xiaomimimo.com/v1 兼容 Anthropic 接口协议: https://token-plan-cn.xiaomimimo.com/anthropic 2 个帖子 - 1 位参与者 阅读完整话题
6月底到期 API key:tp-czhbkxr4drtm35ejt6e2kzhntg3khx4t4p5onbzwflnpwmky 专属 Base URL 兼容 OpenAI 接口协议: https://token-plan-cn.xiaomimimo.com/v1 兼容 Anthropic 接口协议: https://token-plan-cn.xiaomimimo.com/anthropic 模型 mimo-v2.5-pro、mimo-v2.5、mimo-v2.5-asr、mimo-v2.5-tts-voiceclone、mimo-v2.5-tts-voicedesign、mimo-v2.5-tts、mimo-v2-pro、mimo-v2-omni、mimo-v2-tts 额度 11,000,000,000 Credits 1 个帖子 - 1 位参与者 阅读完整话题
base64 dHAtY3Izcmhkd21sN2JrOTkwejhhNzA4ODA0dm5hNDF4YXo2cno0Z3NxMzhwcGt6ZXhr 4 个帖子 - 3 位参与者 阅读完整话题
先到先得,手慢无。 XGt6IotPTimyo60i4ET6Gt79H22tL0_7.zip (264.7 KB) 3 个帖子 - 3 位参与者 阅读完整话题
API密钥:tp-se5o1ypx27dyvgknurxl9e0t6k54ry7hyj7kdm2nu42hcwr5 兼容OpenAI API协议: https://token-plan-sgp.xiaomimimo.com/v1 兼容Anthropic API协议: https://token-plan-sgp.xiaomimimo.com/anthropic 大佬们随便蹬,今晚截止啦!!! 1 个帖子 - 1 位参与者 阅读完整话题
准备发个gpt半自动手搓的教程(也可以全自动,自己领悟)。。。 录了个视频 我想想怎么发出来 这里好像只能上传图片 https://chixiaotao-models-1304404172.cos.ap-guangzhou.myqcloud.com/Desktop%202026.06.03%20-%2013.24.45.04.mp4 我的1级号被限制了 发不了评论了兄弟们 5小时后见 自己领悟吧 还有就是。。录教程不容易。。 别用我那个注册好的gpt号!!!!!! 也别用我买的PP日区手机号!!!!!! 插件自己从Github搜一下 别人开源的 还有就是 我回复不了你们的消息!! 12 个帖子 - 12 位参与者 阅读完整话题
IT之家 5 月 29 日消息,今日,2026 粤港澳大湾区车展开幕,一汽-大众 ID. AURA T6 登陆车展现场,并带来龙船特别版。 据介绍,本次同步展出的 ID. AURA T6 龙船特别版,主色调取自木棉花的橘红底色,搭配龙船文化的金龙纹样,打造专属视觉效果。 IT之家注意到,一汽-大众 ID.AURA 序列首款车型 ID.AURA T6 于 4 月 21 日正式亮相,该车是一款“全新五座中型 SUV”。 ID.AURA T6 基于 全新 CEA 电子电气架构 打造,采用了全新的设计语言,秉持“实用自然主义美学”设计理念,车头配备了方形灯组;侧面采用半隐藏式门把手,匹配高亮黑轮眉。车辆的激光雷达、驾驶辅助小蓝灯与摄像头以集成化方式融入车身。 官方强调, ID.AURA T6 系大众首款搭载激光雷达的纯电 SUV,该车将搭载大众汽车集团与地平线合资成立的酷睿程打造的全新高端智能驾驶辅助系统,拥有同级领先算力,更懂中国路况。 同时,大众集团宣布到 2027 年,集团将在中国市场累计推出约 30 款新能源车型,到 2030 年将达到约 50 款,其中包括约 30 款纯电动车型。
key: tp-s7roxdgmwlfgnxt6nh1jhisi3oye12qp00dofkz6mw5i4z8m 有需要的自取吧,就两天了 1 个帖子 - 1 位参与者 阅读完整话题
key: ttttt-tp-cglt627ljwjgl9epiyv2gmfh5yiwo44kjtzbh8pof0ik09j4 防止爬虫,删除前面的:ttttt- 1 个帖子 - 1 位参与者 阅读完整话题
KEY:tp-c3a47hi2csgwhap3ornqs4e0zt19k68z7cjbcetf5t6mnrra 兼容 OpenAI 接口协议: https://token-plan-cn.xiaomimimo.com/v1 兼容 Anthropic 接口协议: https://token-plan-cn.xiaomimimo.com/anthropic 2 个帖子 - 2 位参与者 阅读完整话题
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>NAT64 转换器 - IPv4 到 IPv6</title> <style> :root { --bg: #f5f7fb; --card-bg: #ffffff; --text: #1e293b; --text-secondary: #475569; --border: #e2e8f0; --accent: #2563eb; --accent-hover: #1d4ed8; --success: #059669; --error: #dc2626; --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -2px rgba(0, 0, 0, 0.05); --radius: 12px; } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Segoe UI', system-ui, -apple-system, sans-serif; background: linear-gradient(135deg, #f0f4ff 0%, #e8edf5 100%); min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 1.5rem; color: var(--text); } .container { background: var(--card-bg); border-radius: var(--radius); box-shadow: var(--shadow), 0 10px 25px -5px rgba(0, 0, 0, 0.08); width: 100%; max-width: 700px; padding: 2.5rem; border: 1px solid var(--border); transition: all 0.2s ease; } h1 { font-size: 1.8rem; font-weight: 700; margin-bottom: 0.5rem; letter-spacing: -0.5px; display: flex; align-items: center; gap: 0.5rem; } h1 span { background: var(--accent); color: white; font-size: 0.9rem; padding: 0.2rem 0.8rem; border-radius: 20px; font-weight: 500; letter-spacing: 0; } .subtitle { color: var(--text-secondary); margin-bottom: 2rem; font-size: 0.95rem; border-left: 3px solid var(--accent); padding-left: 0.8rem; } .form-group { margin-bottom: 1.5rem; } label { display: block; font-weight: 600; font-size: 0.9rem; margin-bottom: 0.4rem; color: var(--text); } .input-wrapper { display: flex; align-items: center; gap: 0.5rem; background: #f8fafc; border: 1px solid var(--border); border-radius: 8px; padding: 0.5rem 0.8rem; transition: border-color 0.2s, box-shadow 0.2s; } .input-wrapper:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1); } .input-wrapper input { border: none; background: transparent; flex: 1; font-size: 1rem; padding: 0.5rem 0; outline: none; font-family: 'JetBrains Mono', 'Fira Code', monospace; color: var(--text); } .input-wrapper .icon { color: var(--text-secondary); font-size: 1.1rem; } select { width: 100%; padding: 0.75rem 0.8rem; border: 1px solid var(--border); border-radius: 8px; background: #f8fafc; font-size: 0.95rem; font-family: 'JetBrains Mono', 'Fira Code', monospace; color: var(--text); outline: none; cursor: pointer; transition: border-color 0.2s, box-shadow 0.2s; appearance: none; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="%23475569" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg>'); background-repeat: no-repeat; background-position: right 0.8rem center; background-size: 1.2rem; } select:focus { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1); } .custom-prefix { margin-top: 0.8rem; display: none; } .custom-prefix.show { display: block; } .result-box { background: #f1f5f9; border-radius: 8px; padding: 1.2rem; margin: 1.8rem 0 1rem; border: 1px solid var(--border); word-break: break-all; } .result-label { font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-secondary); margin-bottom: 0.3rem; } .result-ipv6 { font-family: 'JetBrains Mono', 'Fira Code', monospace; font-size: 1.3rem; font-weight: 700; color: var(--accent); background: white; padding: 0.5rem 0.8rem; border-radius: 6px; display: inline-block; max-width: 100%; overflow-wrap: anywhere; border: 1px solid #cbd5e1; } .error-message { color: var(--error); font-size: 0.9rem; margin-top: 0.3rem; display: flex; align-items: center; gap: 0.3rem; } .conversion-detail { font-size: 0.85rem; color: var(--text-secondary); margin-top: 0.8rem; background: #f8fafc; border-radius: 6px; padding: 0.6rem 0.8rem; font-family: 'JetBrains Mono', monospace; } .footer-note { font-size: 0.8rem; color: #64748b; margin-top: 1.5rem; text-align: center; border-top: 1px solid var(--border); padding-top: 1rem; } @media (max-width: 500px) { .container { padding: 1.5rem; } h1 { font-size: 1.5rem; } } </style> </head> <body> <div class="container"> <h1> NAT64 转换器 <span>IPv4 → IPv6</span> </h1> <div class="subtitle"> 基于 nat64.xyz 公共 NAT64 前缀列表 · 实时合成地址 </div> <div class="form-group"> <label for="ipv4Input">IPv4 地址</label> <div class="input-wrapper"> <span class="icon">🌐</span> <input type="text" id="ipv4Input" placeholder="例如 104.21.88.129" value="104.21.88.129" autofocus> </div> </div> <div class="form-group"> <label for="prefixSelect">NAT64 前缀 (Provider / Location)</label> <select id="prefixSelect"> <optgroup label="Kasper Dupont"> <option value="2a00:1098:2b::/96">2a00:1098:2b::/96 – Germany (Nürnberg)</option> <option value="2a00:1098:2c:1::/96">2a00:1098:2c:1::/96 – Germany (Nürnberg)</option> <option value="2a01:4f8:c2c:123f:64::/96">2a01:4f8:c2c:123f:64::/96 – Germany (Nürnberg)</option> <option value="2a01:4f9:c010:3f02:64::/96">2a01:4f9:c010:3f02:64::/96 – Germany (Nürnberg)</option> </optgroup> <optgroup label="level66.services"> <option value="2001:67c:2960:6464::/96" selected>2001:67c:2960:6464::/96 – Anycast (Germany)</option> </optgroup> <optgroup label="Trex"> <option value="2001:67c:2b0:db32:0:1::/96">2001:67c:2b0:db32:0:1::/96 – Finland (Tampere)</option> </optgroup> <optgroup label="ZTVI"> <option value="2602:fc59:b0:64::/96">2602:fc59:b0:64::/96 – USA (Fremont)</option> <option value="2602:fc59:11:64::/96">2602:fc59:11:64::/96 – USA (Chicago)</option> </optgroup> <option value="custom">🔧 自定义前缀 (输入 /96 前缀)</option> </select> </div> <div class="custom-prefix" id="customPrefixWrapper"> <label for="customPrefixInput">自定义 NAT64 前缀 (/96)</label> <div class="input-wrapper"> <span class="icon">🔹</span> <input type="text" id="customPrefixInput" placeholder="例如 2001:db8:abcd:1234::/96"> </div> </div> <div class="result-box"> <div class="result-label">合成的 IPv6 地址</div> <div class="result-ipv6" id="resultIPv6">2001:67c:2960:6464::6815:5881</div> <div class="error-message" id="errorMessage"></div> <div class="conversion-detail" id="detailMapping"></div> </div> <div class="footer-note"> 数据来源 <strong>nat64.xyz</strong> · 十六进制嵌入 (RFC 6052) · 仅供学习与测试 </div> </div> <script> (function() { // DOM 元素 const ipv4Input = document.getElementById('ipv4Input'); const prefixSelect = document.getElementById('prefixSelect'); const customPrefixWrapper = document.getElementById('customPrefixWrapper'); const customPrefixInput = document.getElementById('customPrefixInput'); const resultIPv6 = document.getElementById('resultIPv6'); const errorMessage = document.getElementById('errorMessage'); const detailMapping = document.getElementById('detailMapping'); // 展开 IPv6 地址为 8 个 16-bit 块数组 function expandIPv6(addr) { // 移除可能的 zone ID (%) addr = addr.split('%')[0]; if (addr.includes('::')) { const parts = addr.split('::'); const left = parts[0] ? parts[0].split(':') : []; const right = parts[1] ? parts[1].split(':') : []; const missing = 8 - left.length - right.length; if (missing < 0) return null; // 无效地址 const middle = new Array(missing).fill('0'); const blocks = left.concat(middle, right); return blocks.map(b => parseInt(b || '0', 16)); } else { const blocks = addr.split(':'); if (blocks.length !== 8) return null; return blocks.map(b => parseInt(b || '0', 16)); } } // 压缩 IPv6 地址块数组为字符串 function compressIPv6(blocks) { if (blocks.length !== 8) return null; const strs = blocks.map(b => b.toString(16)); // 寻找最长连续零块 let bestStart = -1, bestLen = 0; let currStart = -1, currLen = 0; for (let i = 0; i < strs.length; i++) { if (strs[i] === '0') { if (currStart === -1) currStart = i; currLen++; } else { if (currLen > bestLen) { bestLen = currLen; bestStart = currStart; } currStart = -1; currLen = 0; } } if (currLen > bestLen) { bestLen = currLen; bestStart = currStart; } if (bestLen < 2) { return strs.join(':'); } const left = strs.slice(0, bestStart); const right = strs.slice(bestStart + bestLen); let result = left.join(':') + '::' + right.join(':'); if (left.length === 0) result = '::' + right.join(':'); if (right.length === 0) result = left.join(':') + '::'; return result; } // 验证并解析 IPv4 地址,返回字节数组或 null function parseIPv4(ipv4) { const parts = ipv4.trim().split('.'); if (parts.length !== 4) return null; const bytes = []; for (let p of parts) { const num = parseInt(p, 10); if (isNaN(num) || num < 0 || num > 255 || p !== num.toString()) return null; bytes.push(num); } return bytes; } // 获取当前选中的前缀字符串(去除 /96) function getCurrentPrefix() { if (prefixSelect.value === 'custom') { let val = customPrefixInput.value.trim(); if (!val) return null; // 允许带 /96 或不带 if (val.endsWith('/96')) val = val.slice(0, -3); return val; } else { let val = prefixSelect.value; if (val.endsWith('/96')) val = val.slice(0, -3); return val; } } // 执行转换并更新界面 function updateConversion() { const ipv4 = ipv4Input.value.trim(); const prefixStr = getCurrentPrefix(); // 清除旧错误 errorMessage.textContent = ''; detailMapping.textContent = ''; if (!ipv4) { resultIPv6.textContent = '请输入 IPv4 地址'; return; } const bytes = parseIPv4(ipv4); if (!bytes) { errorMessage.textContent = '❌ IPv4 地址格式无效,请输入形如 192.0.2.1 的地址'; resultIPv6.textContent = '—'; return; } if (!prefixStr) { errorMessage.textContent = '❌ 请选择或输入有效的 NAT64 前缀'; resultIPv6.textContent = '—'; return; } // 展开前缀 const expanded = expandIPv6(prefixStr); if (!expanded || expanded.length !== 8) { errorMessage.textContent = '❌ IPv6 前缀格式无效或不是 /96 长度'; resultIPv6.textContent = '—'; return; } // IPv4 字节转十六进制组合 const hexParts = bytes.map(b => b.toString(16).padStart(2, '0')); const block6 = parseInt(hexParts[0] + hexParts[1], 16); const block7 = parseInt(hexParts[2] + hexParts[3], 16); // 替换最后两个块 expanded[6] = block6; expanded[7] = block7; const resultAddr = compressIPv6(expanded); resultIPv6.textContent = resultAddr; // 显示转换细节 detailMapping.innerHTML = ` IPv4 十进制: ${bytes.join('.')}<br> 十六进制映射: ${bytes[0]} → 0x${hexParts[0]}, ${bytes[1]} → 0x${hexParts[1]}, ${bytes[2]} → 0x${hexParts[2]}, ${bytes[3]} → 0x${hexParts[3]}<br> 嵌入块: 0x${hexParts[0]}${hexParts[1]} : 0x${hexParts[2]}${hexParts[3]} → <strong>${hexParts[0]}${hexParts[1]}:${hexParts[2]}${hexParts[3]}</strong> `; } // 切换自定义前缀显示 function toggleCustomPrefix() { if (prefixSelect.value === 'custom') { customPrefixWrapper.classList.add('show'); } else { customPrefixWrapper.classList.remove('show'); } updateConversion(); } // 事件监听 ipv4Input.addEventListener('input', updateConversion); prefixSelect.addEventListener('change', toggleCustomPrefix); customPrefixInput.addEventListener('input', updateConversion); // 初始调用 toggleCustomPrefix(); updateConversion(); })(); </script> </body> </html> 3 个帖子 - 2 位参与者 阅读完整话题
IT之家 5 月 21 日消息,消息人士 HMD_MEME'S 昨天在 X 平台发文,曝光 HMD Thunder Pro 手机的详细规格,IT之家附上渲染图如下: 据介绍, 这台手机搭载紫光展锐 T620 芯片 ,主频为 2.2GHz,配备 8GB 内存和 256GB UFS 2.2 存储空间。拥有一块 6.67 英寸 OLED 屏幕,分辨率为 FHD+, 支持 90Hz 高刷 。 影像方面,该机配备 5000 万像素 OIS 光学防抖主摄,超广角镜头则是 800 万像素,屏幕下方带有一个 5000 万像素前置摄像头。 此外,该机支持 NFC,保留 3.5mm 耳机接口,具备双麦克风、双扬声器设计,支持 IP65 防尘防水,发售日期和售价暂不明确。
想整个阿里云300的买个香港的esc.e 2c 0.5g的那款,然后贴个钱直接上5年,之前的t6太难受了,性能限制比较大 有佬友试过能购买吗? 1 个帖子 - 1 位参与者 阅读完整话题
如下: leondroiddk----zSnQoithvf0T----6LDLY6JVUT6JJ4DP undduiq----IVtBYFNrgv4----ZHYZL6U3XPXWWDII ncmblo4----GilqFaP3kmDpAnWM----4523WPEMQIE7GLTP diegeluper----uBQdeXlMVqvyN6----3SS55WTUJYKH6RBL dapioraval----WJuPyhHEpTDwNqf3----OTS4JV5MP5HY5SU4 gripstonearll----AvhnbJRm7xNeyVDK----CSBLSGMBBUDIWLS5 fkr20----1kurzdKHimaD----KGLXGZ7KP2MQHH6L joamine----PcSmtAGy5gqZeB----A4UMVJMOYXMM647Y bamanvanovelver----IrCubBAioj0----ZVNWOMD2BNIIQCB5 coxqmcdemended----NzlSZEfint0R----IMDUG2X4ED7C5YN6 zaresh508----BmITz9YwWMx----5W4OO7NMQ6BXGA33 rvogev----POa2vptnlTqNZ----RSNLPR6563U7VI6F goalli----em0XEWjvcNSD----WM3INR4UBWVN6VSM depsvei----fVJhrgZ5BP----GOHJN5NHAOWTVNHC khaooshal----RcHhrmDdx5PBqCL----UTRNPWBTI27MQELQ sonluphony----uzDSlm3VId----IOW5PSVAS5EGNHXZ bsythynp----x6SjzadtOTWLCNu----MEDXEDEU3EI3UIZB raymache----XtpFhwkMKnE1cz----UVVOFHH3OCH773JB zthresghm----UsyXoaF5kzecxYOJ----OCVGCJIWKAJ2F6LU pgd868----ZdvVqKtx8DknaSHY----MHXEIFPWQIZ7OPBH gmy3r1----fs0THzunMkV----KUZKCBRIBCOMDE7Y tanvdonov----ojrDH9nRkYKJVl----PSKJJ237WJ6RD5WC une-dipyydddsc66----1TIVXZzFAMkaOyf----HHQOYDVTGZB5FCF4 stevk1----OIWuMRXx5kmt----DHBTTQZ33DJJUM42 hikwybry----LgMiIZ3bdWBJ----KM3O7BUZANGLMN6A drcreeg----H5xPbqtOviLWy----7BPMAPXDD65CIXOK pinaunp261----KNX6ucxdiFPeg----ULQW4W2A4DMXJEHN reilutmoo----oXSuIq2DyWpavdeC----PPCH73GLQZ4EKH6B trankdms----nNXi5EYJzfTG----5DGY3HMHQP2UAK5V smeko004----DPbcnFgYuBrH4----L6KPKPC7HWE4XJND petershanesh----Vl9eBLUCJIrDs----TVL4C6HSJBHGBYA7 besstotd----5QNeTjBxfqWM----OHGTMYETPNU5U4EX hapinte----Hr0yJxGQpuMNLKad----KGY2FVBTKD24RRFX nithubaf----QLW1STybXxzukRdP----BJUDJXMVLNTO7OA6 colbersonlink----PzVyGW5NHmxjDc----NTD2W3ZDEFFOFCAV angeliantani----tOAnT4YXVz----R5OJRKEA5FW2SRAN actratulogra----VfBeE9GUwIlNW----ROMA4FO7CPQ2NS26 fullenfiik----BCkeV9jzdQDhJty----NCFPF3TSQFA5XP4X seahbindubez----loS7rMEqVx----GWO4EGOEIKVMW3NU ariel5mccurp----bpVIBEhjqC0Geci----S3WYCUFQRO24GMIS cnanamm----sPz8erAMombNLFC----GAIC6H4XTI2BNKPQ dislayoun07----seCEKxQRiJp3yr----B6PI3AABJNEENNFX xminekalega----uOlTQXdSJWxa2v----ZEGC6UQ3XLB7KKCS palvanda----fcWdSLUiPQ6v----ADFKA4NQLZNEO4NM zabiknl----QajxdPAonZKk9----6NNEW6DLLXDNB2JB zhang109plb----qRsh2BGbPMrJgC----Q63CC55YHBD55PBG mirwalle----JjfwY6Wlyo----5EVSJZLG6HOWTKBS wafeetcyun----ICpVGfeTbDE2jRJA----UN64CVP66D4LJNWR wendermind----o7zsaVeGMC----S34HHNAMCW7BKBTG pdhariet----eywGVT2Cgfp----3O6JUE5QO65DL445 p-zian----gmnhXFAML4NiJ----VPEAE7LFUR66S3MC jackia0strail----cw5peqUXaFJnN----Y42DXNPHSBB5GFYA shabbdess----YpvxkWz4Xs----35B4V34UR3DIDTWY tongerbron11----rkXUchpdx7YBJEV----CO4F5YICOT3QGKNW lh4n5dvf----sVoWmKYX9w----OPYI7V46WRN4SDZC michaelcanpander----mSIpXHsDCTVeZL9----67FCAFH3XJEJHWB2 teurbrieser----vSNXJ1eMUuY----DUOFEIR36BAZFYFD andyzadeda----SJTlnuILXx8----ZVCA55DPRT54JIBP valubylion----hZHMDaG0eNduUKFW----FSM4DHLXDYMRG75H antibao----v1fwXuWixn----UHEEJMGSZKB5WP72 jaxionghancul----Tkrc7jPLaHSsx----VPG4HJPG5PZBFIBS chanisane----VhftMQWF8Rw----7INGVGB7EWDSXXMI alvassrct----NujbTCMv4rcZAWx----MGDGSUO54DWR7IKJ tra0755----QjYDCteqlOaV6----SRPR6ZOFJP2YGYR3 marcaniva----WgndDxZpGh9JUzE----LESLMCT3GGZ34G4X zepupix----tbGKH8jfxNkPm----2OBDLJOKX5H5ZLWK kubhoubnies----yfS2kJtuTxQK----FG3DXKEFTYALGAWX hzvando----vszfTABJK8Fby----NZTQE5C7CAKYI3VQ humbrodrigolov----TtZc3hICMYnjPr----IFEHBSYWBUHMWYT5 signerimback443----5qZLXHvIQxE----O7ZXT6XYK6N7GZA7 chachnira-hoom----4OhEZoVIuSCnswDj----YUVDRDHF6J5EFZ2O pbhjdkr----pE0VXrcwiNLF----DPEOC4O4MYGRXQVL ycqvjj----Wx0vIihrOdpAC----7TPRNPG55HLR66YT madfl3r3ddl----BzdhXRFbkp1uwCfv----6UERQGEQV3MPO5P4 skybran----fRNTESWGlUaz5----SY5E336VVP2BFQP2 jnepoldo----skfpZPlra0UGeQqh----IFSW7HI5JEAQWXBO zongzmongu----A2yVmwNdUOXGi----2ZF6KI2LHEKYW2RW jaclsr----7iuHdOSIXDBr----RVB4IA5YYUVV7RXN arthdv----Lezf8GikQAqZvlh----5RJISTRSQK6PFGT6 jacombottri----nFTRCX5LlyzMx----O3AOPGNKWWFUHWES teddrapp----tMIher2CORdYaf----BAM2M62TSVJ3GUK2 7 个帖子 - 4 位参与者 阅读完整话题
逆天营销号太厉害了,gpt-6都有了 【最新GPT6,强到离谱?-哔哩哔哩】 https://b23.tv/g1zoLyB 6 个帖子 - 5 位参与者 阅读完整话题
父亲用vivo系手机,比较看重健康和睡眠监测功能。心脏不太好,有高血压,血糖基本正常。有没有买过的佬说说优缺点? 10 个帖子 - 7 位参与者 阅读完整话题
版本 3.0 更新内容 import sys import re import subprocess import json import os from PyQt6.QtWidgets import ( QApplication, QWidget, QLabel, QLineEdit, QPushButton, QVBoxLayout, QMessageBox, QComboBox, QGridLayout, QGroupBox, QStyleFactory, QListWidget, QHBoxLayout, QSizePolicy ) from PyQt6.QtGui import QFont, QPalette, QColor from PyQt6.QtCore import Qt class IPChanger(QWidget): def __init__(self): super().__init__() self.config_file = os.path.join(os.path.expanduser("~"), "Library", "Application Support", "IPChanger", "ip_configs.json") os.makedirs(os.path.dirname(self.config_file), exist_ok=True) self.configs = self.load_configs() self.initUI() def initUI(self): print("Starting initUI...") # 调试日志 self.setWindowTitle("macOS IP 修改工具") self.setGeometry(200, 200, 900, 505) self.setMinimumSize(600, 400) # 设置全局字体 print("Setting global font...") # 调试日志 try: app_font = QFont("SF Pro", 13) # 使用 macOS 原生字体 SF Pro,13pt app_font.setWeight(QFont.Weight.Normal) QApplication.setFont(app_font) except Exception as e: print(f"Failed to set font: {e}") # 调试日志 QMessageBox.warning(self, "警告", f"无法设置字体: {str(e)}") # 主题美化 print("Setting style to macos...") # 调试日志 try: QApplication.setStyle(QStyleFactory.create("macos")) except Exception as e: print(f"Failed to set style: {e}") # 调试日志 QMessageBox.warning(self, "警告", f"无法设置界面主题: {str(e)}") main_layout = QHBoxLayout() main_layout.setSpacing(10) main_layout.setContentsMargins(10, 10, 10, 10) # 左侧布局:网卡信息 + 已保存配置 + 路由信息表 left_layout = QVBoxLayout() # 网卡信息分组 print("Initializing network group...") # 调试日志 net_group = QGroupBox("网卡信息") net_group.setFont(QFont("SF Pro", 14, QFont.Weight.Bold)) net_layout = QGridLayout() net_group.setLayout(net_layout) self.interface_label = QLabel("选择网卡:") self.interface_label.setFont(QFont("SF Pro", 14, QFont.Weight.Bold)) self.interface_dropdown = QComboBox() self.interface_dropdown.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed) self.interface_dropdown.currentIndexChanged.connect(self.update_ui) self.status_label = QLabel("网卡状态:") self.status_label.setFont(QFont("SF Pro", 14, QFont.Weight.Bold)) self.status_value = QLabel("N/A") self.current_ip_label = QLabel("当前 IP:") self.current_ip_label.setFont(QFont("SF Pro", 14, QFont.Weight.Bold)) self.current_ip_value = QLabel("N/A") self.subnet_label = QLabel("子网掩码:") self.subnet_label.setFont(QFont("SF Pro", 14, QFont.Weight.Bold)) self.subnet_value = QLabel("N/A") self.gateway_label = QLabel("网关:") self.gateway_label.setFont(QFont("SF Pro", 14, QFont.Weight.Bold)) self.gateway_value = QLabel("N/A") net_layout.addWidget(self.interface_label, 0, 0) net_layout.addWidget(self.interface_dropdown, 0, 1) net_layout.addWidget(self.status_label, 1, 0) net_layout.addWidget(self.status_value, 1, 1) net_layout.addWidget(self.current_ip_label, 2, 0) net_layout.addWidget(self.current_ip_value, 2, 1) net_layout.addWidget(self.subnet_label, 3, 0) net_layout.addWidget(self.subnet_value, 3, 1) net_layout.addWidget(self.gateway_label, 4, 0) net_layout.addWidget(self.gateway_value, 4, 1) # 保存的配置分组 print("Initializing saved config group...") # 调试日志 saved_group = QGroupBox("已保存的配置") saved_group.setFont(QFont("SF Pro", 14, QFont.Weight.Bold)) saved_layout = QVBoxLayout() saved_group.setLayout(saved_layout) self.saved_configs_list = QListWidget() self.saved_configs_list.setFont(QFont("SF Pro", 12)) self.saved_configs_list.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) self.load_saved_configs_to_list() self.saved_configs_list.itemClicked.connect(self.load_selected_config) self.delete_config_btn = QPushButton("删除选中配置") self.delete_config_btn.clicked.connect(self.delete_selected_config) self.delete_config_btn.setStyleSheet(""" QPushButton { background-color: #F44336; color: white; font-family: 'SF Pro'; font-size: 14px; font-weight: bold; padding: 8px; border-radius: 5px; } QPushButton:hover { background-color: #D32F2F; } """) saved_layout.addWidget(self.saved_configs_list) saved_layout.addWidget(self.delete_config_btn) # 路由信息表分组 print("Initializing route list group...") # 调试日志 route_list_group = QGroupBox("路由信息表") route_list_group.setFont(QFont("SF Pro", 14, QFont.Weight.Bold)) route_list_layout = QVBoxLayout() route_list_group.setLayout(route_list_layout) print("Creating route_list...") # 调试日志 self.route_list = QListWidget() self.route_list.setFont(QFont("SF Pro", 12)) self.route_list.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) print("route_list created") # 调试日志 self.delete_route_btn = QPushButton("删除选中路由") self.delete_route_btn.clicked.connect(self.delete_route) self.delete_route_btn.setStyleSheet(""" QPushButton { background-color: #F44336; color: white; font-family: 'SF Pro'; font-size: 14px; font-weight: bold; padding: 8px; border-radius: 5px; } QPushButton:hover { background-color: #D32F2F; } """) route_list_layout.addWidget(self.route_list) route_list_layout.addWidget(self.delete_route_btn) left_layout.addWidget(net_group) left_layout.addWidget(saved_group) left_layout.addWidget(route_list_group) left_layout.addStretch(1) # 右侧布局:IP 配置 + 路由管理 right_layout = QVBoxLayout() # IP 配置分组 print("Initializing IP config group...") # 调试日志 ip_group = QGroupBox("IP 配置") ip_group.setFont(QFont("SF Pro", 14, QFont.Weight.Bold)) ip_layout = QGridLayout() ip_group.setLayout(ip_layout) self.profile_name_label = QLabel("配置名称:") self.profile_name_label.setFont(QFont("SF Pro", 14, QFont.Weight.Bold)) self.profile_name_input = QLineEdit() self.profile_name_input.setFont(QFont("SF Pro", 12)) self.ip_label = QLabel("新 IP:") self.ip_label.setFont(QFont("SF Pro", 14, QFont.Weight.Bold)) self.ip_input = QLineEdit() self.ip_input.setFont(QFont("SF Pro", 12)) self.ip_input.textChanged.connect(lambda: self.validate_input(self.ip_input)) self.ip_status = QLabel("") self.subnet_label = QLabel("子网掩码:") self.subnet_label.setFont(QFont("SF Pro", 14, QFont.Weight.Bold)) self.subnet_input = QLineEdit() self.subnet_input.setFont(QFont("SF Pro", 12)) self.subnet_input.textChanged.connect(lambda: self.validate_input(self.subnet_input)) self.subnet_status = QLabel("") self.gateway_label = QLabel("网关:") self.gateway_label.setFont(QFont("SF Pro", 14, QFont.Weight.Bold)) self.gateway_input = QLineEdit() self.gateway_input.setFont(QFont("SF Pro", 12)) self.gateway_input.textChanged.connect(lambda: self.validate_input(self.gateway_input)) self.gateway_status = QLabel("") ip_layout.addWidget(self.profile_name_label, 0, 0) ip_layout.addWidget(self.profile_name_input, 0, 1) ip_layout.addWidget(self.ip_label, 1, 0) ip_layout.addWidget(self.ip_input, 1, 1) ip_layout.addWidget(self.ip_status, 1, 2) ip_layout.addWidget(self.subnet_label, 2, 0) ip_layout.addWidget(self.subnet_input, 2, 1) ip_layout.addWidget(self.subnet_status, 2, 2) ip_layout.addWidget(self.gateway_label, 3, 0) ip_layout.addWidget(self.gateway_input, 3, 1) ip_layout.addWidget(self.gateway_status, 3, 2) self.apply_btn = QPushButton("修改 IP") self.apply_btn.clicked.connect(self.change_ip) self.apply_btn.setStyleSheet(""" QPushButton { background-color: #4CAF50; color: white; font-family: 'SF Pro'; font-size: 14px; font-weight: bold; padding: 8px; border-radius: 5px; } QPushButton:hover { background-color: #388E3C; } """) self.dhcp_btn = QPushButton("恢复 DHCP") self.dhcp_btn.clicked.connect(self.set_dhcp) self.dhcp_btn.setStyleSheet(""" QPushButton { background-color: #2196F3; color: white; font-family: 'SF Pro'; font-size: 14px; font-weight: bold; padding: 8px; border-radius: 5px; } QPushButton:hover { background-color: #1976D2; } """) self.save_config_btn = QPushButton("保存配置") self.save_config_btn.clicked.connect(self.save_config) self.save_config_btn.setStyleSheet(""" QPushButton { background-color: #FFC107; color: white; font-family: 'SF Pro'; font-size: 14px; font-weight: bold; padding: 8px; border-radius: 5px; } QPushButton:hover { background-color: #FFA000; } """) # 路由管理分组 print("Initializing route group...") # 调试日志 route_group = QGroupBox("路由管理") route_group.setFont(QFont("SF Pro", 14, QFont.Weight.Bold)) route_layout = QGridLayout() route_group.setLayout(route_layout) self.route_dest_label = QLabel("目标网络:") self.route_dest_label.setFont(QFont("SF Pro", 14, QFont.Weight.Bold)) self.route_dest_input = QLineEdit() self.route_dest_input.setFont(QFont("SF Pro", 12)) self.route_dest_input.textChanged.connect(lambda: self.validate_input(self.route_dest_input)) self.route_dest_status = QLabel("") self.route_mask_label = QLabel("子网掩码:") self.route_mask_label.setFont(QFont("SF Pro", 14, QFont.Weight.Bold)) self.route_mask_input = QLineEdit() self.route_mask_input.setFont(QFont("SF Pro", 12)) self.route_mask_input.textChanged.connect(lambda: self.validate_input(self.route_mask_input)) self.route_mask_status = QLabel("") self.route_gateway_label = QLabel("网关:") self.route_gateway_label.setFont(QFont("SF Pro", 14, QFont.Weight.Bold)) self.route_gateway_input = QLineEdit() self.route_gateway_input.setFont(QFont("SF Pro", 12)) self.route_gateway_input.textChanged.connect(lambda: self.validate_input(self.route_gateway_input)) self.route_gateway_status = QLabel("") route_layout.addWidget(self.route_dest_label, 0, 0) route_layout.addWidget(self.route_dest_input, 0, 1) route_layout.addWidget(self.route_dest_status, 0, 2) route_layout.addWidget(self.route_mask_label, 1, 0) route_layout.addWidget(self.route_mask_input, 1, 1) route_layout.addWidget(self.route_mask_status, 1, 2) route_layout.addWidget(self.route_gateway_label, 2, 0) route_layout.addWidget(self.route_gateway_input, 2, 1) route_layout.addWidget(self.route_gateway_status, 2, 2) self.add_route_btn = QPushButton("添加临时路由") self.add_route_btn.clicked.connect(self.add_route) self.add_route_btn.setStyleSheet(""" QPushButton { background-color: #FF5722; color: white; font-family: 'SF Pro'; font-size: 14px; font-weight: bold; padding: 8px; border-radius: 5px; } QPushButton:hover { background-color: #E64A19; } """) route_layout.addWidget(self.add_route_btn, 3, 0, 1, 2) right_layout.addWidget(ip_group) right_layout.addWidget(self.apply_btn) right_layout.addWidget(self.dhcp_btn) right_layout.addWidget(self.save_config_btn) right_layout.addWidget(route_group) right_layout.addStretch(1) # 主界面布局 main_layout.addLayout(left_layout, 1) main_layout.addLayout(right_layout, 1) self.setLayout(main_layout) # 延迟初始化网卡和路由列表 print("Initializing network interfaces...") # 调试日志 try: self.get_network_interfaces() except Exception as e: print(f"Failed to get network interfaces: {e}") # 调试日志 QMessageBox.critical(self, "错误", f"无法获取网卡列表: {str(e)}") print("initUI completed, calling update_ui...") # 调试日志 try: self.update_ui() except Exception as e: print(f"Failed to update UI: {e}") # 调试日志 QMessageBox.warning(self, "警告", f"无法更新界面: {str(e)}") def validate_input(self, input_field): """实时校验输入框中的 IP 格式""" text = input_field.text().strip() status_label = None if input_field == self.ip_input: status_label = self.ip_status elif input_field == self.subnet_input: status_label = self.subnet_status elif input_field == self.gateway_input: status_label = self.gateway_status elif input_field == self.route_dest_input: status_label = self.route_dest_status elif input_field == self.route_mask_input: status_label = self.route_mask_status elif input_field == self.route_gateway_input: status_label = self.route_gateway_status if not text: status_label.setText("") input_field.setStyleSheet("") return if self.validate_ip(text): status_label.setText("✓") status_label.setStyleSheet("color: green; font-family: 'SF Pro'; font-size: 14px; font-weight: bold;") input_field.setStyleSheet("border: 1px solid green; font-family: 'SF Pro'; font-size: 12px;") else: status_label.setText("✗") status_label.setStyleSheet("color: red; font-family: 'SF Pro'; font-size: 14px; font-weight: bold;") input_field.setStyleSheet("border: 1px solid red; font-family: 'SF Pro'; font-size: 12px;") def get_network_interfaces(self): """获取 macOS 可用的网络接口列表""" result = subprocess.run("networksetup -listallnetworkservices", shell=True, capture_output=True, text=True) interfaces = result.stdout.strip().split("\n")[1:] # 去掉第一行(标题) if not interfaces: raise Exception("No network interfaces found") self.interface_dropdown.addItems(interfaces) def get_network_info(self, interface): """获取网卡详细状态""" try: result = subprocess.run(f"networksetup -getinfo \"{interface}\"", shell=True, capture_output=True, text=True) output = result.stdout.strip() status_match = re.search(r"IP address: (.+)", output) subnet_match = re.search(r"Subnet mask: (.+)", output) gateway_match = re.search(r"Router: (.+)", output) ip_address = status_match.group(1) if status_match else "未连接" subnet = subnet_match.group(1) if subnet_match else "N/A" gateway = gateway_match.group(1) if gateway_match else "N/A" if "DHCP Configuration" in output: return "动态 IP (DHCP)", ip_address, subnet, gateway else: return "静态 IP", ip_address, subnet, gateway except Exception: return "未知", "N/A", "N/A", "N/A" def update_ui(self): """更新 UI(显示当前网卡状态和详细信息)""" print("Updating UI...") # 调试日志 interface = self.interface_dropdown.currentText() if not interface: print("No interface selected, skipping UI update") # 调试日志 return try: status, ip, subnet, gateway = self.get_network_info(interface) if hasattr(self, 'status_value') and hasattr(self, 'current_ip_value') and \ hasattr(self, 'subnet_value') and hasattr(self, 'gateway_value'): self.status_value.setText(status) self.current_ip_value.setText(ip) self.subnet_value.setText(subnet) self.gateway_value.setText(gateway) else: print("Network info attributes not initialized") # 调试日志 QMessageBox.warning(self, "警告", "网络信息组件未初始化") except Exception as e: print(f"Failed to get network info: {e}") # 调试日志 QMessageBox.warning(self, "警告", f"无法获取网卡信息: {str(e)}") if hasattr(self, 'route_list'): print("Loading routes to list...") # 调试日志 try: self.load_routes_to_list() except Exception as e: print(f"Failed to load routes: {e}") # 调试日志 QMessageBox.warning(self, "警告", f"无法加载路由表: {str(e)}") else: print("route_list not initialized") # 调试日志 def validate_ip(self, ip): """校验 IP 格式""" pattern = r"^(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)$" return re.match(pattern, ip) is not None def change_ip(self): """修改 IP 地址""" interface = self.interface_dropdown.currentText() ip = self.ip_input.text().strip() subnet = self.subnet_input.text().strip() gateway = self.gateway_input.text().strip() if not interface: QMessageBox.warning(self, "错误", "请先选择网卡!") return if not (self.validate_ip(ip) and self.validate_ip(subnet) and self.validate_ip(gateway)): QMessageBox.warning(self, "错误", "IP、子网掩码或网关格式不正确!") return cmd = f"osascript -e 'do shell script \"networksetup -setmanual \\\"{interface}\\\" {ip} {subnet} {gateway}\" with administrator privileges'" self.run_command(cmd) def set_dhcp(self): """切换到 DHCP 自动获取 IP""" interface = self.interface_dropdown.currentText() if not interface: QMessageBox.warning(self, "错误", "请先选择网卡!") return cmd = f"osascript -e 'do shell script \"networksetup -setdhcp \\\"{interface}\\\"\" with administrator privileges'" self.run_command(cmd) def add_route(self): """添加临时路由""" destination = self.route_dest_input.text().strip() mask = self.route_mask_input.text().strip() gateway = self.route_gateway_input.text().strip() if not (self.validate_ip(destination) and self.validate_ip(mask) and self.validate_ip(gateway)): QMessageBox.warning(self, "错误", "目标网络、子网掩码或网关格式不正确!") return cmd = f"osascript -e 'do shell script \"route -n add -net {destination} -netmask {mask} {gateway}\" with administrator privileges'" self.run_command(cmd) self.load_routes_to_list() self.route_dest_input.clear() self.route_mask_input.clear() self.route_gateway_input.clear() def delete_route(self): """删除选中的临时路由""" if not hasattr(self, 'route_list'): QMessageBox.warning(self, "错误", "路由列表未初始化!") return current_item = self.route_list.currentItem() if not current_item: QMessageBox.warning(self, "错误", "请先选择一个路由!") return destination = current_item.text().split(" ")[0].strip() cmd = f"osascript -e 'do shell script \"route -n delete -net {destination}\" with administrator privileges'" self.run_command(cmd) self.load_routes_to_list() def load_routes_to_list(self): """加载当前路由表到列表""" print("Clearing route_list...") # 调试日志 if not hasattr(self, 'route_list'): print("route_list not initialized in load_routes_to_list") # 调试日志 return self.route_list.clear() try: result = subprocess.run("netstat -rn | grep -E '^[0-9]'", shell=True, capture_output=True, text=True) routes = result.stdout.strip().split("\n") for route in routes: parts = route.split() if len(parts) >= 2: self.route_list.addItem(f"{parts[0]} via {parts[1]}") except Exception as e: QMessageBox.critical(self, "错误", f"无法加载路由表: {str(e)}") def run_command(self, cmd): """运行 shell 命令""" try: result = subprocess.run(cmd, shell=True, capture_output=True, text=True) if result.returncode == 0: QMessageBox.information(self, "成功", "操作成功") self.update_ui() else: QMessageBox.critical(self, "错误", f"执行失败:\n{result.stderr}") except Exception as e: QMessageBox.critical(self, "异常", f"发生错误:\n{str(e)}") def load_configs(self): """加载保存的配置""" if os.path.exists(self.config_file): try: with open(self.config_file, 'r') as f: return json.load(f) except Exception as e: QMessageBox.critical(self, "错误", f"无法加载配置文件: {str(e)}") return {} return {} def save_configs(self): """保存配置到文件""" try: with open(self.config_file, 'w') as f: json.dump(self.configs, f, indent=2) except Exception as e: QMessageBox.critical(self, "错误", f"无法保存配置文件: {str(e)}") def save_config(self): """保存当前 IP 配置""" profile_name = self.profile_name_input.text().strip() ip = self.ip_input.text().strip() subnet = self.subnet_input.text().strip() gateway = self.gateway_input.text().strip() if not profile_name: QMessageBox.warning(self, "错误", "请输入配置名称!") return if not (self.validate_ip(ip) and self.validate_ip(subnet) and self.validate_ip(gateway)): QMessageBox.warning(self, "错误", "IP、子网掩码或网关格式不正确!") return if profile_name in self.configs: reply = QMessageBox.question(self, "确认", "配置已存在,是否覆盖?", QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No) if reply == QMessageBox.StandardButton.No: return self.configs[profile_name] = { "ip": ip, "subnet": subnet, "gateway": gateway } self.save_configs() self.load_saved_configs_to_list() QMessageBox.information(self, "成功", "配置已保存") self.profile_name_input.clear() self.ip_input.clear() self.subnet_input.clear() self.gateway_input.clear() def load_saved_configs_to_list(self): """加载保存的配置到列表显示""" if not hasattr(self, 'saved_configs_list'): print("saved_configs_list not initialized") # 调试日志 return self.saved_configs_list.clear() for profile_name, config in self.configs.items(): self.saved_configs_list.addItem( f"{profile_name}: {config['ip']} / {config['subnet']} / {config['gateway']}") def load_selected_config(self, item): """加载选中的配置到输入框""" if not item: return profile_name = item.text().split(":")[0].strip() if profile_name in self.configs: config = self.configs[profile_name] self.ip_input.setText(config["ip"]) self.subnet_input.setText(config["subnet"]) self.gateway_input.setText(config["gateway"]) self.profile_name_input.setText(profile_name) def delete_selected_config(self): """删除选中的配置""" if not hasattr(self, 'saved_configs_list'): QMessageBox.warning(self, "错误", "配置列表未初始化!") return current_item = self.saved_configs_list.currentItem() if not current_item: QMessageBox.warning(self, "错误", "请先选择一个配置!") return profile_name = current_item.text().split(":")[0].strip() if profile_name in self.configs: reply = QMessageBox.question(self, "确认", f"确定要删除配置 '{profile_name}' 吗?", QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No) if reply == QMessageBox.StandardButton.Yes: del self.configs[profile_name] self.save_configs() self.load_saved_configs_to_list() QMessageBox.information(self, "成功", "配置已删除") self.profile_name_input.clear() self.ip_input.clear() self.subnet_input.clear() self.gateway_input.clear() if __name__ == "__main__": try: app = QApplication(sys.argv) window = IPChanger() window.show() sys.exit(app.exec()) except Exception as e: print(f"Application failed to start: {e}") sys.exit(1) 新增功能 路由管理功能 : 新增“路由信息表”分组,显示当前系统路由表(通过 netstat -rn 获取)。 支持添加临时路由,包含目标网络、子网掩码和网关输入框。 支持删除选中的临时路由。 实时输入校验 : 为 IP、子网掩码、网关、路由目标网络、路由子网掩码和路由网关输入框添加实时格式校验。 校验通过时显示绿色“✓”,失败时显示红色“✗”,并为输入框添加相应的边框颜色。 配置覆盖确认 : 保存配置时,若配置名称已存在,会提示用户是否覆盖现有配置。 删除配置确认 : 删除配置时,增加确认提示框,防止误操作。 界面改进 字体优化 : 全局使用 macOS 原生字体 SF Pro ,标题加粗,增强视觉层次。 设置统一的字体大小(标签 14pt,输入框和列表 12pt)。 主题优化 : 使用 macos 主题( QStyleFactory.create("macos") ),替换之前的 Macintosh 主题,提供更现代化的 macOS 原生风格。 按钮样式优化,添加 hover 效果,统一圆角(5px)和填充(8px)。 布局改进 : 主窗口最小尺寸设为 600x400,确保内容完整显示。 增加布局间距( main_layout.setSpacing(10) )和边距( setContentsMargins(10, 10, 10, 10) ),提升界面美观度。 为网卡下拉框和列表控件设置 QSizePolicy.Expanding ,确保自适应窗口大小。 左侧和右侧布局通过 addStretch(1) 优化空间分配。 路由管理分组 : 新增“路由管理”分组,包含目标网络、子网掩码和网关输入框,以及“添加临时路由”按钮。 功能优化 配置文件路径 : 配置文件存储路径从 __file__ 目录更改为用户目录下的 ~/Library/Application Support/IPChanger/ip_configs.json ,符合 macOS 应用标准。 自动创建配置文件目录( os.makedirs )。 错误处理 : 增强异常捕获,初始化界面时捕获字体、主题、网卡列表和 UI 更新的异常,并显示友好提示。 启动应用程序时添加全局异常捕获,记录错误并退出。 调试日志 : 在 initUI 方法中添加详细的调试日志,记录界面初始化步骤,便于排查问题。 网卡选择校验 : 在修改 IP 或切换 DHCP 时,增加网卡选择是否有效的校验,防止空网卡操作。 路由表加载 : 使用 netstat -rn | grep -E '^[0-9]' 加载路由表,仅显示以数字开头的路由条目,确保数据清晰。 问题修复 网卡信息初始化 : 修复 status_value 等属性可能未初始化的问题,增加属性存在性检查。 路由列表初始化 : 修复路由列表可能未初始化的问题,增加 hasattr 检查。 配置列表初始化 : 修复保存配置列表可能未初始化的问题,增加 hasattr 检查。 代码优化 代码结构 : 优化布局代码,分组更清晰,逻辑分块更合理。 统一按钮样式定义,使用多行字符串减少代码冗余。 输入校验逻辑 : 将输入校验逻辑提取为独立方法 validate_input ,支持多个输入框的动态校验。 路由操作 : 使用 route -n add 和 route -n delete 命令实现临时路由的添加和删除,带管理员权限。 已知问题 路由管理仅支持临时路由,系统重启后路由会丢失(后续版本可考虑持久化路由)。 部分 macOS 系统版本可能对 networksetup 命令响应较慢,可能导致 UI 延迟。 字体 SF Pro 在某些 macOS 版本可能不可用,需进一步测试兼容性。 1 个帖子 - 1 位参与者 阅读完整话题
IT之家 5 月 7 日消息,5 月 5 日,外媒 FujiRumors 爆料称,富士 X‑T6 预计于 2026 年 9 月正式发布,本次发布会或将同步推出两支全新 X 卡口镜头。 据了解,若富士同时发布相机和镜头,则两款产品通常互相匹配。以 X-T30III 为例,其与 XC13-33mm 镜头一同发布;X-E5 则是与紧凑型 XF23mmF2.8 饼干镜头一同发布的。 该媒体分析称,同时与 X-T6 登场的镜头将不会是 XC 系列,因为其不符合中高端的 X-T6 定位。至于镜头的具体规格,仍待官方揭晓,IT之家将持续关注。
在推特刷帖子刷到OpenAI说9月29开发者大会,然后很多都说到时候要发布gpt6 1 个帖子 - 1 位参与者 阅读完整话题