Bladeren bron

调整内容区域渲染方式,优化CSS样式,增强调试信息显示

zhch158_admin 2 maanden geleden
bovenliggende
commit
d6444f7495
1 gewijzigde bestanden met toevoegingen van 109 en 146 verwijderingen
  1. 109 146
      ocr_validator_layout.py

+ 109 - 146
ocr_validator_layout.py

@@ -163,8 +163,8 @@ class OCRLayoutManager:
         except Exception as e:
             st.error(f"❌ 图像加载失败: {e}")
             return None
-    
-    def render_content_section(self, layout_type: str = "standard"):
+
+    def render_content_section(self, layout_type: str = "compact"):
         """渲染内容区域 - 统一方法"""
         st.header("📄 OCR识别内容")
         
@@ -210,17 +210,9 @@ class OCRLayoutManager:
             else:
                 st.warning(f"未找到包含 '{search_term}' 的内容")
         
-        # 渲染方式选择
-        render_mode = st.radio(
-            "选择渲染方式",
-            ["HTML渲染", "Markdown渲染", "DataFrame表格", "原始文本"],
-            horizontal=True,
-            key=f"{layout_type}_render_mode"
-        )
-        
-        return display_content, render_mode
-    
-    def render_content_by_mode(self, content: str, render_mode: str, font_size: int, layout_type: str):
+        return display_content
+
+    def render_content_by_mode(self, content: str, render_mode: str, font_size: int, container_height: int, layout_type: str):
         """根据渲染模式显示内容 - 增强版本"""
         if content is None or render_mode is None:
             return
@@ -230,6 +222,9 @@ class OCRLayoutManager:
             content_style = f"""
             <style>
             .{layout_type}-content-display {{
+                height: {container_height}px;
+                overflow-x: auto;
+                overflow-y: auto;
                 font-size: {font_size}px !important;
                 line-height: 1.4;
                 color: #333333 !important;
@@ -237,15 +232,15 @@ class OCRLayoutManager:
                 padding: 10px;
                 border-radius: 5px;
                 border: 1px solid #ddd;
-                overflow-x: auto;
                 max-width: 100%;
             }}
             
             .{layout_type}-content-display table {{
-                width: 100%;
+                width: 100%;  /* 修改:从100%改为auto,让表格自适应内容 */
                 border-collapse: collapse;
                 margin: 10px 0;
-                white-space: nowrap;
+                white-space: nowrap;  /* 修改:允许文字换行 */
+                /* table-layout: auto; *?  /* 新增:自动表格布局 */
             }}
             
             .{layout_type}-content-display th,
@@ -253,7 +248,11 @@ class OCRLayoutManager:
                 border: 1px solid #ddd;
                 padding: 8px;
                 text-align: left;
-                min-width: 100px;
+                /* 移除:min-width固定限制 */
+                max-width: 300px;     /* 新增:设置最大宽度避免过宽 */
+                word-wrap: break-word; /* 新增:长单词自动换行 */
+                word-break: break-all; /* 新增:允许在任意字符间换行 */
+                vertical-align: top;   /* 新增:顶部对齐 */
             }}
             
             .{layout_type}-content-display th {{
@@ -261,6 +260,20 @@ class OCRLayoutManager:
                 position: sticky;
                 top: 0;
                 z-index: 1;
+                font-weight: bold;    /* 新增:表头加粗 */
+            }}
+            
+            /* 新增:针对数字列的特殊处理 */
+            .{layout_type}-content-display td.number {{
+                text-align: right;
+                white-space: nowrap;
+                font-family: 'Monaco', 'Menlo', monospace;
+            }}
+            
+            /* 新增:针对短文本列的处理 */
+            .{layout_type}-content-display td.short-text {{
+                white-space: nowrap;
+                min-width: 80px;
             }}
             
             .{layout_type}-content-display img {{
@@ -269,6 +282,31 @@ class OCRLayoutManager:
                 border-radius: 4px;
                 margin: 10px 0;
             }}
+        
+            /* 新增:响应式表格 */
+            @media (max-width: 768px) {{
+                .{layout_type}-content-display table {{
+                    font-size: {max(font_size-2, 8)}px;
+                }}
+                .{layout_type}-content-display th,
+                .{layout_type}-content-display td {{
+                    padding: 4px;
+                    max-width: 150px;
+                }}
+            }}
+
+            .highlight-text {{
+                background-color: #ffeb3b !important;
+                padding: 2px 4px;
+                border-radius: 3px;
+                cursor: pointer;
+                color: #333333 !important;
+            }}
+            
+            .selected-highlight {{
+                background-color: #4caf50 !important;
+                color: white !important;
+            }}
             </style>
             """
             st.markdown(content_style, unsafe_allow_html=True)
@@ -291,45 +329,21 @@ class OCRLayoutManager:
                 height=300,
                 key=f"{layout_type}_text_area"
             )
