2024-10-09 16:37:54 +03:00
#!/usr/bin/python3
"""
Скрипт с графическим интерфейсом
для печати этикеток на принтере серий brother p - touch ,
на основе https : / / gitea . basealt . ru / polkovnikovaav / ptouch - print - labels
подробности и настройки в README . md
"""
from PySide6 . QtWidgets import QApplication
from PySide6 import QtGui , QtWidgets
from PySide6 . QtWidgets import QMainWindow , QWidget , QLabel , QVBoxLayout , QPushButton , QGridLayout , QLineEdit , QComboBox , QMessageBox
import subprocess
import time
import os
import sys
from PIL import Image , ImageOps , ImageDraw , ImageFont
from barcode import EAN13
from barcode . writer import ImageWriter
# главное окно
class MainWindow ( QMainWindow ) :
def __init__ ( self ) :
super ( ) . __init__ ( )
self . conf = " barcode2-gui.ini "
self . setWindowTitle ( ' Печать стикеров ' )
self . q_button_start = QPushButton ( ' печать ' )
self . q_button_start . clicked . connect ( self . start_print )
self . q_label1 = QLabel ( )
self . q_label2 = QLabel ( )
self . q_label3 = QLabel ( )
self . q_label1 . setText ( " Введите текст: " )
self . q_label2 . setText ( " Введите SN (не вводить - генерация): " )
self . q_label3 . setText ( " Выберите тип устройства: " )
self . q_combo = QComboBox ( self )
self . q_combo . addItem ( " компьютер " )
self . q_combo . addItem ( " монитор " )
self . q_combo . addItem ( " сетевое о б . " )
self . q_combo . addItem ( " токен " )
self . q_combo . addItem ( " принтер/МФУ " )
self . q_combo . addItem ( " флешка " )
self . q_combo . addItem ( " HID " )
self . q_combo . addItem ( " UPS " )
self . q_combo . addItem ( " другое " )
self . q_button_start = QPushButton ( " печать " )
self . q_button_start . setMinimumSize ( 20 , 80 )
self . q_button_start . clicked . connect ( self . start_print )
self . grid_layout = QGridLayout ( )
self . layout1 = QVBoxLayout ( )
self . q_edit1 = QLineEdit ( ) # текст (над ШК)
self . q_edit2 = QLineEdit ( ) # вводимый свой серийник (если не нужна генерациия)
self . q_edit3 = QLineEdit ( ) # выводимый SN для справки
self . q_edit3 . setReadOnly ( True )
self . layout1 . addWidget ( self . q_label1 )
self . layout1 . addWidget ( self . q_edit1 )
self . layout1 . addWidget ( self . q_label2 )
self . layout1 . addWidget ( self . q_edit2 )
self . layout1 . addWidget ( self . q_label3 )
self . layout1 . addWidget ( self . q_combo )
self . layout1 . addWidget ( self . q_button_start )
self . layout1 . addWidget ( self . q_edit3 )
self . grid_layout . setRowStretch ( 5 , 0 )
self . grid_layout . setRowStretch ( 20 , 1 )
self . grid_layout . setRowStretch ( 1 , 2 )
self . grid_layout . setRowStretch ( 1 , 3 )
self . grid_layout . setRowStretch ( 1 , 4 )
self . grid_layout . setRowStretch ( 100 , 5 )
self . grid_layout . setRowStretch ( 1 , 6 )
self . grid_layout . addWidget ( self . q_label1 , 0 , 0 )
self . grid_layout . addWidget ( self . q_edit1 , 1 , 0 )
self . grid_layout . addWidget ( self . q_label2 , 2 , 0 )
self . grid_layout . addWidget ( self . q_edit2 , 3 , 0 )
self . grid_layout . addWidget ( self . q_label3 , 4 , 0 )
self . grid_layout . addWidget ( self . q_combo , 5 , 0 )
self . grid_layout . addWidget ( self . q_button_start , 6 , 0 )
self . grid_layout . addWidget ( self . q_edit3 , 7 , 0 ) # шк-код текстом
self . content_widget = QWidget ( )
self . content_widget . setLayout ( self . grid_layout )
self . setCentralWidget ( self . content_widget )
# выпадающий список типов и кодовые соответствия
self . combo_type_items = {
" компьютер " : " 21 " ,
" монитор " : " 22 " ,
" сетевое о б . " : " 23 " ,
" токен " : " 24 " ,
" принтер/МФУ " : " 25 " ,
" флешка " : " 26 " ,
" HID " : " 27 " ,
" UPS " : " 28 " ,
" другое " : " 29 " ,
}
# получаем текущий каталог и переходим в него
def set_current_location ( self ) :
path_there = os . path . dirname ( os . path . realpath ( __file__ ) )
os . chdir ( path_there )
# генерация штрих-кода с контрльной суммой
def gen_ean13 ( self , product_code : str ) :
# добавляем псевдослучаное значение (от времени к коду продукта)
digits_s = product_code + str ( round ( time . time ( ) ) )
# строка продукта в список чисел
digits = [ int ( i ) for i in digits_s ]
# контрольная сумма по алгоритму ЛУна
checksum = ( 10 - ( sum ( digits [ 1 : : 2 ] ) * 3 + sum ( digits [ : : 2 ] ) ) % 10 ) % 10
return " " . join ( str ( i ) for i in ( digits + [ checksum ] ) )
# генерация картинки
def create_code_png ( self , filename , code , text ) :
self . set_current_location ( )
ean13_code = EAN13 ( code , writer = ImageWriter ( ) )
image = ean13_code . render (
writer_options = {
" module_height " : 11.0 ,
" module_width " : 0.3 ,
" dpi " : 169 ,
" font_size " : 0 ,
" text_distance " : 1 ,
" write_text " : None ,
}
)
image = image . convert ( " 1 " , dither = Image . Dither . NONE )
image = ImageOps . expand ( image , border = 17 , fill = 1 )
draw = ImageDraw . Draw ( image )
# загружаем шрифт
dst = " terminus.pil "
font = ImageFont . load ( dst )
text_length = draw . textlength ( text , font = font )
code_text_length = draw . textlength ( code , font = font )
draw . text ( ( ( image . width - text_length ) / 2 , 3 ) , text , fill = " black " , font = font )
draw . text (
( ( image . width - code_text_length ) / 2 , 100 ) ,
code ,
fill = " black " ,
font = font ,
)
image . save ( filename )
#запуск всего процесса (генерация и печать)
def start_print ( self ) :
# берем ID по типу оборудования
type_device = self . combo_type_items [ self . q_combo . currentText ( ) ]
# берем текст подписи
text_data = self . q_edit1 . text ( )
barcode = self . gen_ean13 ( type_device )
# если ввели свой SN, передаем е г о в создание ШК
if len ( self . q_edit2 . text ( ) ) > 0 :
if len ( self . q_edit2 . text ( ) ) == 12 :
barcode = self . q_edit2 . text ( )
else :
msg = QMessageBox ( )
msg . setWindowTitle ( " Внимание " )
msg . setText ( " Должно быть 12 знаков " )
msg . setIcon ( QMessageBox . Warning )
msg . exec_ ( )
exit ( 0 )
2024-10-10 12:45:01 +03:00
self . q_edit3 . setText ( barcode )
2024-10-09 16:37:54 +03:00
self . create_code_png ( " temp.png " , barcode , text_data )
self . start_process ( )
2024-10-10 12:45:01 +03:00
2024-10-09 16:37:54 +03:00
2024-10-10 12:45:01 +03:00
# запуск утилиты печати сфомированного изображения
def start_process ( self ) :
subprocess . run ( [ " ptouch-print " , " --image " , " temp.png " ] )
2024-10-09 16:37:54 +03:00
if __name__ == ' __main__ ' :
app = QApplication ( sys . argv )
configparser = ChildProcessError
# таблица стилей (задаем размер шрифта)
style_sheet01 = """
* {
font - size : 11 pt ;
}
"""
# Применение таблицы стилей (размер шрифта) ко всему приложению
app . setStyleSheet ( style_sheet01 )
window = MainWindow ( )
# Установить размер окна
window . resize ( 500 , 300 )
# Получить допустимое разрешение
SrcSize = QtGui . QScreen . availableGeometry ( QApplication . primaryScreen ( ) )
frmX = ( SrcSize . width ( ) - window . width ( ) ) / 2
frmY = ( SrcSize . height ( ) - window . height ( ) ) / 2
window . move ( frmX , frmY )
window . show ( )
sys . exit ( app . exec_ ( ) )