소스 검색

не много структурные изменения и вернулись к двум камерам

Alex Sidorov 1 년 전
부모
커밋
af968f8d86

+ 57 - 27
docs/template_propusk.html

@@ -1,37 +1,67 @@
-<html lang="ru">
+<!DOCTYPE html>
+<html lang="en">
 
 <head>
     <meta charset="UTF-8">
-    <style>
-        * {
-            margin: 0;
-            padding: 0;
-        }
-    </style>
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Document</title>
 </head>
 
-<body>
+<body style="padding: 0; margin: 0; font-size: 12pt">
     {% for _ in range(2) %}
-    <table>
-        <tr>
-            <td colspan="2">
-                <img src="{{ face_photo }}" width="600" height="300"/>
-            </td>
-        </tr>
-        <tr>
-            <td><b>Временный пропуск №:</b> {{ id_propusk }}</td>
-            <td><b>Место выдачи:</b> {{ place }}</td>
-        </tr>
-        <tr>
-            <td><b>Дата выдачи:</b> {{ date_from }}</td>
-            <td><b>Принимающий:</b><br> {{ receiving_man }}</td>
-        </tr>
-        <tr>
-            <td><b>Действителен до:</b> {{ date_to }}</td>
-            <td><b>Цель визита:</b><br> {{ purpose_visite }}</td>
-        </tr>
+    <table >
+        <tbody>
+            <tr>
+                <td><b>Временный пропуск №:</b> {{ id_propusk }}</td>
+                <td rowspan="5">
+                    <img src="{{ face }}" height="200" width="300"/>
+                </td>
+            </tr>
+            <tr>
+                <td><b>Дата выдачи:</b> {{ date_from }}</td>
+                <td></td>
+            </tr>
+            <tr>
+                <td><b>Действителен до:</b> {{ date_to }}</td>
+            </tr>
+            <tr>
+                <td><b>Выдал:</b> {{ personal }}</td>
+            </tr>
+            <tr>
+                <td>
+                    <p style="font-size: 12pt;">__________________________________</p>
+                    <p style="font-size: 10pt !important;">&nbsp;&nbsp;Подпись сотрудника бюро пропусков</p>
+                    <p style="font-size: 10pt !important;">&nbsp;&nbsp;Печать</p>
+                </td>
+                <td></td>
+                
+            </tr>
+            <tr height="200" width="300">
+                <td><b>Место выдачи:</b>{{ place }}</td>
+                <td rowspan="6">
+                    <img src="{{ document }}" height="200" width="300" />
+                </td>
+            </tr>
+            <tr>
+                <td><b>Принимающий:</b></td>
+            </tr>
+            <tr>
+                <td>{{ receiving_man }}</td>
+            </tr>
+            <tr>
+                <td><b>Цель визита:</b></td>
+            </tr>
+            <tr> 
+                <td>{{ purpose_visite }}</td></tr>
+            <tr>
+                <td><b>Время выхода: __________________</b></td>
+            </tr>
+        </tbody>
     </table>
-    <hr />
+    <br>
+    <hr>
+    <br>
     {% endfor %}
 </body>
 

+ 0 - 68
docs/template_propusk_back.html

@@ -1,68 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-
-<head>
-    <meta charset="UTF-8">
-    <meta http-equiv="X-UA-Compatible" content="IE=edge">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <title>Document</title>
-</head>
-
-<body style="padding: 0; margin: 0; font-size: 12pt">
-    {% for _ in range(2) %}
-    <table >
-        <tbody>
-            <tr>
-                <td><b>Временный пропуск №:</b> {{ id_propusk }}</td>
-                <td rowspan="5">
-                    <img id="img_face" src="{{ face_photo }}" height="200" width="300"/>
-                </td>
-            </tr>
-            <tr>
-                <td><b>Дата выдачи:</b> {{ date_from }}</td>
-                <td></td>
-            </tr>
-            <tr>
-                <td><b>Действителен до:</b> {{ date_to }}</td>
-            </tr>
-            <tr>
-                <td><b>Выдал:</b> {{ personal }}</td>
-            </tr>
-            <tr>
-                <td>
-                    <p style="font-size: 12pt;">__________________________________</p>
-                    <p style="font-size: 10pt !important;">&nbsp;&nbsp;Подпись сотрудника бюро пропусков</p>
-                    <p style="font-size: 10pt !important;">&nbsp;&nbsp;Печать</p>
-                </td>
-                <td></td>
-                
-            </tr>
-            <tr height="200" width="300">
-                <td><b>Место выдачи:</b>{{ place }}</td>
-                <td rowspan="6">
-                    <img id="img_pasport" src="{{ pasport_photo }}" height="200" width="300" />
-                </td>
-            </tr>
-            <tr>
-                <td><b>Принимающий:</b></td>
-            </tr>
-            <tr>
-                <td>{{ receiving_man }}</td>
-            </tr>
-            <tr>
-                <td><b>Цель визита:</b></td>
-            </tr>
-            <tr> 
-                <td>{{ purpose_visite }}</td></tr>
-            <tr>
-                <td><b>Время выхода: __________________</b></td>
-            </tr>
-        </tbody>
-    </table>
-    <br>
-    <hr>
-    <br>
-    {% endfor %}
-</body>
-
-</html>

+ 38 - 0
docs/template_propusk_back_three.html

@@ -0,0 +1,38 @@
+<html lang="ru">
+
+<head>
+    <meta charset="UTF-8">
+    <style>
+        * {
+            margin: 0;
+            padding: 0;
+        }
+    </style>
+</head>
+
+<body>
+    {% for _ in range(2) %}
+    <table>
+        <tr>
+            <td colspan="2">
+                <img src="{{ face_photo }}" width="600" height="300"/>
+            </td>
+        </tr>
+        <tr>
+            <td><b>Временный пропуск №:</b> {{ id_propusk }}</td>
+            <td><b>Место выдачи:</b> {{ place }}</td>
+        </tr>
+        <tr>
+            <td><b>Дата выдачи:</b> {{ date_from }}</td>
+            <td><b>Принимающий:</b><br> {{ receiving_man }}</td>
+        </tr>
+        <tr>
+            <td><b>Действителен до:</b> {{ date_to }}</td>
+            <td><b>Цель визита:</b><br> {{ purpose_visite }}</td>
+        </tr>
+    </table>
+    <hr />
+    {% endfor %}
+</body>
+
+</html>

+ 10 - 11
module/CleanerImage.py

@@ -10,7 +10,6 @@ class CleanerImage:
         
         if os.path.exists(path):    
             self._files_in_db = self._get_list_files_from_db()
-            logger.info(self._files_in_db)
         else:
             logger.error(F"Не корректный путь: {path}")
             raise ValueError(F"Не корректный путь: {path}")
@@ -18,18 +17,18 @@ class CleanerImage:
     def _get_list_files_from_db(self) -> list:
         with connect() as conn:
             list_files = select(
-                list_propusk.c.face_photo,
-                list_propusk.c.pasport_photo
+                list_propusk.c.face,
+                list_propusk.c.document
             ).select_from(list_propusk)
             
-            return sum([[self._only_file(x[0]), self._only_file(x[0])]
-                        for x in conn.execute(list_files).all()], [])
-
-    def _only_file(self, path: str) -> str:
-        if '/' in path:
-            return path.split('/')[-1]
-        else:
-            return path.split('\\')[-1]
+            result = conn.execute(list_files).all()
+            
+            images = []
+            for face, document in result:
+                images.append(face)
+                images.append(document)
+            
+            return images
 
     def clear(self) -> None:
         _, _, files = os.walk(self._path).__next__()