-    
-    # 布局实现
-    def create_standard_layout(self, font_size: int = 10, zoom_level: float = 1.0):
-        """创建标准布局"""
-        if zoom_level is None:
-            zoom_level = self.config['styles']['layout']['default_zoom']
-            
-        # 主要内容区域
-        layout = self.config['styles']['layout']
-        left_col, right_col = st.columns([layout['content_width'], layout['sidebar_width']])
-        
-        with left_col:
-            self.render_content_section("standard")
-            
-            # 显示内容
-            if self.validator.md_content:
-                display_content, render_mode = self.render_md_content("standard")
-                self.render_content_by_mode(display_content, render_mode, font_size, "standard")
-        
-        with right_col:
-            self.create_aligned_image_display(zoom_level, "compact")
-    
-    def create_compact_layout(self, font_size: int = 10, zoom_level: float = 1.0):
+
+    def create_compact_layout(self, config: Dict):
         """创建紧凑的对比布局"""
         # 主要内容区域
-        layout = self.config['styles']['layout']
-        left_col, right_col = st.columns([layout['content_width'], layout['sidebar_width']])                
+        layout = config['styles']['layout']
+        font_size = config['styles'].get('font_size', 10)
+        container_height = layout.get('default_height', 600)  # 默认高度
+        zoom_level = layout.get('default_zoom', 1.0)  # 默认缩放级别
+        layout_type = "compact"
+
+        left_col, right_col = st.columns([layout['content_width'], layout['sidebar_width']], vertical_alignment='top')
 
         with left_col:
-            self.render_content_section("compact")
+            self.render_content_section(layout_type)
 
-            # 只保留一个内容区域高度选择
-            container_height = st.selectbox(
-                "选择内容区域高度", 
-                [400, 600, 800, 1000, 1200], 
-                index=2,
-                key="compact_content_height"
-            )
-            
             # 快速定位文本选择器(使用不同的key)
             if self.validator.text_bbox_mapping:
                 text_options = ["请选择文本..."] + list(self.validator.text_bbox_mapping.keys())
@@ -343,36 +357,6 @@ class OCRLayoutManager:
                 if selected_index > 0:
                     st.session_state.selected_text = text_options[selected_index]
             
-            # 自定义CSS样式
-            st.markdown(f"""
-            <style>
-            .compact-content {{
-                height: {container_height}px;
-                overflow-y: auto;
-                font-size: {font_size}px !important;
-                line-height: 1.4;
-                border: 1px solid #ddd;
-                padding: 10px;
-                background-color: #fafafa !important;
-                font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
-                color: #333333 !important;
-            }}
-            
-            .highlight-text {{
-                background-color: #ffeb3b !important;
-                padding: 2px 4px;
-                border-radius: 3px;
-                cursor: pointer;
-                color: #333333 !important;
-            }}
-            
-            .selected-highlight {{
-                background-color: #4caf50 !important;
-                color: white !important;
-            }}
-            </style>
-            """, unsafe_allow_html=True)
-            
             # 处理并显示OCR内容
             if self.validator.md_content:
                 # 高亮可点击文本
@@ -384,40 +368,30 @@ class OCRLayoutManager:
                             text, 
                             f'<span class="{css_class}" title="{text[:50]}...">{text}</span>'
                         )
-                st.markdown(
-                    f'<div class="compact-content">{highlighted_content}</div>', 
-                    unsafe_allow_html=True
-                )
-        
+                self.render_content_by_mode(highlighted_content, "HTML渲染", font_size, container_height, layout_type)
+            
         with right_col:
             # 修复的对齐图片显示
             self.create_aligned_image_display(zoom_level, "compact")
     
     def create_aligned_image_display(self, zoom_level: float = 1.0, layout_type: str = "aligned"):
         """创建与左侧对齐的图片显示 - 修复显示问题"""
-        # 精确对齐CSS
-        st.markdown(f"""
-        <style>
-        .aligned-image-container-{layout_type} {{
-            margin-top: -70px;
-            padding-top: 0px;
-        }}
-        .aligned-image-container-{layout_type} h1 {{
-            margin-top: 0px !important;
-            padding-top: 0px !important;
-        }}
-        /* 修复:确保Plotly图表容器没有额外边距 */
-        .js-plotly-plot, .plotly {{
-            margin: 0 !important;
-            padding: 0 !important;
-        }}
-        </style>
-        """, unsafe_allow_html=True)
-        
-        st.markdown(f'<div class="aligned-image-container-{layout_type}">', unsafe_allow_html=True)
         st.header("🖼️ 原图标注")
         
