import sys
import time
from PySide2.QtCore import QThread, QThreadPool, QRunnable, Signal
from PySide2.QtWidgets import QApplication, QMainWindow, QGridLayout, QPushButton, QWidget, QSpacerItem, QSizePolicy, \
QHBoxLayout
class Main(QMainWindow):
def __init__(self):
super(Main, self).__init__()
centralWidget = QWidget(self)
self.setCentralWidget(centralWidget)
# добавляем компоновщик
self.h_grid = QHBoxLayout(centralWidget)
self.thread = QThreadPool().globalInstance()
# добавляем кнопки
self.button = QPushButton('Start thread')
self.h_grid.addWidget(self.button)
self.button.clicked.connect(self.thread.start(Worker()))
class Worker(QRunnable):
def __init__(self):
super(Worker, self).__init__()
def run(self):
print(f'Start Worker')
time_to_sleep = 10
print(f'Worker slept for {time_to_sleep} seconds')
time.sleep(time_to_sleep)
print(f'Worker awakening')
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Main()
ex.show()
sys.exit(app.exec_())
# где-то в основном коде
self.thread_pool = QThreadPool().globalInstance()
self.thread_pool.start(Worker())
class Worker(QRunnable):
def __init__(self):
super(Worker, self).__init__()
def run(self):
# код, который будет запускаться в отдельном потоке
print('start')
time.sleep(10)
print('stop')
class StrangeFinder:
result_list_part_count = 0
result_list_part_length = 0
result_splitted_list = None
def get_list_part_count(self, lst: list, min_len_of_part):
# ищем наименьшее количество частей списка
ln = len(lst)
while True:
if ln % min_len_of_part != 0:
min_len_of_part += 1
else:
break
StrangeFinder.result_list_part_length = min_len_of_part
return min_len_of_part
def find_max_item_val_in_dict(self, dc: dict):
# ищем максимальное значение элемента словаря
# предполагаем, что отрицательных чисел в наших списках не будет
max_val = -1
result_item = None
for key in dc:
if dc[key] > max_val:
max_val = dc[key]
result_item = key
return result_item
def split_list_to_parts(self, lst, len_of_part):
# делим список на части, заданные в параметре part_count
list_parts_count = int(len(lst) / len_of_part) # количество частей списка
StrangeFinder.result_list_part_count = list_parts_count
y = [] # результирующий список
for multiplier in range(1, list_parts_count + 1):
# заполняем наш список срезами исходного
y.append(lst[(len_of_part * multiplier) - len_of_part:len_of_part * multiplier])
StrangeFinder.result_splitted_list = y
return y
def find_periodic_seq(self, seq, min_len_of_part):
# получаем наш разделенный список
splitted_list = self.split_list_to_parts(seq, self.get_list_part_count(seq, min_len_of_part))
# тут будут храниться наши последовательности
counters = []
# нужно больше циклов!!!
# пробегаем по нашему расщепенцу
for sub_list in splitted_list:
dc = {}
for element in sub_list:
# заполняем словарь dc данными, сколько раз каждый элемент встречается в последовательности
# count намеренно не использовал
try:
dc[element] += 1
except KeyError:
dc[element] = 1
# находим элемент, который максимально часто встречается в последовательности
max_item = self.find_max_item_val_in_dict(dc)
lst = []
# собираем индексы, на которых находятся наши элементы и запихиваем в список lst
for pos, element in enumerate(sub_list):
if element == max_item:
lst.append(pos)
# список со списками индексов максимально часто повторяющихся элементов, предварительно разбитого списка!
counters.append(lst)
# если длина списка == количеству повторений первого элемента -> наш список содержит одинаковые элементы
if len(counters) == counters.count(counters[0]):
return counters[0]
else:
return None
if __name__ == '__main__':
# не улетаем в небеса и ограничиваем бесконечный цикл
stop_cycles = 10
current_cycles = 1
# исходный список
lst = [0, 1, 1, 2, 0, 3, 4, 4, 5, 3]
# минимальное количество элементов в каждой части при дроблении списка на части
min_len_of_part = 3
while True:
if current_cycles > stop_cycles:
print(f'Can not find sequence with {current_cycles} cycles, stopping :(')
break
# вызываем нашу основную функцию
result = StrangeFinder().find_periodic_seq(lst, min_len_of_part)
if not result:
# если ничего не нашлось - увеличиваем минимальную длину части на 1
min_len_of_part += 1
else:
print(f'Исходная последовательность: {lst}')
print(f'Разделенная на части : {StrangeFinder.result_splitted_list}')
print(f'Количество частей : {StrangeFinder.result_list_part_count}')
print(f'Длина каждой части : {StrangeFinder.result_list_part_length}')
print(f'Индексы элементов : {result}')
break
[0, 1, 1, 2, 1, 3, 4, 4, 5, 4, 5, 6, 6, 3, 6], сделаем опять проверку, на этот раз делится на три то есть [0,1,1] [2,1,3] [4,4,5][4,5,6][6,3,6], не на три, а по три
import sys
import PySide2
from PySide2 import QtCore
from PySide2.QtCore import Signal
from PySide2.QtWidgets import QApplication, QTableWidget, QTableWidgetItem, QStyledItemDelegate, QLineEdit
class Main(QTableWidget):
def __init__(self):
super(Main, self).__init__(5, 5)
# создаем простую таблицу и заполняем ее данными
for row_num in range(self.rowCount()):
for col_num in range(self.columnCount()):
item = QTableWidgetItem()
item.setText(f'pos {row_num + 1} {col_num + 1}')
self.setItem(row_num, col_num, item)
# создаем делегата
self.delegate = ItemDelegate(self)
# коннектимся к нашим сигналам
self.delegate.cellEditingStarted.connect(self._on_cell_edit_starts)
self.delegate.cellEditingFinished.connect(self._on_cell_edit_finished)
self.delegate.editorTextEdited.connect(self._on_text_edited)
# устанавливаем делегата для нашей модели
self.setItemDelegate(self.delegate)
def _on_cell_edit_starts(self, *args):
print(f'_on_cell_edit_starts, args = {args}')
def _on_cell_edit_finished(self, *args):
print(f'_on_cell_edit_ends, args = {args}')
def _on_text_edited(self, new_text):
print(f'_on_cell_edit_ends, new_text = {new_text}')
class ItemDelegate(QStyledItemDelegate):
cellEditingStarted = Signal(int, int) # создание редактора для строки, начало редактирования, аргументы - row, column
cellEditingFinished = Signal(int, int) # завершение редактирования, аргументы - row, column
editorTextEdited = Signal(str) # ретраннсляция сигнала от QLineEdit, аргумент -
# переопределение метода QStyledItemDelegate.createEditor
# вызывается при необходимости редактирования, создает редактор
def createEditor(self, parent: PySide2.QtWidgets.QWidget, option: PySide2.QtWidgets.QStyleOptionViewItem,
index: PySide2.QtCore.QModelIndex) -> PySide2.QtWidgets.QWidget:
# результат работы метода createEditor - виджет, в котором проходит редактирования, про них читать в доках
result = super(ItemDelegate, self).createEditor(parent, option, index)
if result:
self.cellEditingStarted.emit(index.row(), index.column()) # шлем сигнал
if type(result) == QLineEdit: # обработка только QLineEdit
# коннектим сигнал от QLineEdit и отправку editorTextEdited
result.textEdited.connect(self.editorTextEdited.emit)
return result
# уничтожает редактор
def destroyEditor(self, editor: PySide2.QtWidgets.QWidget, index: PySide2.QtCore.QModelIndex):
self.cellEditingFinished.emit(index.row(), index.column()) # шлем сигнал о завершении редактирования
if type(editor) == QLineEdit:
editor.textEdited.disconnect() # отключаем сигнал от QLineEdit, т.к. он будет уничтожен
super(ItemDelegate, self).destroyEditor(editor, index) # метод родителя уничтожает редактор
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Main()
ex.show()
sys.exit(app.exec_())