+ 6 - 3
module/ModelPropusk.py

@@ -34,7 +34,8 @@ class PropuskData:
     place: Place
     receiving_man: str
     purpose_visite: str
-    face_photo: str
+    face: str
+    document: str
 
 
 class PropuskDataMethods:
@@ -45,7 +46,8 @@ class PropuskDataMethods:
                  place: Place = None,
                  receiving_man: str = None,
                  purpose_visite: str = None,
-                 face_photo: str = None):
+                 face: str = None,
+                 document: str = None):
 
         self._propusk_data = PropuskData(id_propusk,
                                          date_from,
@@ -54,7 +56,8 @@ class PropuskDataMethods:
                                          place,
                                          receiving_man,
                                          purpose_visite,
-                                         face_photo)
+                                         face,
+                                         document)
 
     @key_error
     def set_value(self, key: str, value: str | int | datetime | Personal | Place):

+ 2 - 2
module/WorkWithDB.py

@@ -59,8 +59,8 @@ list_propusk = Table("list_propusk", meta,
                      Column("place", Integer, ForeignKey("list_place.id"), nullable=False),
                      Column("receiving_man", Text, nullable=False),
                      Column("purpose_visite", Text, nullable=False),
-                     Column("face_photo", Text, nullable=False),
-                     Column("pasport_photo", Text, nullable=False),
+                     Column("face", Text, nullable=False),
+                     Column("document", Text, nullable=False),
                      Column("created", DateTime, default=func.now()),
                      Column("update", DateTime, default=func.now(),
                             onupdate=func.current_timestamp()))

+ 19 - 25
module/cam/IPCam.py

@@ -7,15 +7,6 @@ import cv2
 from module.ImageTool import create_filename
 from logger import logger
 
-def check_error(func):
-    def wrapper(*args):
-        try:
-            print(args)
-            return func(*args)
-        except ConnectionError:
-            args[0].stop_cam()
-            
-    return wrapper
 
 class IPCam(Thread):
     lnk_connect: str = None
@@ -26,48 +17,52 @@ class IPCam(Thread):
         Thread.__init__(self, parent)
         self.status = True
         self.cap = True
-    
+
     def run(self) -> None:
         logger.info("srarting take image from ip cam")
         self.net_work_error = False
         try:
             self.cap = cv2.VideoCapture()
-        
+
             if 'rtsp' in self.lnk_connect:
-                self.cap.open(self.lnk_connect)    
-            
+                self.cap.open(self.lnk_connect)
+
                 if not self.cap.isOpened():
                     raise ConnectionError
-            
+
             while self.status:
-            
+
                 if 'http' in self.lnk_connect:
                     self.cap.open(self.lnk_connect)
-                    
+
                     if not self.cap.isOpened():
                         raise ConnectionError
-                
+
                 ret, frame = self.cap.read()
                 if not ret:
                     continue
 
                 color_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
-            
+
                 h, w, ch = color_frame.shape
-                img = QImage(color_frame.data, w, h, ch * w, QImage.Format_RGB888)
-                self.__scaled_img = QPixmap.fromImage(img.scaled(h, w, Qt.KeepAspectRatio))
+                img = QImage(color_frame.data, w, h,
+                             ch * w, QImage.Format_RGB888)
+                self.__scaled_img = QPixmap.fromImage(
+                    img.scaled(h, w, Qt.KeepAspectRatio))
 
                 self.qLabel.setPixmap(self.__scaled_img)
-                
+
             # "http://admin:admin102030@192.168.1.108/cgi-bin/snapshot.cgi?2"\
-            
+
         except ConnectionError:
             logger.error("Нет сети или не правильная строка подключения")
             logger.info("stop take image from ip cam")
+
             self.status = False
-            self.qLabel.setText('Нет сети или не правильная строка подключения')    
+            self.qLabel.setText(
+                'Нет сети или не правильная строка подключения')
         except RuntimeError:
-            self.status = False        
+            self.status = False
 
     def stop_cam(self):
         logger.info("stop take image from ip cam")
@@ -81,4 +76,3 @@ class IPCam(Thread):
         qLabel.setPixmap(self.__scaled_img)
         self.__scaled_img.save(name_file, 'jpg')
         return name_file
-    

+ 2 - 4
PropuskWidgets/PCamChecked.py → widgets/PCamChecked.py

@@ -1,9 +1,7 @@
 
 from PySide6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLineEdit, QComboBox, QPushButton, QMessageBox
-from PropuskWidgets.PStackedWidget import PStackedWidget
-from module.cam import IPCam, USBCam, get_list_name_cam, check_error
-from module.MyMessageBox import show_dialog
-from time import sleep
+from widgets.PStackedWidget import PStackedWidget
+from module.cam import IPCam, USBCam, get_list_name_cam
 
 
 class PCamChecked(QWidget):

+ 0 - 0
PropuskWidgets/PLineEdit.py → widgets/PLineEdit.py


+ 5 - 5
PropuskWidgets/PStackedWidget.py → widgets/PStackedWidget.py

@@ -52,8 +52,8 @@ class PStackedWidget(QStackedWidget):
     def to_video(self) -> None:
         self.setCurrentIndex(1)
 
-    def cupture_image(self) -> None:
-        if self.__mode == 'video':
-            self.video = self.video.cupture_image(self.image)
-        else:
-            self.video = self.video.cupture_image(self.image)
+    # def cupture_image(self) -> None:
+    #     if self.__mode == 'video':
+    #         self.video = self.video.cupture_image(self.image)
+    #     else:
+    #         self.video = self.video.cupture_image(self.image)

+ 17 - 0
widgets/__init__.py

@@ -0,0 +1,17 @@
+from .PStackedWidget import *
+from .PLineEdit import *
+from .PCamChecked import *
+
+
+
+def create_widget_cam_shecked(obj, layout, name_object: str, mode: str = 'video', ) -> PCamChecked:
+    widget = PCamChecked(obj, mode=mode)
+    widget.setObjectName(name_object)
+    layout.addWidget(widget)
+    return widget
+    
+def create_widget_stacked(obj, layout, name_object: str,  mode: str = 'video') -> PStackedWidget:
+    widget = PStackedWidget(obj, mode=mode)
+    widget.setObjectName(name_object)
+    layout.addWidget(widget)
+    return widget

+ 9 - 5
window/DialogHistory.py

@@ -71,20 +71,24 @@ class DialogHistory(Ui_DialogHistory, QDialog):
                     func.format(list_place.c.name_place).label("place"),
                     list_propusk.c.receiving_man,
                     list_propusk.c.purpose_visite,
-                    list_propusk.c.face_photo
+                    list_propusk.c.face,
+                    list_propusk.c.document
                 ).select_from(list_propusk).join(
                     list_personal, list_propusk.c.personal == list_personal.c.id
+                ).join(
+                    list_place, list_propusk.c.place == list_place.c.id
                 ).where(list_propusk.c.id_propusk == id_propusk)
             ).fetchone()
 
             pdm = PropuskDataMethods(*row)