-        # 方向检测控制面板
+        # 图片控制选项
+        col1, col2, col3, col4 = st.columns(4)
+        with col1:
+            current_zoom = st.slider("图片缩放", 0.3, 2.0, zoom_level, 0.1, key=f"{layout_type}_zoom_level")
+        with col2:
+            show_all_boxes = st.checkbox("显示所有框", value=False, key=f"{layout_type}_show_all_boxes")
+        with col3:
+            fit_to_container = st.checkbox("适应容器", value=True, key=f"{layout_type}_fit_container")
+        with col4:
+            # 显示当前角度状态
+            current_angle = self.get_rotation_angle()
+            st.metric("当前角度", f"{current_angle}°")
+
+         # 方向检测控制面板
         with st.expander("🔄 图片方向检测", expanded=False):
             col1, col2, col3 = st.columns(3)
             
@@ -498,19 +472,7 @@ class OCRLayoutManager:
                                 st.error(f"错误: {individual['error']}")
                             st.write("---")
         
-        # 图片控制选项
-        col1, col2, col3, col4 = st.columns(4)
-        with col1:
-            current_zoom = st.slider("图片缩放", 0.3, 2.0, zoom_level, 0.1, key=f"{layout_type}_zoom_level")
-        with col2:
-            show_all_boxes = st.checkbox("显示所有框", value=False, key=f"{layout_type}_show_all_boxes")
-        with col3:
-            fit_to_container = st.checkbox("适应容器", value=True, key=f"{layout_type}_fit_container")
-        with col4:
-            # 显示当前角度状态
-            current_angle = self.get_rotation_angle()
-            st.metric("当前角度", f"{current_angle}°")
-        
+       
         # 使用增强的图像加载方法
         image = self.load_and_rotate_image(self.validator.image_path)
         
@@ -538,32 +500,6 @@ class OCRLayoutManager:
                                 scaled_bbox = [coord * current_zoom for coord in bbox]
                                 all_boxes.append(scaled_bbox)
                 
-                # 增强的调试信息
-                with st.expander("🔍 图像和坐标调试信息", expanded=False):
-                    rotation_angle = self.get_rotation_angle()
-                    rotation_config = get_ocr_tool_rotation_config(self.validator.ocr_data, self.config)
-                    
-                    col_debug1, col_debug2, col_debug3 = st.columns(3)
-                    with col_debug1:
-                        st.write("**图像信息:**")
-                        st.write(f"原始尺寸: {image.width} x {image.height}")
-                        st.write(f"缩放后尺寸: {resized_image.width} x {resized_image.height}")
-                        st.write(f"当前角度: {rotation_angle}°")
-                        
-                    with col_debug2:
-                        st.write("**坐标信息:**")
-                        if selected_bbox:
-                            st.write(f"选中框: {selected_bbox}")
-                        st.write(f"总框数: {len(all_boxes)}")
-                        st.write(f"文本框数: {len(self.validator.text_bbox_mapping)}")
-                        
-                    with col_debug3:
-                        st.write("**配置信息:**")
-                        st.write(f"工具类型: {rotation_config.get('coordinates_are_pre_rotated', 'unknown')}")
-                        st.write(f"缓存状态: {len(self._rotated_image_cache)} 项")
-                        if hasattr(self, '_auto_detected_angle'):
-                            st.write(f"自动检测角度: {self._auto_detected_angle}°")
-                
                 # 创建交互式图片
                 fig = self.create_resized_interactive_plot(resized_image, selected_bbox, current_zoom, all_boxes)
                 
@@ -613,6 +549,33 @@ class OCRLayoutManager:
                     if st.button("✅ 取消错误标记", key=f"{layout_type}_unmark_error"):
                         st.session_state.marked_errors.discard(st.session_state.selected_text)
                         st.rerun()
+                
+                # 增强的调试信息
+                with st.expander("🔍 图像和坐标调试信息", expanded=False):
+                    rotation_angle = self.get_rotation_angle()
+                    rotation_config = get_ocr_tool_rotation_config(self.validator.ocr_data, self.config)
+                    
+                    col_debug1, col_debug2, col_debug3 = st.columns(3)
+                    with col_debug1:
+                        st.write("**图像信息:**")
+                        st.write(f"原始尺寸: {image.width} x {image.height}")
+                        st.write(f"缩放后尺寸: {resized_image.width} x {resized_image.height}")
+                        st.write(f"当前角度: {rotation_angle}°")
+                        
+                    with col_debug2:
+                        st.write("**坐标信息:**")
+                        if selected_bbox:
+                            st.write(f"选中框: {selected_bbox}")
+                        st.write(f"总框数: {len(all_boxes)}")
+                        st.write(f"文本框数: {len(self.validator.text_bbox_mapping)}")
+                        
+                    with col_debug3:
+                        st.write("**配置信息:**")
+                        st.write(f"工具类型: {rotation_config.get('coordinates_are_pre_rotated', 'unknown')}")
+                        st.write(f"缓存状态: {len(self._rotated_image_cache)} 项")
+                        if hasattr(self, '_auto_detected_angle'):
+                            st.write(f"自动检测角度: {self._auto_detected_angle}°")
+                
                         
             except Exception as e:
                 st.error(f"❌ 图片处理失败: {e}")