-            path_photo = os.path.join(os.environ.get('PHOTO_DIR'), pdm.get_value("face_photo"))
-            # pdm.set_value("face_photo", rotate_image(path_photo))
-            pdm.set_value("face_photo", path_photo)
+            face = os.path.join(os.environ.get('PHOTO_DIR'), pdm.get_value("face"))
+            documet = os.path.join(os.environ.get('PHOTO_DIR'), pdm.get_value("document"))
+            pdm.set_value("face", face)
+            pdm.set_value("document", documet)
+            
             
             render_text = str(TemplatePropusk(pdm._propusk_data.__dict__,
                                               os.path.join(os.path.dirname(
                                                   os.path.abspath(__package__)), 'docs')
                                               ))
-            # logger.info(render_text)
             self.browser.setText(render_text)

+ 7 - 10
window/DialogSettingCam.py

@@ -3,7 +3,7 @@ from PySide6.QtWidgets import QDialog
 from PySide6.QtCore import Qt, Slot
 
 from module.WorkWithDB import *
-from PropuskWidgets.PCamChecked import PCamChecked
+from widgets import create_widget_cam_shecked
 from logger import logger
 
 
@@ -39,19 +39,16 @@ class SettingCam(QDialog, Ui_DialogSettingCam):
     def __recreate_widget(self, select_mode: str = 'video') -> None:
         self.__del_widget()
         if self.tabWidget.currentIndex() == 0:
-            self.__create_widget(
-                mode=select_mode,
-                tab=self.tab,
+            self.widget = create_widget_cam_shecked(mode=select_mode,
+                name_object=u'widget',
+                obj=self.tab,
                 layout=self.verticalLayout)
         else:
-            self.__create_widget(
-                tab=self.tab_2,
+            self.widget = create_widget_cam_shecked(
+                name_object=U'widget',
+                obj=self.tab_2,
                 layout=self.verticalLayout_3)
 
-    def __create_widget(self, tab, layout, mode: str = 'video') -> None:
-        self.widget = PCamChecked(tab, mode=mode)
-        self.widget.setObjectName('widget')
-        layout.addWidget(self.widget)
 
     def __del_widget(self) -> None:
         if self.widget is not None:

+ 149 - 110
window/MainWindow.py

@@ -1,15 +1,14 @@
 from PySide6.QtWidgets import QMainWindow, QMessageBox
-from PySide6.QtCore import Slot, QDate, QDateTime
+from PySide6.QtCore import QDate, QDateTime
 
 from module.WorkWithDB import *
 from module.MyMessageBox import show_dialog
-from PropuskWidgets.PStackedWidget import PStackedWidget
 from module.TemplatePropusk import TemplatePropusk
 from module.Printer import Printer
 from module.lang.ru import *
-from module.ImageTool import rotate_image
-from module.cam import IPCam, USBCam
+from module.cam import IPCam, USBCam, load_image
 
+from widgets import PStackedWidget, create_widget_stacked
 
 from .ui_py.ui_MainWindow import Ui_MainWindow
 from .ListPersonal import ListPersonal
@@ -23,7 +22,9 @@ from time import sleep
 from datetime import datetime
 from logger import logger
 from pathlib import Path
-import platform
+
+
+vecrot_cam_from_db = [str, str, str]
 
 
 class MainWindow(QMainWindow, Ui_MainWindow):
@@ -36,51 +37,84 @@ class MainWindow(QMainWindow, Ui_MainWindow):
         self.date_from.setDateTime(QDateTime().currentDateTime())
         self.date_to.setDateTime(QDateTime().currentDateTime())
 
-        
+        self.__init_menu_action()
+        self.__init_btn_action()
+        self.__update_list_combobox()
+        self.__check_setting_cam()
+        self.__create_widget_face_cam()
 
-        self._init_menu_btn_action()
-        self._init_push_btn_action()
-        self._update_list_combobox()
-        self._check_setting_cam()
-        self._init_widget_cam()
-        
-        self.stacked_widget.currentChanged.connect(
+        self.stacked_document.currentChanged.connect(
             self.__change_text_in_btn_start_cam
         )
 
-    def open_history(self) -> None:
-        DialogHistory(self).exec_()
+        self.tabWidget.currentChanged.connect(
+            self.change_tab
+        )
 
     def __change_text_in_btn_start_cam(self):
-        match self.stacked_widget.currentIndex():
-            case 0: self.btn_start_cam_photo.setText(start_cam)
-            case 1: self.btn_start_cam_photo.setText(stop_cam)
+        match self.tabWidget.currentIndex():
+            case 0: self.btn_start_cam.setText(start_cam)
+            case 1: self.btn_start_cam.setText(stop_cam)
 
-    def _init_menu_btn_action(self) -> None:
+    def __init_menu_action(self) -> None:
         self.action_open_history.triggered.connect(self.open_history)
         self.btn_show_personal_window.triggered.connect(
-            self._show_personal_window
+            self.__show_personal_window
         )
         self.btn_show_place_window.triggered.connect(
-            self._show_place_window
+            self.__show_place_window
         )
         self.setting_cam.triggered.connect(
-            self._show_setting_cam_window
+            self.__show_setting_cam_window
         )
         self.update_list.triggered.connect(
-            self._update_list_combobox
+            self.__update_list_combobox
         )
 
         self.btn_show_about.triggered.connect(
-            self._show_about_dialog
+            self.__show_about_dialog
         )
 
-    def _show_about_dialog(self):
+    def __init_btn_action(self) -> None:
+        self.btn_start_cam.clicked.connect(
+            self.__press_btn_start_cam
+        )
+
+        self.capturePhoto.clicked.connect(
+            self.__take_image_face
+        )
+
+        self.btn_save.clicked.connect(self.__save)
+        self.btn_clear.clicked.connect(self.__clear)
+        self.btn_print.clicked.connect(self.__print)
+
+    def __show_about_dialog(self):
         DialogAbout(self).exec_()
 
-    def _check_setting_cam(self) -> None:
+    def __show_personal_window(self) -> None:
+        ListPersonal(self).exec_()
+        self.__update_list_combobox()
+
+    def __show_place_window(self) -> None:
+        ListPlace(self).exec_()
+        self.__update_list_combobox()
+
+    def __show_setting_cam_window(self) -> None:
+        SettingCam(self).exec_()
+        self.__check_setting_cam()
+        self.__create_widget_face_cam()
+
+    def open_history(self) -> None:
+        DialogHistory(self).exec_()
+
+    def change_tab(self) -> None:
+        self.__check_setting_cam()
+        if self.tabWidget.currentIndex() == 1:
+            self.__mode = 'video'
+
+    def __check_setting_cam(self) -> None:
         try:
-            self.__mode, self.__cam = self.__get_selected_cam()
+            self.__mode, self.__cam_face, self.__cam_document = self.__get_selected_cam()
         except ValueError:
             logger.warning(warring_cams.get("title"))
             if show_dialog(
@@ -88,41 +122,16 @@ class MainWindow(QMainWindow, Ui_MainWindow):
                 warring_cams.get("title"),
                 warring_cams.get("body")
             ):
-                self._show_setting_cam_window()
-                self._check_setting_cam()
+                self.__show_setting_cam_window()
+                self.__check_setting_cam()
             else:
                 self.close()
 
-    def _init_push_btn_action(self) -> None:
-        self.btn_start_cam_photo.clicked.connect(
-            self._start_cam_photo
-        )
-
-        self.capturePhoto.clicked.connect(
-            self._take_image_face
-        )
-
-        self.btn_save.clicked.connect(self._save)
-        self.btn_clear.clicked.connect(self._clear)
-        self.btn_print.clicked.connect(self._print)
-
-    def _show_personal_window(self) -> None:
-        ListPersonal(self).exec_()
-        self._update_list_combobox()
+    def __update_list_combobox(self) -> None:
+        self.__load_personal()
+        self.__load_place()
 
-    def _show_place_window(self) -> None:
-        ListPlace(self).exec_()
-        self._update_list_combobox()
-
-    def _show_setting_cam_window(self) -> None:
-        SettingCam(self).exec_()
-        self._check_setting_cam()
-
-    def _update_list_combobox(self) -> None:
-        self._load_personal()
-        self._load_place()
-
-    def _load_personal(self) -> None:
+    def __load_personal(self) -> None:
         self.personal_combobox.clear()
 
         with connect() as conn:
@@ -135,7 +144,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
                     userData=personal.id
                 )
 
-    def _load_place(self) -> None:
+    def __load_place(self) -> None:
         self.place_combobox.clear()
 
         with connect() as conn:
@@ -147,62 +156,77 @@ class MainWindow(QMainWindow, Ui_MainWindow):
                     userData=place.id
                 )
 
-    def __get_selected_cam(self) -> bool:
+    def __get_selected_cam(self) -> vecrot_cam_from_db:
+        '''
+        return: 
+            str -> video, snapshot
+            str -> ссылка для подключения к ip камеры или названия камеры (для лица)
+            str -> названия камеры (для документа)
+        '''
         with connect() as conn:
             cam = conn.execute(
                 cam_setting.select()
-            ).fetchone()
+            ).all()
 
             try:
-                return cam.mode, cam.selected_cam
+                return cam[0].mode, cam[0].selected_cam, cam[1].selected_cam
             except:
-                raise ValueError('Нет записи о камерах')
+                logger.error('Нет записи о камерах')
+                show_dialog(
+                    QMessageBox.Icon.Critical,
+                    'Отсутствуют записи о камерах',
+                    'Отсутствуют записи о камерах'
+                )
 
-    def _init_widget_cam(self) -> None:
-        
-        self.stacked_widget = PStackedWidget(self.groupBox_2, self.__mode)
-        self.stacked_widget.setObjectName(u'stacked_widget')
-        self.verticalLayout_4.addWidget(self.stacked_widget)
-        
-    def _start_cam_photo(self) -> None:
+    def __press_btn_start_cam(self):
+        match self.tabWidget.currentIndex():
+            case 0: self.__start_cam(self.stacked_face, self.__cam_face)
+            case 1: self.__start_cam(self.stacked_document, self.__cam_document)
+
+    def __start_cam(self, widget: PStackedWidget, cam: str) -> None:
         if self.__wwc is None:
-            self.stacked_widget.to_video()
-            self._create_wwc()
+            widget.to_video()
+            self.__create_wwc(widget, cam)
         else:
-            self.__stop_cam()      
-            self.stacked_widget.to_image()
-            
-    def _create_wwc(self) -> None:
-        match self.__mode:
-            case 'video':
-                self.__wwc = USBCam(self.stacked_widget.video, self.__cam)
-                self.__wwc.start_cam()
-            case 'snapshot':
-                self.__wwc = IPCam()
-                self.__wwc.qLabel = self.stacked_widget.video
-                self.__wwc.lnk_connect = self.__cam
-                self.__wwc.start()
-            case _: return None
-
-    def _take_image_face(self) -> None:
-        self.__file_name = self.__wwc.cupture_image(self.stacked_widget.image)
+            self.__stop_cam()
+            widget.to_image()
+
+    def __create_wwc(self, widget: PStackedWidget, cam: str) -> None:
+        if self.__mode in 'snapshot':
+            self.__wwc = IPCam()
+            self.__wwc.qLabel = widget.video
+            self.__wwc.lnk_connect = cam
+            self.__wwc.start()
+        else:
+            self.__wwc = USBCam(widget.video, cam)
+            self.__wwc.start_cam()
+
+    def __take_image_face(self) -> None:
+        if self.tabWidget.currentIndex() == 1:
+            self.__file_name_document = self.__wwc.cupture_image(self.stacked_document.image)
+            sleep(1)
+            load_image(self.stacked_document.image, self.__file_name_document)
+        else:
+            self.__file_name_face = self.__wwc.cupture_image(self.stacked_face.image)
+            sleep(1)
+            load_image(self.stacked_face.image, self.__file_name_face)
             
-        sleep(1)
-        self.stacked_widget.to_image()
         self.__stop_cam()
 
-    def _print(self) -> None:
+    def __print(self) -> None:
         if self.data_propusk is None:
-            self._save()
+            self.__save()
 
         propusk_data = self.data_propusk.copy()
-        propusk_data["personal"] = self.personal_combobox.currentText()
-        propusk_data["place"] = self.place_combobox.currentText()
-        propusk_data["date_from"] = self.date_from.dateTime().toString(
-            'dd.MM.yyyy hh:mm')
-        propusk_data["date_to"] = self.date_to.dateTime().toString(
-            'dd.MM.yyyy hh:mm')
-        propusk_data["face_photo"] = self.__file_name
+        
+        propusk_data.update({
+            "personal": self.personal_combobox.currentText(),
+            "place": self.place_combobox.currentText(),
+            "date_from": self.date_from.dateTime().toString('dd.MM.yyyy hh:mm'),
+            "date_to": self.date_to.dateTime().toString('dd.MM.yyyy hh:mm'),
+            "face": self.__file_name_face,
+            "document": self.__file_name_face        
+        })
 
         render_text = TemplatePropusk(
             propusk_data,
@@ -211,13 +235,13 @@ class MainWindow(QMainWindow, Ui_MainWindow):
 
         Printer(str(render_text)).print()
 
-    def _clear(self) -> None:
+    def __clear(self) -> None:
         if self.data_propusk is not None:
             self.data_propusk = None
 
-        self._set_default_data()
+        self.__set_default_data()
 
-    def _save(self) -> None:
+    def __save(self) -> None:
         date_from = self.date_from.dateTime().toMSecsSinceEpoch() / 1000
         date_to = self.date_to.dateTime().toMSecsSinceEpoch() / 1000
 
@@ -229,8 +253,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
             "place": self.place_combobox.currentData(),
             "receiving_man": self.receiving_man.toPlainText(),
             "purpose_visite": self.purpose_visite.toPlainText(),
-            "face_photo": F"{Path(self.__file_name).name}",
-            "pasport_photo": F"{Path(self.__file_name).name}"
+            "face": F"{Path(self.__file_name_face).name}",
+            "document": F"{Path(self.__file_name_document).name}"
         }
 
         with connect() as conn:
@@ -238,14 +262,13 @@ class MainWindow(QMainWindow, Ui_MainWindow):
                 list_propusk.insert().values(**self.data_propusk)
             )
 
-    def _set_default_data(self) -> None:
+    def __set_default_data(self) -> None:
         self.number_propusk.clear()
         self.date_from.setDate(QDate().currentDate())
         self.date_to.setDate(QDate().currentDate())
-        
+
         if self.__wwc is not None:
             self.__stop_cam()
-            self.stacked_widget.to_image()
             
         self.receiving_man.clear()
         self.purpose_visite.clear()
@@ -254,5 +277,21 @@ class MainWindow(QMainWindow, Ui_MainWindow):
         if self.__wwc is not None:
             self.__wwc.stop_cam()
             self.__wwc = None
-            
-        self.stacked_widget.to_image()
+
+        if self.tabWidget.currentIndex() == 1:
+            self.stacked_document.to_image()
+        else: self.stacked_face.to_image()
+
+    def __create_widget_face_cam(self) -> None:
+        if hasattr(self, 'stacked_face'):
+            self.gridLayout.removeWidget(self.stacked_face)
+        self.stacked_face = create_widget_stacked(
+            name_object=u'stacked_face',
+            obj=self.tab,
+            layout=self.gridLayout,
+            mode=self.__mode)
+        
+        self.stacked_face.currentChanged.connect(
+            self.__change_text_in_btn_start_cam
+        )
+        

+ 310 - 262
window/ui/MainWindow.ui

@@ -10,7 +10,7 @@
     <x>0</x>
     <y>0</y>
     <width>920</width>
-    <height>511</height>
+    <height>588</height>
    </rect>
   </property>
   <property name="sizePolicy">
@@ -44,273 +44,321 @@
    <property name="autoFillBackground">
     <bool>false</bool>
    </property>
-   <layout class="QGridLayout" name="gridLayout">
-    <item row="0" column="0">
-     <widget class="QGroupBox" name="groupBox">
-      <property name="minimumSize">
-       <size>
-        <width>400</width>
-        <height>0</height>
-       </size>
-      </property>
-      <property name="title">
-       <string>Информация:</string>
-      </property>
-      <layout class="QVBoxLayout" name="verticalLayout_3">
-       <item>
-        <layout class="QHBoxLayout" name="horizontalLayout">
-         <item>
-          <widget class="QLabel" name="label">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="text">
-            <string>Временный пропуск №:</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="number_propusk">
-           <property name="inputMask">
-            <string/>
-           </property>
-           <property name="text">
-            <string/>
-           </property>
-           <property name="maxLength">
-            <number>32767</number>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout" name="horizontalLayout_2">
-         <item>
-          <widget class="QLabel" name="label_2">
-           <property name="text">
-            <string>Дата и время выдачи:</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QDateTimeEdit" name="date_from">
-           <property name="dateTime">
-            <datetime>
-             <hour>21</hour>
-             <minute>0</minute>
-             <second>0</second>
-             <year>1999</year>
-             <month>12</month>
-             <day>31</day>
-            </datetime>
-           </property>
-           <property name="timeSpec">
-            <enum>Qt::UTC</enum>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout" name="horizontalLayout_3">
-         <item>
-          <widget class="QLabel" name="label_4">
-           <property name="text">
-            <string>Действителене до:</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QDateTimeEdit" name="date_to"/>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout" name="horizontalLayout_4">
-         <item>
-          <widget class="QLabel" name="label_3">
-           <property name="text">
-            <string>Выдал:</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QComboBox" name="personal_combobox"/>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout" name="horizontalLayout_5">
-         <item>
-          <widget class="QLabel" name="label_5">
-           <property name="text">
-            <string>Место выдачи:</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QComboBox" name="place_combobox"/>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QVBoxLayout" name="verticalLayout">
-         <item>
-          <widget class="QLabel" name="label_6">
-           <property name="text">
-            <string>Принимающий:</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QTextEdit" name="receiving_man"/>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QVBoxLayout" name="verticalLayout_2">
-         <item>
-          <widget class="QLabel" name="label_7">
-           <property name="text">
-            <string>Цель визита:</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QTextEdit" name="purpose_visite"/>
-         </item>
-        </layout>
-       </item>
-      </layout>
-     </widget>
-    </item>
-    <item row="0" column="1" colspan="2">
-     <widget class="QGroupBox" name="groupBox_2">
-      <property name="title">
-       <string>Фото</string>
-      </property>
-      <layout class="QVBoxLayout" name="verticalLayout_4">
-       <item>
-        <widget class="QStackedWidget" name="stacked_widget_photo">
-         <property name="enabled">
-          <bool>true</bool>
-         </property>
-         <property name="toolTip">
-          <string notr="true"/>
-         </property>
-         <property name="statusTip">
-          <string/>
-         </property>
-         <widget class="QWidget" name="page">
-          <layout class="QGridLayout" name="gridLayout_2">
-           <item row="0" column="0">
-            <widget class="QLabel" name="imagePhoto">
-             <property name="enabled">
-              <bool>true</bool>
-             </property>
-             <property name="sizePolicy">
-              <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
-               <horstretch>0</horstretch>
-               <verstretch>0</verstretch>
-              </sizepolicy>
-             </property>
-             <property name="frameShape">
-              <enum>QFrame::Box</enum>
-             </property>
-             <property name="frameShadow">
-              <enum>QFrame::Raised</enum>
-             </property>
-             <property name="text">
-              <string/>
-             </property>
-             <property name="wordWrap">
-              <bool>false</bool>
-             </property>
+   <layout class="QVBoxLayout" name="verticalLayout_9">
+    <item>
+     <layout class="QVBoxLayout" name="verticalLayout_6">
+      <item>
+       <layout class="QHBoxLayout" name="horizontalLayout_11">
+        <item>
+         <layout class="QHBoxLayout" name="horizontalLayout_7">
+          <item>
+           <widget class="QGroupBox" name="groupBox">
+            <property name="minimumSize">
+             <size>
+              <width>400</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="title">
+             <string>Информация:</string>
+            </property>
+            <layout class="QVBoxLayout" name="verticalLayout_3">
+             <item>
+              <layout class="QHBoxLayout" name="horizontalLayout">
+               <item>
+                <widget class="QLabel" name="label">
+                 <property name="sizePolicy">
+                  <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+                   <horstretch>0</horstretch>
+                   <verstretch>0</verstretch>
+                  </sizepolicy>
+                 </property>
+                 <property name="text">
+                  <string>Временный пропуск №:</string>
+                 </property>
+                </widget>
+               </item>
+               <item>
+                <widget class="QLineEdit" name="number_propusk">
+                 <property name="inputMask">
+                  <string/>
+                 </property>
+                 <property name="text">
+                  <string/>
+                 </property>
+                 <property name="maxLength">
+                  <number>32767</number>
+                 </property>
+                </widget>
+               </item>
+              </layout>
+             </item>
+             <item>
+              <layout class="QHBoxLayout" name="horizontalLayout_2">
+               <item>
+                <widget class="QLabel" name="label_2">
+                 <property name="text">
+                  <string>Дата и время выдачи:</string>
+                 </property>
+                </widget>
+               </item>
+               <item>
+                <widget class="QDateTimeEdit" name="date_from">
+                 <property name="dateTime">
+                  <datetime>
+                   <hour>18</hour>
+                   <minute>0</minute>
+                   <second>0</second>
+                   <year>1999</year>
+                   <month>12</month>
+                   <day>31</day>
+                  </datetime>
+                 </property>
+                 <property name="timeSpec">
+                  <enum>Qt::UTC</enum>
+                 </property>
+                </widget>
+               </item>
+              </layout>
+             </item>
+             <item>
+              <layout class="QHBoxLayout" name="horizontalLayout_3">
+               <item>
+                <widget class="QLabel" name="label_4">
+                 <property name="text">
+                  <string>Действителене до:</string>
+                 </property>
+                </widget>
+               </item>
+               <item>
+                <widget class="QDateTimeEdit" name="date_to"/>
+               </item>
+              </layout>
+             </item>
+             <item>
+              <layout class="QHBoxLayout" name="horizontalLayout_4">
+               <item>
+                <widget class="QLabel" name="label_3">
+                 <property name="text">
+                  <string>Выдал:</string>
+                 </property>
+                </widget>
+               </item>
+               <item>
+                <widget class="QComboBox" name="personal_combobox"/>
+               </item>
+              </layout>
+             </item>
+             <item>
+              <layout class="QHBoxLayout" name="horizontalLayout_5">
+               <item>
+                <widget class="QLabel" name="label_5">
+                 <property name="text">
+                  <string>Место выдачи:</string>
+                 </property>
+                </widget>
+               </item>
+               <item>
+                <widget class="QComboBox" name="place_combobox"/>
+               </item>
+              </layout>
+             </item>
+             <item>
+              <layout class="QVBoxLayout" name="verticalLayout">
+               <item>
+                <widget class="QLabel" name="label_6">
+                 <property name="text">
+                  <string>Принимающий:</string>
+                 </property>
+                </widget>
+               </item>
+               <item>
+                <widget class="QTextEdit" name="receiving_man"/>
+               </item>
+              </layout>
+             </item>
+             <item>
+              <layout class="QVBoxLayout" name="verticalLayout_2">
+               <item>
+                <widget class="QLabel" name="label_7">
+                 <property name="text">
+                  <string>Цель визита:</string>
+                 </property>
+                </widget>
+               </item>
+               <item>
+                <widget class="QTextEdit" name="purpose_visite"/>
+               </item>
+              </layout>
+             </item>
+            </layout>
+           </widget>
+          </item>
+         </layout>
+        </item>
+        <item>
+         <layout class="QVBoxLayout" name="verticalLayout_5">
+          <item>
+           <widget class="QTabWidget" name="tabWidget">
+            <property name="currentIndex">
+             <number>0</number>
+            </property>
+            <widget class="QWidget" name="tab">
+             <attribute name="title">
+              <string>Tab 1</string>
+             </attribute>
+             <layout class="QGridLayout" name="gridLayout">
+              <item row="0" column="0">
+               <layout class="QVBoxLayout" name="verticalLayout_4">
+                <item>
+                 <widget class="QStackedWidget" name="stacked_widget_photo">
+                  <property name="enabled">
+                   <bool>true</bool>
+                  </property>
+                  <property name="toolTip">
+                   <string notr="true"/>
+                  </property>
+                  <property name="statusTip">
+                   <string/>
+                  </property>
+                  <widget class="QWidget" name="page">
+                   <layout class="QGridLayout" name="gridLayout_3">
+                    <item row="0" column="0">
+                     <widget class="QLabel" name="imagePhoto">
+                      <property name="enabled">
+                       <bool>true</bool>
+                      </property>
+                      <property name="sizePolicy">
+                       <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+                        <horstretch>0</horstretch>
+                        <verstretch>0</verstretch>
+                       </sizepolicy>
+                      </property>
+                      <property name="frameShape">
+                       <enum>QFrame::Box</enum>
+                      </property>
+                      <property name="frameShadow">
+                       <enum>QFrame::Raised</enum>
+                      </property>
+                      <property name="text">
+                       <string/>
+                      </property>
+                      <property name="wordWrap">
+                       <bool>false</bool>
+                      </property>
+                     </widget>
+                    </item>
+                   </layout>
+                  </widget>
+                  <widget class="QWidget" name="page_2">
+                   <layout class="QGridLayout" name="gridLayout_4">
+                    <item row="0" column="0">
+                     <widget class="QVideoWidget" name="face_video_widget">
+                      <property name="enabled">
+                       <bool>false</bool>
+                      </property>
+                      <property name="sizePolicy">
+                       <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+                        <horstretch>0</horstretch>
+                        <verstretch>0</verstretch>
+                       </sizepolicy>
+                      </property>
+                     </widget>
+                    </item>
+                   </layout>
+                  </widget>
+                 </widget>
+                </item>
+               </layout>
+              </item>
+             </layout>
             </widget>
-           </item>
-          </layout>
-         </widget>
-         <widget class="QWidget" name="page_2">
-          <layout class="QGridLayout" name="gridLayout_4">
-           <item row="0" column="0">
-            <widget class="QVideoWidget" name="face_video_widget">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="sizePolicy">
-              <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
-               <horstretch>0</horstretch>
-               <verstretch>0</verstretch>
-              </sizepolicy>
-             </property>
+            <widget class="QWidget" name="tab_2">
+             <attribute name="title">
+              <string>Tab 2</string>
+             </attribute>
             </widget>
-           </item>
-          </layout>
+           </widget>
+          </item>
+          <item>
+           <layout class="QHBoxLayout" name="horizontalLayout_6">
+            <item>
+             <widget class="QPushButton" name="btn_start_cam">
+              <property name="text">
+               <string>Запустить камеру</string>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QPushButton" name="capturePhoto">
+              <property name="text">
+               <string>Сфотографировать</string>
+              </property>
+             </widget>
+            </item>
+           </layout>
+          </item>
+         </layout>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <spacer name="verticalSpacer">
+        <property name="orientation">
+         <enum>Qt::Vertical</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>20</width>
+          <height>40</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <layout class="QHBoxLayout" name="horizontalLayout_8">
+        <item>
+         <widget class="QPushButton" name="btn_clear">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="text">
+           <string>Отчистить</string>
+          </property>
          </widget>
-        </widget>
-       </item>
-       <item>
-        <widget class="QSplitter" name="splitter">
-         <property name="orientation">
-          <enum>Qt::Horizontal</enum>
-         </property>
-         <widget class="QPushButton" name="btn_start_cam_photo">
+        </item>
+        <item>
+         <widget class="QPushButton" name="btn_save">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
           <property name="text">
-           <string>Запустить камеру</string>
+           <string>Сохранить</string>
           </property>
          </widget>
-         <widget class="QPushButton" name="capturePhoto">
+        </item>
+        <item>
+         <widget class="QPushButton" name="btn_print">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
           <property name="text">
-           <string>Сфотографировать</string>
+           <string>Печать</string>
           </property>
          </widget>
-        </widget>
-       </item>
-      </layout>
-     </widget>
-    </item>
-    <item row="1" column="0">
-     <widget class="QPushButton" name="btn_clear">
-      <property name="sizePolicy">
-       <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
-        <horstretch>0</horstretch>
-        <verstretch>0</verstretch>
-       </sizepolicy>
-      </property>
-      <property name="text">
-       <string>Отчистить</string>
-      </property>
-     </widget>
-    </item>
-    <item row="1" column="1">
-     <widget class="QPushButton" name="btn_save">
-      <property name="sizePolicy">
-       <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
-        <horstretch>0</horstretch>
-        <verstretch>0</verstretch>
-       </sizepolicy>
-      </property>
-      <property name="text">
-       <string>Сохранить</string>
-      </property>
-     </widget>
-    </item>
-    <item row="1" column="2">
-     <widget class="QPushButton" name="btn_print">
-      <property name="sizePolicy">
-       <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
-        <horstretch>0</horstretch>
-        <verstretch>0</verstretch>
-       </sizepolicy>
-      </property>
-      <property name="text">
-       <string>Печать</string>
-      </property>
-     </widget>
+        </item>
+       </layout>
+      </item>
+     </layout>
     </item>
    </layout>
   </widget>
@@ -320,7 +368,7 @@
      <x>0</x>
      <y>0</y>
      <width>920</width>
-     <height>23</height>
+     <height>28</height>
     </rect>
    </property>
    <property name="mouseTracking">
@@ -394,7 +442,7 @@
   </action>
   <action name="setting_cam">
    <property name="text">
-    <string>Настроки камеры</string>
+    <string>Настройки камеры</string>
    </property>
   </action>
   <action name="btn_show_personal_window">
@@ -404,7 +452,7 @@
   </action>
   <action name="btn_show_place_window">
    <property name="text">
-    <string>Место выдочи</string>
+    <string>Место выдачи</string>
    </property>
   </action>
   <action name="update_list">

+ 0 - 1
window/ui_py/ui_DialogSettingCam.py

@@ -11,7 +11,6 @@
 from PySide6.QtCore import (QCoreApplication, QMetaObject)
 from PySide6.QtWidgets import (
     QComboBox, QPushButton, QTabWidget, QVBoxLayout, QWidget)
-from PropuskWidgets.PCamChecked import PCamChecked
 
 
 class Ui_DialogSettingCam(object):

+ 97 - 50
window/ui_py/ui_MainWindow.py

@@ -12,10 +12,12 @@ from PySide6.QtCore import (QCoreApplication, QDate, QDateTime,
                             QMetaObject, QRect, QSize, QTime, Qt)
 from PySide6.QtGui import (QAction)
 from PySide6.QtWidgets import (QComboBox, QDateTimeEdit,
-                               QGridLayout, QGroupBox, QHBoxLayout, QLabel, QMenu, QMenuBar,
-                               QPushButton, QSizePolicy, QSplitter, QStatusBar, QTextEdit, QVBoxLayout, QWidget)
-from PropuskWidgets.PLineEdit import PLineEdit
-from PropuskWidgets.PStackedWidget import PStackedWidget
+                               QGridLayout, QGroupBox, QHBoxLayout, QLabel,
+                               QMenu, QMenuBar, QPushButton, QSizePolicy, QSpacerItem,
+                               QStatusBar, QTabWidget, QTextEdit, QVBoxLayout,
+                               QWidget)
+
+from widgets import PStackedWidget, PLineEdit
 
 
 class Ui_MainWindow(object):
@@ -23,7 +25,7 @@ class Ui_MainWindow(object):
         if not MainWindow.objectName():
             MainWindow.setObjectName(u"MainWindow")
         MainWindow.setWindowModality(Qt.WindowModal)
-        MainWindow.resize(920, 511)
+        MainWindow.resize(920, 588)
         sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
         sizePolicy.setHorizontalStretch(0)
         sizePolicy.setVerticalStretch(0)
@@ -33,10 +35,10 @@ class Ui_MainWindow(object):
         MainWindow.setBaseSize(QSize(864, 430))
         self.actionExit = QAction(MainWindow)
         self.actionExit.setObjectName(u"actionExit")
-        # self.actionSave = QAction(MainWindow)
-        # self.actionSave.setObjectName(u"actionSave")
-        # self.actionLoad = QAction(MainWindow)
-        # self.actionLoad.setObjectName(u"actionLoad")
+        self.actionSave = QAction(MainWindow)
+        self.actionSave.setObjectName(u"actionSave")
+        self.actionLoad = QAction(MainWindow)
+        self.actionLoad.setObjectName(u"actionLoad")
         self.actionExit_2 = QAction(MainWindow)
         self.actionExit_2.setObjectName(u"actionExit_2")
         self.setting_cam = QAction(MainWindow)
@@ -62,8 +64,14 @@ class Ui_MainWindow(object):
         self.centralwidget.setSizePolicy(sizePolicy)
         self.centralwidget.setFocusPolicy(Qt.NoFocus)
         self.centralwidget.setAutoFillBackground(False)
-        self.gridLayout = QGridLayout(self.centralwidget)
-        self.gridLayout.setObjectName(u"gridLayout")
+        self.verticalLayout_9 = QVBoxLayout(self.centralwidget)
+        self.verticalLayout_9.setObjectName(u"verticalLayout_9")
+        self.verticalLayout_6 = QVBoxLayout()
+        self.verticalLayout_6.setObjectName(u"verticalLayout_6")
+        self.horizontalLayout_11 = QHBoxLayout()
+        self.horizontalLayout_11.setObjectName(u"horizontalLayout_11")
+        self.horizontalLayout_7 = QHBoxLayout()
+        self.horizontalLayout_7.setObjectName(u"horizontalLayout_7")
         self.groupBox = QGroupBox(self.centralwidget)
         self.groupBox.setObjectName(u"groupBox")
         self.groupBox.setMinimumSize(QSize(400, 0))
@@ -81,7 +89,6 @@ class Ui_MainWindow(object):
 
         self.number_propusk = PLineEdit(self.groupBox)
         self.number_propusk.setObjectName(u"number_propusk")
-        self.number_propusk.setMaxLength(32767)
 
         self.horizontalLayout.addWidget(self.number_propusk)
 
@@ -97,7 +104,7 @@ class Ui_MainWindow(object):
         self.date_from = QDateTimeEdit(self.groupBox)
         self.date_from.setObjectName(u"date_from")
         self.date_from.setDateTime(
-            QDateTime(QDate(1999, 12, 31), QTime(21, 0, 0)))
+            QDateTime(QDate(1999, 12, 31), QTime(18, 0, 0)))
         self.date_from.setTimeSpec(Qt.UTC)
 
         self.horizontalLayout_2.addWidget(self.date_from)
@@ -174,39 +181,69 @@ class Ui_MainWindow(object):
 
         self.verticalLayout_3.addLayout(self.verticalLayout_2)
 
-        self.gridLayout.addWidget(self.groupBox, 0, 0, 1, 1)
-
-        self.groupBox_2 = QGroupBox(self.centralwidget)
-        self.groupBox_2.setObjectName(u"groupBox_2")
-        self.verticalLayout_4 = QVBoxLayout(self.groupBox_2)
-        self.verticalLayout_4.setObjectName(u"verticalLayout_4")
-
-        # self.stacked_widget = PStackedWidget(self.groupBox_2, mode)
-        # self.stacked_widget.setObjectName(u'stacked_widget')
-        # self.stacked_widget.setEnabled(True)
-        # self.verticalLayout_4.addWidget(self.stacked_widget)
-
-        self.splitter = QSplitter(self.groupBox_2)
-        self.splitter.setObjectName(u"splitter")
-        self.splitter.setOrientation(Qt.Horizontal)
-        self.btn_start_cam_photo = QPushButton(self.splitter)
-        self.btn_start_cam_photo.setObjectName(u"btn_start_cam_photo")
-        self.splitter.addWidget(self.btn_start_cam_photo)
-        self.capturePhoto = QPushButton(self.splitter)
+        self.horizontalLayout_7.addWidget(self.groupBox)
+
+        self.horizontalLayout_11.addLayout(self.horizontalLayout_7)
+
+        self.verticalLayout_5 = QVBoxLayout()
+        self.verticalLayout_5.setObjectName(u"verticalLayout_5")
+        self.tabWidget = QTabWidget(self.centralwidget)
+        self.tabWidget.setObjectName(u"tabWidget")
+        self.tab = QWidget()
+        self.tab.setObjectName(u"tab")
+
+        self.gridLayout = QGridLayout(self.tab)
+        self.gridLayout.setObjectName(u"gridLayout")
+
+        
+
+        self.tabWidget.addTab(self.tab, "")
+        self.tab_2 = QWidget()
+        self.tab_2.setObjectName(u"tab_2")
+
+        self.gridLayout_2 = QGridLayout(self.tab_2)
+        self.gridLayout_2.setObjectName(u"gridLayout")
+
+        self.stacked_document = PStackedWidget(self.tab_2)
+        self.stacked_document.setObjectName(u'stacked_document')
+        self.gridLayout_2.addWidget(self.stacked_document, 0, 0, 1, 1)
+
+        self.tabWidget.addTab(self.tab_2, "")
+
+        self.verticalLayout_5.addWidget(self.tabWidget)
+
+        self.horizontalLayout_6 = QHBoxLayout()
+        self.horizontalLayout_6.setObjectName(u"horizontalLayout_6")
+        self.btn_start_cam = QPushButton(self.centralwidget)
+        self.btn_start_cam.setObjectName(u"btn_start_cam")
+
+        self.horizontalLayout_6.addWidget(self.btn_start_cam)
+
+        self.capturePhoto = QPushButton(self.centralwidget)
         self.capturePhoto.setObjectName(u"capturePhoto")
-        self.splitter.addWidget(self.capturePhoto)
 
-        self.verticalLayout_4.addWidget(self.splitter)
+        self.horizontalLayout_6.addWidget(self.capturePhoto)
+
+        self.verticalLayout_5.addLayout(self.horizontalLayout_6)
+
+        self.horizontalLayout_11.addLayout(self.verticalLayout_5)
+
+        self.verticalLayout_6.addLayout(self.horizontalLayout_11)
 
-        self.gridLayout.addWidget(self.groupBox_2, 0, 1, 1, 2)
+        self.verticalSpacer = QSpacerItem(
+            20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
 
+        self.verticalLayout_6.addItem(self.verticalSpacer)
+
+        self.horizontalLayout_8 = QHBoxLayout()
+        self.horizontalLayout_8.setObjectName(u"horizontalLayout_8")
         self.btn_clear = QPushButton(self.centralwidget)
         self.btn_clear.setObjectName(u"btn_clear")
         sizePolicy.setHeightForWidth(
             self.btn_clear.sizePolicy().hasHeightForWidth())
         self.btn_clear.setSizePolicy(sizePolicy)
 
-        self.gridLayout.addWidget(self.btn_clear, 1, 0, 1, 1)
+        self.horizontalLayout_8.addWidget(self.btn_clear)
 
         self.btn_save = QPushButton(self.centralwidget)
         self.btn_save.setObjectName(u"btn_save")
@@ -214,7 +251,7 @@ class Ui_MainWindow(object):
             self.btn_save.sizePolicy().hasHeightForWidth())
         self.btn_save.setSizePolicy(sizePolicy)
 
-        self.gridLayout.addWidget(self.btn_save, 1, 1, 1, 1)
+        self.horizontalLayout_8.addWidget(self.btn_save)
 
         self.btn_print = QPushButton(self.centralwidget)
         self.btn_print.setObjectName(u"btn_print")
@@ -222,12 +259,16 @@ class Ui_MainWindow(object):
             self.btn_print.sizePolicy().hasHeightForWidth())
         self.btn_print.setSizePolicy(sizePolicy)
 
-        self.gridLayout.addWidget(self.btn_print, 1, 2, 1, 1)
+        self.horizontalLayout_8.addWidget(self.btn_print)
+
+        self.verticalLayout_6.addLayout(self.horizontalLayout_8)
+
+        self.verticalLayout_9.addLayout(self.verticalLayout_6)
 
         MainWindow.setCentralWidget(self.centralwidget)
         self.menubar = QMenuBar(MainWindow)
         self.menubar.setObjectName(u"menubar")
-        self.menubar.setGeometry(QRect(0, 0, 920, 23))
+        self.menubar.setGeometry(QRect(0, 0, 920, 28))
         self.menubar.setMouseTracking(True)
         self.menubar.setAcceptDrops(True)
         self.menubar.setNativeMenuBar(True)
@@ -248,8 +289,8 @@ class Ui_MainWindow(object):
         self.menubar.addAction(self.menu.menuAction())
         self.menubar.addAction(self.menu_2.menuAction())
         self.menuFile.addSeparator()
-        # self.menuFile.addAction(self.actionSave)
-        # self.menuFile.addAction(self.actionLoad)
+        self.menuFile.addAction(self.actionSave)
+        self.menuFile.addAction(self.actionLoad)
         self.menuFile.addAction(self.btn_show_about)
         self.menuFile.addSeparator()
         self.menuFile.addAction(self.exit)
@@ -265,18 +306,23 @@ class Ui_MainWindow(object):
 
         self.retranslateUi(MainWindow)
 
+        self.tabWidget.setCurrentIndex(0)
+
         QMetaObject.connectSlotsByName(MainWindow)
     # setupUi
 
     def retranslateUi(self, MainWindow):
         MainWindow.setWindowTitle(QCoreApplication.translate(
             "MainWindow", u"\u0412\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u043f\u0443\u0441\u043a", None))
+        
+        # self.number_propusk.__create_id()
+        
         self.actionExit.setText(
             QCoreApplication.translate("MainWindow", u"Exit", None))
-        # self.actionSave.setText(
-        #     QCoreApplication.translate("MainWindow", u"Save", None))
-        # self.actionLoad.setText(
-        #     QCoreApplication.translate("MainWindow", u"Load", None))
+        self.actionSave.setText(
+            QCoreApplication.translate("MainWindow", u"Save", None))
+        self.actionLoad.setText(
+            QCoreApplication.translate("MainWindow", u"Load", None))
         self.actionExit_2.setText(
             QCoreApplication.translate("MainWindow", u"Exit", None))
         self.setting_cam.setText(QCoreApplication.translate(
@@ -309,10 +355,11 @@ class Ui_MainWindow(object):
             "MainWindow", u"\u041f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0438\u0439:", None))
         self.label_7.setText(QCoreApplication.translate(
             "MainWindow", u"\u0426\u0435\u043b\u044c \u0432\u0438\u0437\u0438\u0442\u0430:", None))
-        self.groupBox_2.setTitle(QCoreApplication.translate(
-            "MainWindow", u"\u0424\u043e\u0442\u043e", None))
-
-        self.btn_start_cam_photo.setText(QCoreApplication.translate(
+        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), QCoreApplication.translate(
+            "MainWindow", u"\u041A\u0430\u043C\u0435\u0440\u0430 \u0434\u043B\u044F \u043B\u0438\u0446\u0430", None))
+        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), QCoreApplication.translate(
+            "MainWindow", u"\u041A\u0430\u043C\u0435\u0440\u0430 \u0434\u043B\u044F \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430", None))
+        self.btn_start_cam.setText(QCoreApplication.translate(
             "MainWindow", u"\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043a\u0430\u043c\u0435\u0440\u0443", None))
         self.capturePhoto.setText(QCoreApplication.translate(
             "MainWindow", u"\u0421\u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0440\u043e\u0432\u0430\u0442\u044c", None))
@@ -325,7 +372,7 @@ class Ui_MainWindow(object):
         self.menuFile.setTitle(
             QCoreApplication.translate("MainWindow", u"File", None))
         self.menu.setTitle(QCoreApplication.translate(
-            "MainWindow", u"\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438", None))
+            "MainWindow", u"\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438", None))
         self.menu_3.setTitle(QCoreApplication.translate(
             "MainWindow", u"\u0421\u043f\u0438\u0441\u043a\u0438", None))
         self.menu_2.setTitle(QCoreApplication.translate(