class OffsetRow(QWidget): def __init__(self): super(OffsetRow, self).__init__() self.layout = QHBoxLayout() self.layout.setContentsMargins(0,0,0,0) self.sign = QComboBox() self.sign.addItems(['-', '+']) self.amount = QLineEdit() self.amount.setInputMask('99999999') self.unit = QComboBox() self.unit.addItems(['sec', 'min', 'hrs', 'day']) self.layout.addWidget(self.sign) self.layout.addWidget(self.amount, stretch = 1) self.layout.addWidget(self.unit) def show(self): self.sign.show() self.amount.show() self.unit.show() def hide(self): self.sign.hide() self.amount.hide() self.unit.hide() def set_values(self, sign, amount, unit): self.sign.setCurrentText(sign) self.amount.setText(str(amount)) self.unit.setCurrentText(unit)
def __addSinglesLine(self): """ Private slot to add a line of entry widgets for single characters. """ hbox = QWidget(self.singlesItemsBox) hboxLayout = QHBoxLayout(hbox) hboxLayout.setContentsMargins(0, 0, 0, 0) hboxLayout.setSpacing(6) hbox.setLayout(hboxLayout) cb1 = QComboBox(hbox) cb1.setEditable(False) self.__populateCharTypeCombo(cb1, True) hboxLayout.addWidget(cb1) le1 = QLineEdit(hbox) le1.setValidator(self.charValidator) hboxLayout.addWidget(le1) cb1a = QComboBox(hbox) cb1a.setEditable(False) cb1a.setSizeAdjustPolicy(QComboBox.AdjustToContents) hboxLayout.addWidget(cb1a) cb1a.hide() cb2 = QComboBox(hbox) cb2.setEditable(False) self.__populateCharTypeCombo(cb2, True) hboxLayout.addWidget(cb2) le2 = QLineEdit(hbox) le2.setValidator(self.charValidator) hboxLayout.addWidget(le2) cb2a = QComboBox(hbox) cb2a.setEditable(False) cb2a.setSizeAdjustPolicy(QComboBox.AdjustToContents) hboxLayout.addWidget(cb2a) cb2a.hide() self.singlesItemsBoxLayout.addWidget(hbox) cb1.activated[int].connect(self.__singlesCharTypeSelected) cb2.activated[int].connect(self.__singlesCharTypeSelected) hbox.show() self.singlesItemsBox.adjustSize() self.singlesEntries.append([cb1, le1, cb1a]) self.singlesEntries.append([cb2, le2, cb2a])
class LabelComboBox(QWidget): def __init__(self, label='', items = {'UJ object reference value': 'Name to show'}): super(LabelComboBox, self).__init__() self.label = QLabel() self.label.setText(label) self.items = items self.combo_box = QComboBox() self.combo_box.insertItems(0, self.items.values()) self.layout = QHBoxLayout() self.layout.setContentsMargins(0,0,0,0) self.layout.addWidget(self.label) self.layout.addWidget(self.combo_box, stretch = 1) def reset_items(self, items = {'UJ object reference value': 'Name to show'}): while self.combo_box.count() != 0: self.combo_box.removeItem(0) self.items = items self.combo_box.addItems(self.items.values()) def show(self): self.combo_box.show() self.label.show() def hide(self): self.combo_box.hide() self.label.hide() def set_text(self, text): if text in self.items.values(): self.combo_box.setCurrentText(text) if text in self.items.keys(): self.combo_box.setCurrentText(self.items[text]) def text(self): return self.combo_box.currentText()
class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.okButton = QPushButton("查询") self.cancelButton = QPushButton("退出") hbox = QHBoxLayout() # 水平布局 hbox.addStretch(1) # 伸展因子 hbox.addWidget(self.okButton) # 添加按钮 hbox.addWidget(self.cancelButton) # 添加按钮 vbox = QVBoxLayout() # 垂直布局 vbox.addStretch(1) vbox.addLayout(hbox) self.cancelButton.clicked.connect(QCoreApplication.instance().quit) self.setLayout(vbox) self.lbl1 = QLabel("起始地", self) self.lbl1.resize(self.lbl1.sizeHint()) self.lbl1.move(50, 20) self.lbl2 = QLabel("目的地", self) self.lbl2.resize(self.lbl1.sizeHint()) self.lbl2.move(300, 20) self.textbox1 = QLineEdit(self) self.textbox1.move(50, 40) self.textbox1.resize(self.textbox1.sizeHint()) self.textbox2 = QLineEdit(self) self.textbox2.move(300, 40) self.textbox2.resize(self.textbox2.sizeHint()) self.okButton.clicked.connect(self.search) # self.cancelButton.clicked.connect(self.cancel) self.combobox = QComboBox(self) self.combobox.move(50, 400) self.combobox.addItem("出发最早") self.combobox.addItems(["出发最晚", "时长最短"]) self.combobox.hide() self.setGeometry(300, 300, 1000, 500) self.setWindowTitle('高铁动车查询') self.center() self.show() def center(self): qr = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft()) def closeEvent(self, event): reply = QMessageBox.question(self, "Message", "Are you sure to exit", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: event.accept() else: event.ignore() self.conn.close() def search(self): # print(1) start = self.textbox1.text() stop = self.textbox2.text() print("正在搜索") print(start) print(stop) import json with conn.cursor() as cursor: with open("G:\软件工程课程设计\全国高铁信息\高铁车站出发信息.json", "r", encoding="utf-8") as jf: results = json.load(jf) stations = list(results.keys()) # print(stations) if start in stations: sql = search_table_station.replace("example", start) cursor.execute(sql) results = cursor.fetchall() train_list = [] for trains in results: # print(trains) if stop in trains: train_list.append(trains[0]) if len(train_list) == 0: # print("没有从" + start + "到" + stop + "的高铁动车") self.stop_no_train(start, stop) # pass # for station_train in trains: # print(station_train) # if stop in station_train: # train_list.append(trains[0]) travels = [] for train in train_list: sql = search_table_train.replace("example", train) cursor.execute(sql) results = cursor.fetchall() travel = {} for train_station in results: if start in train_station: train_id = train_station[1] start_station = train_station[2] start_time = train_station[4] if stop in train_station: arrival_time = train_station[3] time_start = start_time.split(":") time_arrival = arrival_time.split(":") # print(time_start) # print(time_arrival) time_total = [] if int(time_start[0]) <= int( time_arrival[0]) and int( time_start[1]) < int( time_arrival[1]): time_total.append( int(time_arrival[0]) - int(time_start[0])) time_total.append( int(time_arrival[1]) - int(time_start[1])) if int(time_start[0]) <= int( time_arrival[0]) and int( time_start[1]) > int( time_arrival[1]): time_total.append( int(time_arrival[0]) - int(time_start[0]) - 1) time_total.append( int(time_arrival[1]) - int(time_start[1]) + 60) if int(time_start[0]) > int( time_arrival[0]) and int( time_start[1]) < int( time_arrival[1]): time_total.append( int(time_arrival[0]) - int(time_start[0]) + 24) time_total.append( int(time_arrival[1]) - int(time_start[1])) if int(time_start[0]) > int( time_arrival[0]) and int( time_start[1]) > int( time_arrival[1]): time_total.append( int(time_arrival[0]) - int(time_start[0]) + 24 - 1) time_total.append( int(time_arrival[1]) - int(time_start[1]) + 60) else: pass total_time = "{}:{}".format( time_total[0], time_total[1]) travel = { "train_id": train_id, "start_station": start_station, "start_time": start_time, "arrival_time": arrival_time, "stop": stop, "total_time": total_time } travels.append(travel) self.show_trains(travels) else: self.station_no_train(start) def show_trains(self, travels): self.tableWidget = QTableWidget(self) # 创建一个表格 self.tableWidget.setEditTriggers(QTableWidget.NoEditTriggers) self.tableWidget.move(50, 100) self.tableWidget.resize(700, 250) self.tableWidget.setRowCount(len(travels)) self.tableWidget.setColumnCount(6) self.tableWidget.setHorizontalHeaderLabels( ['列车', '出发站', '出发时间', '到达时间', '到达站', '总时长']) if self.combobox.currentText() == "出发最早": start_times = [] for travel in travels: start_time = travel["start_time"].split(":") start_time = int(start_time[0] + start_time[1]) start_times.append(start_time) time_time = dict(zip(range(len(travels)), start_times)) # start_times = list(time_time.values()) # start_times.sort() results = sorted(time_time.items(), key=lambda item: item[1], reverse=False) sort_time = [] for result in results: sort_time.append(result[0]) for result in results: list = [] list.append(travels[result[0]]["train_id"]) list.append(travels[result[0]]["start_station"]) list.append(travels[result[0]]["start_time"]) list.append(travels[result[0]]["arrival_time"]) list.append(travels[result[0]]["stop"]) list.append(travels[result[0]]["total_time"]) for info in list: self.tableWidget.setItem(sort_time.index(result[0]), list.index(info), QTableWidgetItem(info)) elif self.combobox.currentText() == "出发最晚": start_times = [] for travel in travels: start_time = travel["start_time"].split(":") start_time = int(start_time[0] + start_time[1]) start_times.append(start_time) time_time = dict(zip(range(len(travels)), start_times)) results = sorted(time_time.items(), key=lambda item: item[1], reverse=True) sort_time = [] for result in results: sort_time.append(result[0]) for result in results: list = [] list.append(travels[result[0]]["train_id"]) list.append(travels[result[0]]["start_station"]) list.append(travels[result[0]]["start_time"]) list.append(travels[result[0]]["arrival_time"]) list.append(travels[result[0]]["stop"]) list.append(travels[result[0]]["total_time"]) for info in list: self.tableWidget.setItem(sort_time.index(result[0]), list.index(info), QTableWidgetItem(info)) elif self.combobox.currentText() == "时长最短": start_times = [] for travel in travels: start_time = travel["total_time"].split(":") start_time = int(start_time[0] + start_time[1]) start_times.append(start_time) time_time = dict(zip(range(len(travels)), start_times)) results = sorted(time_time.items(), key=lambda item: item[1], reverse=False) sort_time = [] for result in results: sort_time.append(result[0]) for result in results: list = [] list.append(travels[result[0]]["train_id"]) list.append(travels[result[0]]["start_station"]) list.append(travels[result[0]]["start_time"]) list.append(travels[result[0]]["arrival_time"]) list.append(travels[result[0]]["stop"]) list.append(travels[result[0]]["total_time"]) for info in list: self.tableWidget.setItem(sort_time.index(result[0]), list.index(info), QTableWidgetItem(info)) self.combobox.show() self.tableWidget.show() def choose_soft(self, combobox_current_index, travels): print("已经被调用") print(combobox_current_index) if combobox_current_index == 0: start_times = [] for travel in travels: start_time = travel["start_time"].split(":") start_time = int(start_time[0] + start_time[1]) start_times.append(start_time) time_time = dict(zip(range(len(travels)), start_times)) results = sorted(time_time.items(), key=lambda item: item[1]) sort_time = [] for result in results: sort_time.append(result[0]) for result in results: list = [] list.append(travels[result[0]]["train_id"]) list.append(travels[result[0]]["start_station"]) list.append(travels[result[0]]["start_time"]) list.append(travels[result[0]]["arrival_time"]) list.append(travels[result[0]]["stop"]) for info in list: self.tableWidget.setItem(sort_time.index(result[0]), list.index(info), QTableWidgetItem(info)) self.tableWidget.show() def cancel(self): self.show() def station_no_train(self, start): self.tableWidget.hide() # if self.tableWidget: # self.tableWidget.hide() self.lable = QLabel(start + "车站无高铁经过", self) self.lable.move(50, 100) self.lable.resize(self.lable.sizeHint()) self.lable.show() def stop_no_train(self, start, stop): self.tableWidget.hide() self.lable = QLabel("没有从" + start + "到" + stop + "的高铁动车", self) self.lable.move(50, 100) self.lable.show()
from PyQt5.QtWidgets import QWidget, QPushButton, QLabel, QComboBox, QLineEdit, QTableWidget, QTableWidgetItem, \
class Example(QMainWindow): def __init__(self): super(Example, self).__init__() self.tmr = QTimer() self.tmr.timeout.connect(self.on_timer) self.alarm_class = Alarm(0, 0) self.status = False self.h_m_list = [None, None] self.color_frame = (0, 0, 0) self.old_pos = None self.text = ['00', '00'] self.initUI() def initUI(self): # Генерация окна self.setWindowTitle('Clock') self.setGeometry(100, 100, 260, 160) self.setWindowFlags(Qt.FramelessWindowHint) self.setObjectName('MainWidget') self.setStyleSheet("#MainWidget {background-color: #272727;}") # Кнопка закрытие окна self.btn_close = QPushButton(self, clicked=self.close) self.btn_close.setIcon(QtGui.QIcon(QtGui.QPixmap('pngs/cross.png'))) self.btn_close.setFlat(True) self.btn_close.resize(17, 17) self.btn_close.move(242, 1) self.btn_close.show() # Кнопка возрата в general self.btn_gn = QPushButton(self, clicked=self.general) self.btn_gn.setIcon(QtGui.QIcon(QtGui.QPixmap('pngs/back.png'))) self.btn_gn.setFlat(True) self.btn_gn.resize(20, 20) self.btn_gn.move(1, 1) self.btn_gn.show() # Кнопка входа в settings self.btn_st = QPushButton(self, clicked=self.settings) self.btn_st.setIcon(QtGui.QIcon(QtGui.QPixmap("pngs/gear.png"))) self.btn_st.setFlat(True) self.btn_st.resize(15, 15) self.btn_st.move(3, 3) self.btn_st.show() # Кнопка будильника self.alarmB = QPushButton(self, clicked=self.alarm_st) self.alarmB.setIcon(QtGui.QIcon(QtGui.QPixmap("pngs/alarmN.png"))) self.alarmB.setFlat(True) self.alarmB.resize(25, 25) self.alarmB.move(204, 39) self.alarmB.show() # Кнопка включения будильника self.alVKL = QPushButton('Включить', self, clicked=self.alarm_status) self.alVKL.resize(65, 20) self.alVKL.setObjectName('a') self.alVKL.setStyleSheet( "#a {background-color: white; border-radius: 2px;}") self.alVKL.move(98, 110) # Синхронизация системного времени self.sinT = QPushButton('Синхронизация\nсистемного\nвремени', self, clicked=set_server_time) self.sinT.resize(90, 50) self.sinT.move(120, 28) # Дисплей для будильника self.lcdA = QLCDNumber(self) self.lcdA.resize(150, 75) self.lcdA.move(55, 30) self.lcdA.setSegmentStyle(QLCDNumber.Flat) self.lcdA.setObjectName("LCDA") self.lcdA.setStyleSheet( "#LCDA {background-image: url(pngs/фон.png); border: 2px solid #4c4c4c;}" ) self.lcdA.display(':'.join(self.text)) # Слайдер выбора часа self.sldH = QSlider(Qt.Vertical, self) self.sldH.setMaximum(23) self.sldH.move(46, 30) self.sldH.resize(9, 75) self.sldH.valueChanged.connect(self.slider) # Слайдер выбора минут self.sldM = QSlider(Qt.Vertical, self) self.sldM.setMaximum(59) self.sldM.move(206, 30) self.sldM.resize(9, 75) self.sldM.valueChanged.connect(self.slider2) # Дисплей часов self.lcd = QLCDNumber(self) self.lcd.resize(150, 75) self.lcd.setSegmentStyle(QLCDNumber.Flat) self.lcd.move(55, 40) self.lcd.display(make_time_for_lcd()) self.lcd.setObjectName("LCD") self.lcd.setStyleSheet( "#LCD {background-image: url(pngs/фон.png); border: 2px solid #4c4c4c;}" ) # Комбобокс для стилизации self.combo = QComboBox(self) self.combo.setStyleSheet('border-radius: 3px, 3px, 2px, 1px;') self.combo.resize(75, 20) self.combo.addItems([ "Stylization", "Color", "Olds", "Matrix", "Sofa", "Low Poly", "Anime", "Pony", "Савок" ]) self.combo.activated[str].connect(self.onActivated) self.combo.move(30, 30) # Кнопка отключения будильника self.gm = QPushButton('ОТКЛЮЧИТЬ\nБУДИЛЬНИК', self, clicked=self.play_stop) self.gm.setObjectName('x') self.gm.setStyleSheet("#x {background-color: rgb(0, 255, 0);}") self.gm.resize(90, 50) self.gm.move(85, 55) self.general() # Сцена часов def general(self): try: self.btn_st.show() self.btn_gn.hide() self.combo.hide() self.alarmB.show() self.lcd.show() self.sldH.hide() self.sldM.hide() self.lcdA.hide() self.alVKL.hide() self.sinT.hide() self.gm.hide() except AttributeError: pass # Сцена настроек def settings(self): self.btn_gn.show() self.btn_st.hide() self.combo.show() self.alarmB.hide() self.lcd.hide() self.sldH.hide() self.sldM.hide() self.lcdA.hide() self.alVKL.hide() self.sinT.show() self.gm.hide() def alarm_st(self): self.btn_gn.show() self.btn_st.hide() self.alarmB.hide() self.lcd.hide() self.sldH.show() self.sldM.show() self.sldH.setValue(get_local_time()['hours']) self.sldM.setValue(get_local_time()['minutes']) self.lcdA.show() self.alVKL.show() self.sinT.hide() def good_morning(self): self.gm.show() self.btn_gn.hide() self.btn_st.hide() self.alarmB.hide() self.lcd.hide() self.sldH.hide() self.sldM.hide() self.lcdA.hide() self.alVKL.hide() self.sinT.hide() def play_stop(self): self.alarm_class.stop_sound() self.alarm_status() self.general() # Изменение фона окна def palette(self): color = QColorDialog.getColor() if color.isValid(): self.setStyleSheet("#MainWidget {background-color: %s;}" % color.name()) self.paintEvent(self, clr=self.hex_to_rgb(color.name())) # рисование окна def paintEvent(self, event: QtGui.QPaintEvent, clr=(0, 0, 0)): painter = QtGui.QPainter(self) painter.setPen( QtGui.QPen( QtGui.QColor(int(fabs(clr[0] - 75)), int(fabs(clr[1] - 75)), int(fabs(clr[2] - 75))), 2)) painter.drawRect(self.rect()) # нужна для перемещёния окна def mousePressEvent(self, event): if event.button() == Qt.LeftButton: self.old_pos = event.pos() # вызывается всякий раз, когда мышь перемещается def mouseMoveEvent(self, event): if not self.old_pos: return delta = event.pos() - self.old_pos self.move(self.pos() + delta) # перевод их hex в rgb def hex_to_rgb(self, value): value = value.lstrip('#') lv = len(value) return tuple( int(value[i:i + lv // 3], 16) for i in range(0, lv, lv // 3)) def onActivated(self, val): backgrounds = { 'Stylization': '#272727', 'Olds': 'pngs/olds.png', 'Matrix': 'pngs/matrix.png', 'Sofa': 'pngs/диван.jpg', 'Low Poly': 'pngs/bg.png', "Anime": 'pngs/anime.jpg', "Pony": 'pngs/pony.jpg', "Савок": 'pngs/фоник.png' } if val == 'Color': self.palette() elif val == 'Stylization': self.setStyleSheet("#MainWidget {background-color: #272727;}") elif val != 'Color': self.setStyleSheet("#MainWidget {background-image: url(%s);}" % backgrounds[val]) self.paintEvent(self) def slider(self, n): self.h_m_list[0] = n if len(str(n)) == 1: n = '0' + str(n) self.text[0] = str(n) self.lcdA.display(':'.join(self.text)) def slider2(self, n): self.h_m_list[1] = n if len(str(n)) == 1: n = '0' + str(n) self.text[1] = str(n) self.lcdA.display(':'.join(self.text)) def on_timer(self): """ timer handler """ self.lcd.display(make_time_for_lcd()) if self.status: t = get_local_time() if t['hours'] == self.h_m_list[0] and t[ 'minutes'] == self.h_m_list[1]: self.alarm_class.start_sound() self.good_morning() def alarm_status(self): if not self.status: self.status = True self.alarmB.setIcon(QtGui.QIcon(QtGui.QPixmap("pngs/alarmA.png"))) self.alVKL.setText('Выключить') self.alarm_class.set(self.h_m_list[0], self.h_m_list[1]) elif self.status: self.status = False self.alarmB.setIcon(QtGui.QIcon(QtGui.QPixmap("pngs/alarmN.png"))) self.alVKL.setText('Включить') self.alarm_class.tracked = self.status
class ActionBar(QFrame): """ SIGNALS: @changeCurrent(PyQt_PyObject) @runFile(QString) @reopenTab(QString) @recentTabsModified() """ changeCurrent = pyqtSignal('QObject*', int) runFile = pyqtSignal(str) reopenTab = pyqtSignal(str) recentTabsModified = pyqtSignal() closeFile = pyqtSignal()# closeSplit editorSplited = pyqtSignal(bool)# splitEditor, hasSplitEditor addToProject = pyqtSignal(str) showFileInExplorer = pyqtSignal(str) goToSymbol = pyqtSignal(int) dockWidget = pyqtSignal("QObject*") undockWidget = pyqtSignal() undockEditor = pyqtSignal() class ORIENTATION: Horizontal = 0 Vertical = 1 Q_ENUMS(ORIENTATION) def __init__(self, main_combo=False): super(ActionBar, self).__init__() self.setObjectName("actionbar") hbox = QHBoxLayout(self) hbox.setContentsMargins(1, 1, 1, 1) hbox.setSpacing(1) self.lbl_checks = QLabel('') self.lbl_checks.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.lbl_checks.setFixedWidth(48) self.lbl_checks.setVisible(False) hbox.addWidget(self.lbl_checks) self.combo = ComboFiles()#self) self.combo.setIconSize(QSize(16, 16)) #model = QStandardItemModel() #self.combo.setModel(model) #self.combo.view().setDragDropMode(QAbstractItemView.InternalMove) self.combo.setMaximumWidth(300) self.combo.setObjectName("combotab") self.combo.currentIndexChanged[int].connect(self.current_changed) self.combo.setToolTip(translations.TR_COMBO_FILE_TOOLTIP) self.combo.setContextMenuPolicy(Qt.CustomContextMenu) self.combo.customContextMenuRequested['const QPoint &'].connect(self._context_menu_requested) hbox.addWidget(self.combo) #QTimer.singleShot(50000, lambda: print("singleShot", self.combo.showPopup())) self.symbols_combo = QComboBox() self.symbols_combo.setIconSize(QSize(16, 16)) self.symbols_combo.setObjectName("combo_symbols") self.symbols_combo.activated[int].connect(self.current_symbol_changed) hbox.addWidget(self.symbols_combo) self.code_navigator = CodeNavigator() hbox.addWidget(self.code_navigator) self._pos_text = "Line: %d, Col: %d" # self.lbl_position = QLabel(self._pos_text % (0, 0)) # self.lbl_position.setObjectName("position") # self.lbl_position.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) # hbox.addWidget(self.lbl_position) # hbox.addSpacerItem(QSpacerItem(10,10, QSizePolicy.Expanding)) hbox.addSpacing(100) self.btn_close = QPushButton( self.style().standardIcon(QStyle.SP_DialogCloseButton), '') self.btn_close.setIconSize(QSize(16, 16)) if main_combo: self.btn_close.setObjectName('navigation_button') self.btn_close.setToolTip(translations.TR_CLOSE_FILE) self.btn_close.clicked['bool'].connect(lambda s: self.about_to_close_file()) else: self.btn_close.setObjectName('close_split') self.btn_close.setToolTip(translations.TR_CLOSE_SPLIT) self.btn_close.clicked['bool'].connect(self.close_split) self.btn_close.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) hbox.addWidget(self.btn_close) def resizeEvent(self, event): super(ActionBar, self).resizeEvent(event) if event.size().width() < 350: self.symbols_combo.hide() self.code_navigator.hide() # self.lbl_position.hide() else: self.symbols_combo.show() self.code_navigator.show() # self.lbl_position.show() def add_item(self, text, neditable): """Add a new item to the combo and add the neditable data.""" self.combo.addItem(text, neditable) self.combo.setCurrentIndex(self.combo.count() - 1) def get_editables(self): editables = [] for index in range(self.combo.count()): neditable = self.combo.itemData(index) editables.append(neditable) return editables def add_symbols(self, symbols): """Add the symbols to the symbols's combo.""" self.symbols_combo.clear() for symbol in symbols: data = symbol[1] if data[1] == 'f': icon = QIcon(":img/function") else: icon = QIcon(":img/class") self.symbols_combo.addItem(icon, data[0]) def set_current_symbol(self, index): self.symbols_combo.setCurrentIndex(index) def update_item_icon(self, neditable, icon): index = self.combo.findData(neditable) self.combo.setItemIcon(index, icon) def update_item_text(self, neditable, text): index = self.combo.findData(neditable) self.combo.setItemText(index, text) def current_changed(self, index): """Change the current item in the combo.""" neditable = self.combo.itemData(index) self.changeCurrent.emit(neditable, index) def current_symbol_changed(self, index): """Change the current symbol in the combo.""" self.goToSymbol.emit(index) def update_line_col(self, line, col): """Update the line and column position.""" #self.lbl_position.setText(self._pos_text % (line, col)) IDE.getInstance().showMessageStatus(self._pos_text % (line, col)) def _context_menu_requested(self, point): """Display context menu for the combo file.""" if self.combo.count() == 0: # If there is not an Editor opened, don't show the menu return menu = QMenu() actionAdd = menu.addAction(translations.TR_ADD_TO_PROJECT) actionRun = menu.addAction(translations.TR_RUN_FILE) menuSyntax = menu.addMenu(translations.TR_CHANGE_SYNTAX) self._create_menu_syntax(menuSyntax) menu.addSeparator() actionClose = menu.addAction(translations.TR_CLOSE_FILE) actionCloseAll = menu.addAction(translations.TR_CLOSE_ALL_FILES) actionCloseAllNotThis = menu.addAction( translations.TR_CLOSE_OTHER_FILES) menu.addSeparator() actionSplitH = menu.addAction(translations.TR_SPLIT_VERTICALLY) actionSplitV = menu.addAction(translations.TR_SPLIT_HORIZONTALLY) menu.addSeparator() actionCopyPath = menu.addAction( translations.TR_COPY_FILE_PATH_TO_CLIPBOARD) actionShowFileInExplorer = menu.addAction( translations.TR_SHOW_FILE_IN_EXPLORER) actionReopen = menu.addAction(translations.TR_REOPEN_FILE) actionUndock = menu.addAction(translations.TR_UNDOCK_EDITOR) if len(settings.LAST_OPENED_FILES) == 0: actionReopen.setEnabled(False) #Connect actions actionSplitH.triggered['bool'].connect(lambda s: self._split(self.ORIENTATION.Horizontal)) actionSplitV.triggered['bool'].connect(lambda s: self._split(self.ORIENTATION.Vertical)) actionRun.triggered['bool'].connect(lambda s: self._run_this_file()) actionAdd.triggered['bool'].connect(lambda s: self._add_to_project()) actionClose.triggered['bool'].connect(lambda s: self.about_to_close_file()) actionCloseAllNotThis.triggered['bool'].connect(lambda s: self._close_all_files_except_this()) actionCloseAll.triggered['bool'].connect(lambda s: self._close_all_files()) actionCopyPath.triggered['bool'].connect(lambda s: self._copy_file_location()) actionShowFileInExplorer.triggered['bool'].connect(lambda s: self._show_file_in_explorer()) actionReopen.triggered['bool'].connect(lambda s: self._reopen_last_tab()) actionUndock.triggered['bool'].connect(lambda s: self._undock_editor()) menu.exec_(QCursor.pos()) def _create_menu_syntax(self, menuSyntax): """Create Menu with the list of syntax supported.""" syntax = list(settings.SYNTAX.keys()) syntax.sort() for syn in syntax: act = menuSyntax.addAction(syn) act.triggered['bool'].connect(lambda s: QMessageBox.critical(self, "Beta Info", "Can not construct this segment!"))#self._reapply_syntax def _reapply_syntax(self, syntaxAction): #TODO if [self.combo.currentIndex(), syntaxAction] != self._resyntax: self._resyntax = [self.combo.currentIndex(), syntaxAction] self.syntaxChangedemit(self.currentWidget(), syntaxAction.text()) def set_current_file(self, neditable): index = self.combo.findData(neditable) self.combo.setCurrentIndex(index) def set_current_by_index(self, index): self.combo.setCurrentIndex(index) def about_to_close_file(self, index=None): """Close the NFile object.""" if index is None: index = self.combo.currentIndex() neditable = self.combo.itemData(index) if neditable: print("\n\nabout_to_close_file:", self.combo.count(), index, self.combo.currentIndex()) neditable.nfile.close() def close_split(self): self.closeFile.emit() def close_file(self, neditable): """Receive the confirmation to close the file.""" index = self.combo.findData(neditable) self.combo.removeItem(index) return index def _run_this_file(self): """Execute the current file.""" neditable = self.combo.itemData(self.combo.currentIndex()) self.runFile.emit(neditable.file_path) def _add_to_project(self): """Emit a signal to let someone handle the inclusion of the file inside a project.""" neditable = self.combo.itemData(self.combo.currentIndex()) self.addToProject.emit(neditable.file_path) def _show_file_in_explorer(self): '''Triggered when the "Show File in Explorer" context menu action is selected. Emits the "showFileInExplorer(QString)" signal with the current file's full path as argument.''' neditable = self.combo.itemData(self.combo.currentIndex()) self.showFileInExplorer.emit(neditable.file_path) def _reopen_last_tab(self): self.reopenTab.emit(settings.LAST_OPENED_FILES.pop()) self.recentTabsModified.emit() def _undock_editor(self): self.undockEditor.emit() def _split(self, orientation): self.editorSplited.emit(orientation) def _copy_file_location(self): """Copy the path of the current opened file to the clipboard.""" neditable = self.combo.itemData(self.combo.currentIndex()) QApplication.clipboard().setText(neditable.file_path, QClipboard.Clipboard) def _close_all_files(self): """Close all the files opened.""" for i in range(self.combo.count()): self.about_to_close_file(0) def _close_all_files_except_this(self): """Close all the files except the current one.""" neditable = self.combo.itemData(self.combo.currentIndex()) for i in reversed(list(range(self.combo.count()))): ne = self.combo.itemData(i) if ne is not neditable: self.about_to_close_file(i)
class SongsTableToolbar(QWidget): play_all_needed = pyqtSignal() filter_albums_needed = pyqtSignal([list]) filter_text_changed = pyqtSignal([str]) def __init__(self, parent=None): super().__init__(parent) self.play_all_btn = QPushButton('Play All', self) self.play_all_btn.clicked.connect(self.play_all_needed.emit) # album filters self.filter_albums_combobox = QComboBox(self) self.filter_albums_combobox.addItems(['所有专辑', '标准', '单曲与EP', '现场', '合辑']) self.filter_albums_combobox.currentIndexChanged.connect( self.on_albums_filter_changed) # 8 works on macOS, don't know if it works on various Linux DEs self.filter_albums_combobox.setMinimumContentsLength(8) self.filter_albums_combobox.hide() self._setup_ui() def before_change_mode(self): """filter all filter buttons""" self.filter_albums_combobox.hide() self.play_all_btn.hide() def albums_mode(self): self.before_change_mode() self.filter_albums_combobox.show() def songs_mode(self): self.before_change_mode() self.play_all_btn.show() def enter_state_playall_start(self): self.play_all_btn.setEnabled(False) # currently, this is called only when feeluown is fetching songs, # so when we enter state_playall_start, we set play all btn text # to this. self.play_all_btn.setText('正在获取全部歌曲...') def enter_state_playall_end(self): self.play_all_btn.setText('正在获取全部歌曲...done') self.play_all_btn.setEnabled(True) self.play_all_btn.setText('播放全部') def _setup_ui(self): self._layout = QHBoxLayout(self) # left margin of meta widget is 30, we align with it # bottom margin of meta widget is 15, we should be larger than that self._layout.setContentsMargins(30, 0, 30, 20) self._layout.addWidget(self.play_all_btn) self._layout.addStretch(0) self._layout.addWidget(self.filter_albums_combobox) def on_albums_filter_changed(self, index): # ['所有', '专辑', '单曲与EP', '现场', '合辑'] if index == 0: types = [] elif index == 1: types = [AlbumType.standard] elif index == 2: types = [AlbumType.single, AlbumType.ep] elif index == 3: types = [AlbumType.live] else: types = [AlbumType.compilation, AlbumType.retrospective] self.filter_albums_needed.emit(types)
class SettingsPopUp(QDialog): def __init__(self, sender, pass1_needed=True, pass2_needed=False, add_list=None, delete_list=None): super(SettingsPopUp, self).__init__() self.initUI(pass1_needed, pass2_needed, add_list, delete_list) def initUI(self, pass1_needed, pass2_needed, add_list, delete_list): self.ltTop = QGridLayout() self.ldt_pass1 = QLineEdit() self.ldt_pass2 = QLineEdit() self.lbl_pass1 = QLabel(self) self.lbl_pass2 = QLabel(self) self.cbx_keys_to_add = QComboBox() self.cbx_keys_to_delete = QComboBox() self.btn_OK = QPushButton('OK', self) self.btn_showhide1 = QPushButton('', self) self.btn_showhide2 = QPushButton('', self) self.lbl_pass1.setText("Enter any existing password:"******"Enter new password:") self.btn_showhide1.setIcon(QIcon('images/showhide.png')) self.btn_showhide2.setIcon(QIcon('images/showhide.png')) self.ldt_pass1.setEchoMode(QLineEdit.Password) self.ldt_pass2.setEchoMode(QLineEdit.Password) self.btn_OK.clicked.connect(self.close) self.btn_showhide1.clicked.connect( lambda: self.ldt_pass1.setEchoMode(QLineEdit.Normal) if self.ldt_pass1.echoMode() == QLineEdit.Password else self. ldt_pass1.setEchoMode(QLineEdit.Password)) self.btn_showhide2.clicked.connect( lambda: self.ldt_pass2.setEchoMode(QLineEdit.Normal) if self.ldt_pass2.echoMode() == QLineEdit.Password else self. ldt_pass2.setEchoMode(QLineEdit.Password)) self.ltTop.addWidget(self.lbl_pass1, 0, 0, 1, 4) self.ltTop.addWidget(self.lbl_pass2, 1, 0, 1, 4) self.ltTop.addWidget(self.ldt_pass1, 0, 4, 1, 3) self.ltTop.addWidget(self.ldt_pass2, 1, 4, 1, 3) self.ltTop.addWidget(self.btn_showhide1, 0, 7, 1, 1) self.ltTop.addWidget(self.btn_showhide2, 1, 7, 1, 1) self.ltTop.addWidget(self.cbx_keys_to_add, 2, 0, 1, 8) self.ltTop.addWidget(self.cbx_keys_to_delete, 3, 0, 1, 8) self.ltTop.addWidget(self.btn_OK, 4, 3, 1, 2) self.setLayout(self.ltTop) if pass1_needed == False: self.ldt_pass1.hide() self.btn_showhide1.hide() self.lbl_pass1.hide() else: self.ldt_pass1.show() self.btn_showhide1.show() self.lbl_pass1.show() if pass2_needed == False: self.ldt_pass2.hide() self.btn_showhide2.hide() self.lbl_pass2.hide() else: self.ldt_pass2.show() self.btn_showhide2.show() self.lbl_pass2.show() if add_list != None: self.cbx_keys_to_add.addItems(add_list) self.cbx_keys_to_add.show() else: self.cbx_keys_to_add.hide() if delete_list != None: self.cbx_keys_to_delete.addItems(delete_list) self.cbx_keys_to_delete.show() else: self.cbx_keys_to_delete.hide()
class Painter(QMainWindow): def __init__(self, width=640, height=480, color=QColor('white'), name='', objects=None): super().__init__() if objects is None: objects = [] self.objects = objects self.file_name = name self.height = height self.width = width self.color = color self.temp = [] self.history = [[]] self.history_flag = False self.state_number = 0 self.click = False self.instrument = None self.cur_object = None self.setFocusPolicy(Qt.StrongFocus) self.setMouseTracking(True) self.edit_fl = False self.is_moving = False self.make_forms() self.gr_x1 = None self.gr_x2 = None self.gr_y1 = None self.gr_y2 = None self.line_color = QColor('blue') self.fill_color = None def make_forms(self): self.instruments = QComboBox(self) self.instruments.addItems(["Line", "Hand", "Rectangle", "Circle", "Select"]) self.instruments.move(10, 50) self.instruments.resize(200, 70) self.instruments.currentIndexChanged.connect(self.instrumentChanged) self.color_button = QPushButton('COLOR', self) self.color_button.move(220, 50) self.color_button.resize(150, 70) self.color_button.clicked.connect(self.color_picker) self.thick_button = QSpinBox(self) self.thick_button.move(530, 50) self.thick_button.resize(100, 70) self.thick_button.setMinimum(2) self.thick_button.setMaximum(60) self.thick_button.valueChanged.connect(self.spinboxChanged) self.thick_lbl = QLabel('Thickness', self) self.thick_lbl.move(530, -10) self.thick_lbl.resize(120, 70) self.combine_button = QPushButton('COMBINE', self) self.combine_button.move(640, 50) self.combine_button.resize(150, 70) self.combine_button.clicked.connect(self.combine) self.combine_button.hide() self.delete_button = QPushButton('DELETE', self) self.delete_button.move(800, 50) self.delete_button.resize(100, 70) self.delete_button.clicked.connect(self.delete) self.delete_button.hide() self.change_color_button = QPushButton('COLOR', self) self.change_color_button.move(220, 50) self.change_color_button.resize(150, 70) self.change_color_button.clicked.connect(self.change_color) self.change_color_button.hide() self.background_button = QPushButton('BACKGROUND', self) self.background_button.move(2500, 50) self.background_button.resize(200, 70) self.background_button.clicked.connect(self.settings) self.fill_button = QPushButton('FILL', self) self.fill_button.move(910, 50) self.fill_button.resize(100, 70) self.fill_button.clicked.connect(self.fill) self.fill_button.hide() self.save_button = QPushButton('SAVE', self) self.save_button.move(1500, 50) self.save_button.resize(100, 70) self.save_button.clicked.connect(self.save) self.save_button.show() self.grad_instruments = QComboBox(self) self.grad_instruments.addItems(["Linear", "Radial"]) self.grad_instruments.move(10, 50) self.grad_instruments.resize(1300, 70) self.grad_instruments.hide() def save(self): from SVGParser import SVGParser as svg s = svg(self.file_name).save2svg(self) def instrumentChanged(self): self.get_instrument() for o in self.objects: if o.selected: o.deselect() self.is_moving = False self.click = False self.cur_object = None self.update() def set_instrument(self, o): if isinstance(o, Circle): self.instrument = 'Circle' elif isinstance(o, Rectangle): self.instrument = 'Rectangle' elif isinstance(o, Line): self.instrument = 'Line' elif isinstance(o, Hand): self.instrument = 'Hand' elif isinstance(o, Object): self.instrument = 'Object' def edit(self): for i in self.objects: if i.selected: self.cur_object = i break if self.cur_object is not None: self.edit_fl = True self.click = True self.set_instrument(self.cur_object) def edit_ok(self): self.edit_fl = False self.cur_object.deselect() self.cur_object.stop_moving() self.instrument = 'Select' self.cur_object = None self.click = False self.is_moving = False def settings(self): form = Form(self) form.setFocus() vbox = QVBoxLayout() vbox.addWidget(form) self.setLayout(vbox) form.setGeometry(500, 500, 500, 800) form.show() def get_line_thick(self): th = int(self.thick_button.text()) return th def color_picker(self): self.line_color = QColorDialog.getColor() def change_thick(self, th): for e in self.objects: if e.selected: e.set_thickness(th) self.history_flag = True self.update() def fill(self): form = FillForm(self) form.setFocus() vbox = QVBoxLayout() vbox.addWidget(form) self.setLayout(vbox) form.setGeometry(500, 500, 500, 800) form.show() form.exec() for e in self.objects: if e.selected: e.fill(self.fill_color) self.history_flag = True self.fill_color = None self.update() def spinboxChanged(self, value): self.change_thick(value) def change_color(self): self.color_picker() for e in self.objects: if e.selected: e.deselect() e.set_color(self.line_color) self.history_flag = True self.update() def get_instrument(self): self.instrument = self.instruments.currentText() if self.instrument == "Select": self.instruments.show() self.thick_button.show() self.change_color_button.show() self.combine_button.show() self.delete_button.show() self.fill_button.show() self.color_button.hide() elif self.instrument == 'Line' \ or self.instrument == "Hand" \ or self.instrument == "Rectangle" \ or self.instrument == "Circle": self.combine_button.hide() self.change_color_button.hide() self.combine_button.hide() self.delete_button.hide() self.fill_button.hide() self.instruments.show() self.thick_button.show() self.color_button.show() self.update() def in_bounds(self, x, y): if self.is_moving and ( self.cur_object is not None) and ( not self.cur_object.in_bounds(self.width, self.height)): self.edit_ok() return False return 40 <= x + self.get_line_thick() / 2 <= self.width + 40 and ( 150 <= y + self.get_line_thick() / 2 <= 150 + self.height) and ( 40 <= x - self.get_line_thick() / 2 <= self.width + 40) and ( 150 <= y - self.get_line_thick() / 2 <= 150 + self.height) def mousePressEvent(self, event): x, y = event.pos().x(), event.pos().y() if not self.in_bounds(x, y): return if not self.edit_fl: self.get_instrument() self.get_line_thick() if self.instrument != "Select": if self.click and self.is_moving and self.cur_object is not None: self.edit_ok() self.click = False return self.history = self.history[:self.state_number + 1] self.history_flag = True if self.click: self.click = False if self.in_bounds(x, y): if self.instrument == 'Circle' and self.cur_object is not None: if self.circle_in_bounds(x, y): if self.cur_object is not None: if self.is_moving: self.cur_object.move(x, y) else: self.cur_object.set_end_coord(x, y) else: if self.cur_object is not None: if self.is_moving: self.cur_object.move(x, y) else: self.cur_object.set_end_coord(x, y) if not self.edit_fl: self.objects.append(self.cur_object) self.cur_object.set_color(self.line_color) self.cur_object.set_thickness(self.get_line_thick()) if self.edit_fl: self.edit_ok() else: if self.in_bounds(x, y): self.click = True if self.instrument == "Line": self.cur_object = Line(x, y) elif self.instrument == "Hand": self.cur_object = Hand(x, y) elif self.instrument == 'Rectangle': self.cur_object = Rectangle(x, y) elif self.instrument == 'Circle': self.cur_object = Circle(x, y) else: self.history_flag = False for f in self.objects: if f.is_coord_on_figure(x, y): if f.selected: f.move_or_deselect(x, y) if f.selected: self.is_moving = True self.edit() else: f.select() self.is_moving = True self.update() def circle_in_bounds(self, x2, y2): if self.is_moving and not self.cur_object.in_bounds(self.width, self.height): return False xr = self.cur_object.x1 yr = self.cur_object.y1 x = x2 - xr y = y2 - yr rad = sqrt(x * x + y * y) return self.in_bounds(xr + rad, yr) and ( self.in_bounds(xr - rad, yr)) and ( self.in_bounds(xr, yr + rad)) and ( self.in_bounds(xr, yr - rad)) def mouseMoveEvent(self, e): y = e.pos().y() x = e.pos().x() if self.cur_object is not None and self.click: if self.in_bounds(x, y): if self.instrument == 'Circle' and self.cur_object is not None: if self.circle_in_bounds(x, y): if self.is_moving: self.cur_object.move(x, y) else: self.cur_object.set_end_coord(x, y) else: if self.is_moving: self.cur_object.move(x, y) else: self.cur_object.set_end_coord(x, y) self.temp.append(self.cur_object) self.update() def get_max_x(self): return 40 + self.width def get_max_y(self): return 150 + self.height def draw_current_image(self): painter = QPainter(self) painter.fillRect(380, 50, 140, 70, self.line_color) painter.fillRect(40, 150, self.width, self.height, self.color) for e in self.objects: if e is not None: e.draw(painter, None, None, self.get_max_x(), self.get_max_y()) else: self.objects.remove(e) for e in self.temp: if e is not None: e.draw(painter, self.line_color, self.get_line_thick(), None, None) self.temp = [] def store_current_state(self): if self.history_flag and not self.click: self.history.append(deepcopy(self.objects)) self.history_flag = False self.state_number += 1 def paintEvent(self, e): self.draw_current_image() self.store_current_state() def keyPressEvent(self, event): key = event.key() if key == Qt.Key_Right: if self.state_number + 1 < len(self.history): self.state_number += 1 self.objects = deepcopy(self.history[self.state_number]) self.update() if key == Qt.Key_Left: if self.state_number - 1 >= 0: self.was_back = True self.state_number -= 1 self.objects = deepcopy(self.history[self.state_number]) self.update() def combine(self): li = [] o = [] obj = None for e in self.objects: if e.selected: e.deselect() if e is Object and obj is not None: obj = e else: li.append(e) else: o.append(e) self.history_flag = True o.append(Combiner.combine(li, obj)) self.objects = o self.update() def delete(self): o = [] for e in self.objects: if not e.selected: o.append(e) self.history_flag = True self.objects = o self.update()
class ActionBar(QFrame): """ SIGNALS: @changeCurrent(PyQt_PyObject) @runFile(QString) @reopenTab(QString) @recentTabsModified() """ change_current = pyqtSignal('PyQt_PyObject', int) splitEditor = pyqtSignal(bool) runFile = pyqtSignal('QString') closeSplit = pyqtSignal() addToProject = pyqtSignal('QString') showFileInExplorer = pyqtSignal('QString') goToSymbol = pyqtSignal(int) undockEditor = pyqtSignal() reopenTab = pyqtSignal('QString') closeImageViewer = pyqtSignal(int) needUpdateFocus = pyqtSignal() def __init__(self, main_combo=False): super(ActionBar, self).__init__() self.setAutoFillBackground(True) self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) self.setObjectName("actionbar") hbox = QHBoxLayout(self) hbox.setContentsMargins(1, 0, 0, 0) hbox.setSpacing(1) # self.lbl_checks = QLabel('') # self.lbl_checks.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) # self.lbl_checks.setFixedWidth(48) # self.lbl_checks.setVisible(False) # hbox.addWidget(self.lbl_checks) self.combo_files = ComboFiles(self) self.combo_files.setObjectName("combotab") # self.combo_files.setSizePolicy( # QSizePolicy.Expanding, QSizePolicy.Fixed) self.combo_files.setSizeAdjustPolicy( QComboBox.AdjustToMinimumContentsLengthWithIcon) self.combo_files.setMaximumWidth(400) self.combo_files.currentIndexChanged[int].connect(self.current_changed) self.combo_files.setToolTip(translations.TR_COMBO_FILE_TOOLTIP) self.combo_files.setContextMenuPolicy(Qt.CustomContextMenu) self.combo_files.customContextMenuRequested.connect( self._context_menu_requested) hbox.addWidget(self.combo_files) self.symbols_combo = QComboBox() self.symbols_combo.setObjectName("combo_symbols") # For correctly style sheet self.symbols_combo.setItemDelegate(QStyledItemDelegate()) self.symbols_combo.setModel(Model([])) self.symbols_combo.setSizeAdjustPolicy( QComboBox.AdjustToMinimumContentsLengthWithIcon) self.symbols_combo.activated[int].connect(self.current_symbol_changed) hbox.addWidget(self.symbols_combo) # Code Navigator actions self.code_navigator = CodeNavigator() hbox.addWidget(self.code_navigator) # Image Viewer actions self.image_viewer_controls = ImageViewerControls() self.image_viewer_controls.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Fixed) self.image_viewer_controls.setVisible(False) hbox.addWidget(self.image_viewer_controls) self._pos_text = "Line: %d, Col: %d" self.lbl_position = QLabel() self.lbl_position.setObjectName("position") self.lbl_position.setText(self._pos_text % (0, 0)) margin = self.style().pixelMetric( QStyle.PM_LayoutHorizontalSpacing) / 2 self.lbl_position.setContentsMargins(margin, 0, margin, 0) self.lbl_position.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) hbox.addWidget(self.lbl_position) self.btn_close = QPushButton() self.btn_close.setIcon( self.style().standardIcon(QStyle.SP_DialogCloseButton)) if main_combo: self.btn_close.setObjectName('close_button_combo') self.btn_close.setToolTip(translations.TR_CLOSE_FILE) self.btn_close.clicked.connect(self.about_to_close_file) else: self.btn_close.setObjectName('close_split') self.btn_close.setToolTip(translations.TR_CLOSE_SPLIT) self.btn_close.clicked.connect(lambda: self.closeSplit.emit()) self.btn_close.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Minimum) hbox.addWidget(self.btn_close) # Added for set language # self._setter_language = set_language.SetLanguageFile() # def _on_lbl_position_clicked(self): # main_container = IDE.get_service("main_container") # editor_widget = main_container.get_current_editor() # self._go_to_line_widget.set_line_count(editor_widget.line_count()) # self._go_to_line_widget.show() def resizeEvent(self, event): super(ActionBar, self).resizeEvent(event) if event.size().width() < 400: self.symbols_combo.hide() self.code_navigator.hide() self.lbl_position.hide() elif not self.image_viewer_controls.isVisible(): self.symbols_combo.show() self.code_navigator.show() self.lbl_position.show() def add_item(self, text, neditable): """Add a new item to the combo and add the neditable data.""" self.combo_files.addItem(text, neditable) self.combo_files.setCurrentIndex(self.combo_files.count() - 1) def get_editables(self): editables = [] for index in range(self.combo_files.count()): neditable = self.combo_files.itemData(index) editables.append(neditable) return editables def add_symbols(self, symbols): """Add the symbols to thcurrente symbols's combo.""" mo = Model(symbols) self.symbols_combo.setModel(mo) # self.symbols_combo.clear() # for symbol in symbols: # data = symbol[1] # if data[1] == 'f': # icon = QIcon(":img/function") # else: # icon = QIcon(":img/class") # self.symbols_combo.addItem(icon, data[0]) def set_current_symbol(self, index): self.symbols_combo.setCurrentIndex(index + 1) def update_item_icon(self, neditable, icon): index = self.combo_files.findData(neditable) self.combo_files.setItemIcon(index, icon) def update_item_text(self, neditable, text): index = self.combo_files.findData(neditable) self.combo_files.setItemText(index, text) def current_changed(self, index): """Change the current item in the combo.""" if index != -1: neditable = self.combo_files.itemData(index) self.change_current.emit(neditable, index) def current_symbol_changed(self, index): """Change the current symbol in the combo.""" if index == 0: return self.goToSymbol.emit(index - 1) def set_language_combo_changed(self, index): """Change the current language of editor.""" self._setter_language.set_language_to_editor(index) def update_line_col(self, line, col): """Update the line and column position.""" self.lbl_position.setText(self._pos_text % (line, col)) def _context_menu_requested(self, point): """Display context menu for the combo file.""" if self.combo_files.count() == 0: # If there is not an Editor opened, don't show the menu return menu = QMenu() action_add = menu.addAction(translations.TR_ADD_TO_PROJECT) action_run = menu.addAction(translations.TR_RUN_FILE) # menuSyntax = menu.addMenu(translations.TR_CHANGE_SYNTAX) action_show_folder = menu.addAction( translations.TR_SHOW_CONTAINING_FOLDER) # self._create_menu_syntax(menuSyntax) menu.addSeparator() action_close = menu.addAction(translations.TR_CLOSE_FILE) action_close_all = menu.addAction(translations.TR_CLOSE_ALL_FILES) action_close_all_not_this = menu.addAction( translations.TR_CLOSE_OTHER_FILES) menu.addSeparator() # actionSplitH = menu.addAction(translations.TR_SPLIT_VERTICALLY) # actionSplitV = menu.addAction(translations.TR_SPLIT_HORIZONTALLY) # menu.addSeparator() action_copy_path = menu.addAction( translations.TR_COPY_FILE_PATH_TO_CLIPBOARD) action_show_file_in_explorer = menu.addAction( translations.TR_SHOW_FILE_IN_EXPLORER) action_reopen = menu.addAction(translations.TR_REOPEN_FILE) action_undock = menu.addAction(translations.TR_UNDOCK_EDITOR) main_container = IDE.get_service("main_container") if not main_container.last_opened_files: action_reopen.setEnabled(False) # set language action # menu_set_language = menu.addMenu(translations.TR_SET_LANGUAGE) # self._set_list_languages(menu_set_language) # Connect actions action_close.triggered.connect(self.about_to_close_file) action_close_all.triggered.connect(self._close_all_files) action_close_all_not_this.triggered.connect( self._close_all_files_except_this) action_run.triggered.connect(self._run_this_file) action_undock.triggered.connect(self._undock_editor) action_show_folder.triggered.connect(self._show_containing_folder) action_copy_path.triggered.connect(self._copy_file_location) action_show_file_in_explorer.triggered.connect( self._show_file_in_explorer) action_add.triggered.connect(self._add_to_project) action_reopen.triggered.connect(self._reopen_last_tab) # self.connect(actionSplitH, SIGNAL("triggered()"), # lambda: self._split(False)) # self.connect(actionSplitV, SIGNAL("triggered()"), # lambda: self._split(True)) menu.exec_(QCursor.pos()) def _set_list_languages(self, menu_set_language): for l in self._setter_language.get_list_of_language(): if l is None: continue action = menu_set_language.addAction(l) action.triggered.connect(lambda checked, language=l: self._set_language_action(language)) def _set_language_action(self, language): self._setter_language.set_language_to_editor(language) def _show_containing_folder(self): main_container = IDE.get_service("main_container") editor_widget = main_container.get_current_editor() filename = editor_widget.file_path file_manager.show_containing_folder(filename) def _create_menu_syntax(self, menuSyntax): """Create Menu with the list of syntax supported.""" syntax = list(settings.SYNTAX.keys()) syntax.sort() for syn in syntax: menuSyntax.addAction(syn) # self.connect(menuSyntax, SIGNAL("triggered(QAction*)"), # self._reapply_syntax) def _reapply_syntax(self, syntaxAction): # TODO if [self.currentIndex(), syntaxAction] != self._resyntax: self._resyntax = [self.currentIndex(), syntaxAction] # self.emit(SIGNAL("syntaxChanged(QWidget, QString)"), # self.currentWidget(), syntaxAction.text()) def set_current_file(self, neditable): index = self.combo_files.findData(neditable) self.combo_files.setCurrentIndex(index) def set_current_by_index(self, index): self.combo_files.setCurrentIndex(index) @pyqtSlot() def about_to_close_file(self, index=None): """Close the NFile or ImageViewer object.""" parent = self.parent().parentWidget() # Splitter if parent.count() > 1: return if index is None: index = self.combo_files.currentIndex() if index == -1: return neditable = self.combo_files.itemData(index) if neditable: neditable.nfile.close() else: # Image viewer self.combo_files.removeItem(index) self.closeImageViewer.emit(index) def close_split(self): self.closeSplit.emit() def close_file(self, neditable): """Receive the confirmation to close the file.""" index = self.combo_files.findData(neditable) self.combo_files.removeItem(index) return index def _run_this_file(self): """Execute the current file""" neditable = self.combo_files.itemData(self.combo_files.currentIndex()) self.runFile.emit(neditable.file_path) def _add_to_project(self): """Emit a signal to let someone handle the inclusion of the file inside a project.""" neditable = self.combo_files.itemData(self.combo_files.currentIndex()) self.addToProject.emit(neditable.file_path) def _show_file_in_explorer(self): """Triggered when the "Show File in Explorer" context menu action is selected. Emits the "showFileInExplorer(QString)" signal with the current file's full path as argument.""" neditable = self.combo_files.itemData(self.combo_files.currentIndex()) self.showFileInExplorer.emit(neditable.file_path) def _reopen_last_tab(self): main_container = IDE.get_service("main_container") last_closed = main_container.last_opened_files[0] self.reopenTab.emit(last_closed) def _undock_editor(self): self.undockEditor.emit() def _split(self, orientation): print("emitir splitEditor") # self.emit(SIGNAL("splitEditor(bool)"), orientation) def _copy_file_location(self): """Copy the path of the current opened file to the clipboard.""" neditable = self.combo_files.itemData(self.combo_files.currentIndex()) QApplication.clipboard().setText(neditable.file_path, QClipboard.Clipboard) def _close_all_files(self): """Close all the files opened.""" for i in range(self.combo_files.count()): self.about_to_close_file(0) def _close_all_files_except_this(self): """Close all the files except the current one.""" neditable = self.combo_files.itemData(self.combo_files.currentIndex()) for i in reversed(list(range(self.combo_files.count()))): ne = self.combo_files.itemData(i) if ne is not neditable: self.about_to_close_file(i)
class ReceiveView(QWidget): _qr_window: Optional[QR_Window] = None def __init__(self, main_window: 'ElectrumWindow', account_id: int) -> None: super().__init__(main_window) self._main_window = weakref.proxy(main_window) self._account_id = account_id self._account = main_window._wallet.get_account(account_id) self._logger = logs.get_logger(f"receive-view[{self._account_id}]") self._receive_key_id: Optional[int] = None self._request_list_toolbar_layout = TableTopButtonLayout() self._request_list_toolbar_layout.refresh_signal.connect( self._main_window.refresh_wallet_display) self._request_list_toolbar_layout.filter_signal.connect( self._filter_request_list) form_layout = self.create_form_layout() self._request_list = RequestList(self, main_window) request_container = self.create_request_list_container() vbox = QVBoxLayout(self) vbox.addLayout(form_layout) vbox.addSpacing(20) vbox.addWidget(request_container, 1) self.setLayout(vbox) def clean_up(self) -> None: # If there are no accounts there won't be a receive QR code object created yet. if self._receive_qr is not None: self._receive_qr.clean_up() if self._qr_window is not None: self._qr_window.close() def create_form_layout(self) -> QHBoxLayout: # A 4-column grid layout. All the stretch is in the last column. # The exchange rate plugin adds a fiat widget in column 2 grid = QGridLayout() grid.setSpacing(8) grid.setColumnStretch(3, 1) self._receive_destination_e = ButtonsLineEdit() self._receive_destination_e.addCopyButton(app_state.app) self._receive_destination_e.setReadOnly(True) msg = _( 'Bitcoin SV payment destination where the payment should be received. ' 'Note that each payment request uses a different Bitcoin SV payment destination.' ) receive_address_label = HelpLabel(_('Receiving destination'), msg) self._receive_destination_e.textChanged.connect( self._update_receive_qr) self._receive_destination_e.setFocusPolicy(Qt.NoFocus) grid.addWidget(receive_address_label, 0, 0) grid.addWidget(self._receive_destination_e, 0, 1, 1, -1) self._receive_message_e = QLineEdit() grid.addWidget(QLabel(_('Description')), 1, 0) grid.addWidget(self._receive_message_e, 1, 1, 1, -1) self._receive_message_e.textChanged.connect(self._update_receive_qr) self._receive_amount_e = BTCAmountEdit() grid.addWidget(QLabel(_('Requested amount')), 2, 0) grid.addWidget(self._receive_amount_e, 2, 1) self._receive_amount_e.textChanged.connect(self._update_receive_qr) self._fiat_receive_e = AmountEdit( app_state.fx.get_currency if app_state.fx else '') if not app_state.fx or not app_state.fx.is_enabled(): self._fiat_receive_e.setVisible(False) grid.addWidget(self._fiat_receive_e, 2, 2, Qt.AlignLeft) self._main_window.connect_fields(self._receive_amount_e, self._fiat_receive_e) self._expires_combo = QComboBox() self._expires_combo.addItems([i[0] for i in expiration_values]) self._expires_combo.setCurrentIndex(3) self._expires_combo.setFixedWidth(self._receive_amount_e.width()) msg = ' '.join([ _('Expiration date of your request.'), _('This information is seen by the recipient if you send them ' 'a signed payment request.'), _('Expired requests have to be deleted manually from your list, ' 'in order to free the corresponding Bitcoin SV addresses.'), _('The Bitcoin SV address never expires and will always be part ' 'of this ElectrumSV wallet.'), ]) grid.addWidget(HelpLabel(_('Request expires'), msg), 3, 0) grid.addWidget(self._expires_combo, 3, 1) self._expires_label = QLineEdit('') self._expires_label.setReadOnly(1) self._expires_label.setFocusPolicy(Qt.NoFocus) self._expires_label.hide() grid.addWidget(self._expires_label, 3, 1) self._save_request_button = EnterButton(_('Save request'), self._save_form_as_request) self._new_request_button = EnterButton(_('New'), self._new_payment_request) self._receive_qr = QRCodeWidget(fixedSize=200) self._receive_qr.link_to_window(self._toggle_qr_window) buttons = QHBoxLayout() buttons.addStretch(1) buttons.addWidget(self._save_request_button) buttons.addWidget(self._new_request_button) grid.addLayout(buttons, 4, 1, 1, 2) vbox_g = QVBoxLayout() vbox_g.addLayout(grid) vbox_g.addStretch() hbox = QHBoxLayout() hbox.addLayout(vbox_g) hbox.addWidget(self._receive_qr) return hbox def create_request_list_container(self) -> QGroupBox: layout = QVBoxLayout() layout.setSpacing(0) layout.setContentsMargins(6, 0, 6, 6) layout.addLayout(self._request_list_toolbar_layout) layout.addWidget(self._request_list) request_box = QGroupBox() request_box.setTitle(_('Requests')) request_box.setAlignment(Qt.AlignCenter) request_box.setContentsMargins(0, 0, 0, 0) request_box.setLayout(layout) return request_box def update_widgets(self) -> None: self._request_list.update() def update_destination(self) -> None: text = "" if self._receive_key_id is not None: script_template = self._account.get_script_template_for_id( self._receive_key_id) if script_template is not None: text = script_template_to_string(script_template) self._receive_destination_e.setText(text) def update_contents(self) -> None: self._expires_label.hide() self._expires_combo.show() if self._account.is_deterministic(): fresh_key = self._account.get_fresh_keys(RECEIVING_SUBPATH, 1)[0] self.set_receive_key(fresh_key) def update_for_fx_quotes(self) -> None: if self._account_id is not None: edit = (self._fiat_receive_e if self._fiat_receive_e.is_last_edited else self._receive_amount_e) edit.textEdited.emit(edit.text()) # Bound to text fields in `_create_receive_form_layout`. def _update_receive_qr(self) -> None: if self._receive_key_id is None: return amount = self._receive_amount_e.get_amount() message = self._receive_message_e.text() self._save_request_button.setEnabled((amount is not None) or (message != "")) script_template = self._account.get_script_template_for_id( self._receive_key_id) address_text = script_template_to_string(script_template) uri = web.create_URI(address_text, amount, message) self._receive_qr.setData(uri) if self._qr_window and self._qr_window.isVisible(): self._qr_window.set_content(self._receive_destination_e.text(), amount, message, uri) def _toggle_qr_window(self, event: QEvent) -> None: if self._receive_key_id is None: self.show_message(_("No available receiving destination.")) return if not self._qr_window: self._qr_window = QR_Window(self) self._qr_window.setVisible(True) self._qr_window_geometry = self._qr_window.geometry() else: if not self._qr_window.isVisible(): self._qr_window.setVisible(True) self._qr_window.setGeometry(self._qr_window_geometry) else: self._qr_window_geometry = self._qr_window.geometry() self._qr_window.setVisible(False) self._update_receive_qr() def set_fiat_ccy_enabled(self, flag: bool) -> None: self._fiat_receive_e.setVisible(flag) def get_bsv_edits(self) -> List[BTCAmountEdit]: return [self._receive_amount_e] def _save_form_as_request(self) -> None: if not self._receive_key_id: self._main_window.show_error(_('No receiving payment destination')) return amount = self._receive_amount_e.get_amount() message = self._receive_message_e.text() if not message and not amount: self._main_window.show_error(_('No message or amount')) return def callback(exc_value: Optional[Exception] = None) -> None: if exc_value is not None: raise exc_value # pylint: disable=raising-bad-type self._request_list.update_signal.emit() i = self._expires_combo.currentIndex() expiration = [x[1] for x in expiration_values][i] row = self._account.requests.get_request_for_key_id( self._receive_key_id) if row is None: row = self._account.requests.create_request( self._receive_key_id, PaymentFlag.UNPAID, amount, expiration, message, callback) else: # Expiration is just a label, so we don't use the value. self._account.requests.update_request(row.paymentrequest_id, row.state, amount, row.expiration, message, callback) self._save_request_button.setEnabled(False) def _new_payment_request(self) -> None: keyinstances: List[KeyInstanceRow] = [] if self._account.is_deterministic(): keyinstances = self._account.get_fresh_keys(RECEIVING_SUBPATH, 1) if not len(keyinstances): if not self._account.is_deterministic(): msg = [ _('No more payment destinations in your wallet.'), _('You are using a non-deterministic account, which ' 'cannot create new payment destinations.'), _('If you want to create new payment destinations, ' 'use a deterministic account instead.') ] self._main_window.show_message(' '.join(msg)) return self._main_window.show_message( _('Your wallet is broken and could not allocate a new payment destination.' )) self.update_contents() self._new_request_button.setEnabled(False) self._receive_message_e.setFocus(1) def get_receive_key_id(self) -> Optional[int]: return self._receive_key_id # Only called from key list menu. def receive_at_id(self, key_id: int) -> None: self._receive_key_id = key_id self._new_request_button.setEnabled(True) self.update_destination() self._main_window.show_receive_tab() def set_receive_key_id(self, key_id: int) -> None: self._receive_key_id = key_id def set_receive_key(self, keyinstance: KeyInstanceRow) -> None: self._receive_key_id = keyinstance.keyinstance_id self._receive_message_e.setText("") self._receive_amount_e.setAmount(None) self.update_destination() def set_form_contents(self, address_text: str, value: int, description: Optional[str] = None, expires_description: str = "") -> None: self._receive_destination_e.setText(address_text) self._receive_message_e.setText(description or "") self._receive_amount_e.setAmount(value) self._expires_combo.hide() self._expires_label.show() self._expires_label.setText(expires_description) self._new_request_button.setEnabled(True) def set_new_button_enabled(self, flag: bool) -> None: self._new_request_button.setEnabled(flag) def _filter_request_list(self, text: str) -> None: self._request_list.filter(text)
class Menu(QWidget): def __init__(self, option=None): super().__init__() self.setBackground(QImage("Images/menu/biohazard.jpg"), self.width(), self.height()) self.combo = QComboBox(self) self.combo.addItem("SIR") self.combo.addItem("SEIHFR") self.combo.addItem("SEIHFBR") self.combo.addItem("SEIRS") self.combo.addItem("Dispersion spatiale") self.combo.addItem("Effet du vaccin") self.combo.addItem("Map") self.comboMap = QComboBox(self) self.comboMap.addItem("PlateCarree") self.comboMap.addItem("Miller") self.comboMap.addItem("Mollweide") self.comboMap.addItem("EckertIII") self.comboMap.addItem("EuroPP") self.comboMap.hide() self.combo.currentIndexChanged.connect( lambda: self.showNewCombo() if self.combo.currentIndex() == 6 else self.comboMap.hide() if not self.comboMap.isHidden() else None) self.button = QPushButton("GO", self) self.button.clicked.connect(self.choose_model) self.button.keyPressEvent = self.keyPressEvent self.hbox = QHBoxLayout() self.hbox.addWidget(self.button) self.hbox.addWidget(self.combo) self.hbox.setAlignment(Qt.AlignCenter) # vbox = QVBoxLayout(self) # vbox.addStretch(1) # vbox.addWidget(self.button2) # vbox.addLayout(hbox) self.setLayout(self.hbox) if option is not None: if option == "SIR": self.choose_model(model_name="SIR") elif option == "SEIRS": self.choose_model(model_name="SEIRS") elif option == "SEIHFR": self.choose_model(model_name="SEIHFR") elif option == "SEIHFBR": self.choose_model(model_name="SEIHFBR") elif option == "spa": self.choose_model(model_name="Dispersion spatiale") elif option == "vac": self.choose_model(model_name="Effet du vaccin") elif option == "map": self.choose_model(model_name="Map") else: self.showMaximized() else: self.showMaximized() def setBackground(self, aimage, width=None, height=None): image = aimage.scaled(width, height, Qt.IgnoreAspectRatio, Qt.SmoothTransformation) sImage = image.scaled(QSize(width, height)) palette = QPalette() palette.setBrush(QPalette.Window, QBrush(sImage)) self.setPalette(palette) def keyPressEvent(self, e): if e.key() == 16777220: self.choose_model() def choose_model(self, notUsed=None, model_name=None): from GUI_pyqt import App if model_name is None: model_name = self.combo.currentText() self.close() if model_name == "SIR": from GUI_pyqt import SIR self.app2 = App(SIR()) elif model_name == "SEIRS": from GUI_pyqt import SEIRS self.app2 = App(SEIRS()) elif model_name == "SEIHFR": from GUI_pyqt import SEIHFR self.app2 = App(SEIHFR()) elif model_name == "SEIHFBR": from GUI_pyqt import SEIHFBR self.app2 = App(SEIHFBR()) elif model_name == "Dispersion spatiale": from PixelGrid import PixelGridWindow self.app2 = PixelGridWindow() elif model_name == "Effet du vaccin": from VaccineGrid import PixelGridWindowVaccined self.app2 = PixelGridWindowVaccined() elif model_name == "Map": from map import MapWindow self.app2 = MapWindow("ccrs." + self.comboMap.currentText() + "()") def showNewCombo(self): self.hbox.addWidget(self.comboMap) self.comboMap.show()
class SongsTableToolbar(QWidget): _desc_btn_checked_text = '折叠' _desc_btn_unchecked_text = '展开描述' play_all_needed = pyqtSignal() show_songs_needed = pyqtSignal() show_albums_needed = pyqtSignal() show_contributed_albums_needed = pyqtSignal() # show_videos_needed = pyqtSignal() filter_albums_needed = pyqtSignal([list]) toggle_desc_needed = pyqtSignal() def __init__(self, parent=None): super().__init__(parent) self.play_all_btn = QPushButton('播放全部', self) self.show_songs_btn = QPushButton('歌曲', parent=self) self.show_albums_btn = QPushButton('专辑', parent=self) self.show_contributed_albums_btn = QPushButton('参与作品', parent=self) # self.show_videos_btn = QPushButton(parent=self) self.desc_btn = QPushButton(self._desc_btn_unchecked_text, self) self.play_all_btn.clicked.connect(self.play_all_needed.emit) self.show_songs_btn.clicked.connect(self.show_songs_needed.emit) self.show_albums_btn.clicked.connect(self.show_albums_needed.emit) self.show_contributed_albums_btn.clicked.connect( self.show_contributed_albums_needed.emit) # self.show_videos_btn.clicked.connect(self.show_videos_needed.emit) self.desc_btn.clicked.connect(self.on_desc_btn_toggled) # album filters self.filter_albums_combobox = QComboBox(self) self.filter_albums_combobox.addItems( ['所有专辑', '标准', '单曲与EP', '现场', '合辑']) self.filter_albums_combobox.currentIndexChanged.connect( self.on_albums_filter_changed) # 8 works on macOS, don't know if it works on various Linux DEs self.filter_albums_combobox.setMinimumContentsLength(8) self.show_songs_btn.hide() self.show_albums_btn.hide() self.show_contributed_albums_btn.hide() self.desc_btn.hide() self.filter_albums_combobox.hide() self._setup_ui() def before_change_mode(self): """filter all filter buttons""" self.filter_albums_combobox.hide() def artist_mode(self): self.before_change_mode() self.play_all_btn.show() self.show_songs_btn.show() self.show_albums_btn.show() self.show_contributed_albums_btn.show() def albums_mode(self): self.before_change_mode() self.play_all_btn.hide() # self.show_albums_btn.show() self.filter_albums_combobox.show() def songs_mode(self): self.before_change_mode() self.play_all_btn.show() def pure_songs_mode(self): """playlist/collections mode""" self.before_change_mode() self.show_contributed_albums_btn.hide() self.show_albums_btn.hide() self.show_songs_btn.hide() self.play_all_btn.show() def enter_state_playall_start(self): self.play_all_btn.setEnabled(False) # currently, this is called only when feeluown is fetching songs, # so when we enter state_playall_start, we set play all btn text # to this. self.play_all_btn.setText('正在获取全部歌曲...') def enter_state_playall_end(self): self.play_all_btn.setText('正在获取全部歌曲...done') self.play_all_btn.setEnabled(True) self.play_all_btn.setText('播放全部') def _setup_ui(self): self._layout = QHBoxLayout(self) self._layout.setContentsMargins(0, 0, 0, 0) self._layout.setSpacing(0) self._layout.addWidget(self.play_all_btn) self._layout.addSpacing(5) self._layout.addWidget(self.show_songs_btn) self._layout.addSpacing(5) self._layout.addWidget(self.show_albums_btn) self._layout.addSpacing(5) self._layout.addWidget(self.show_contributed_albums_btn) self._layout.addStretch(1) self._layout.addWidget(self.filter_albums_combobox) self._layout.addStretch(1) self._layout.addWidget(self.desc_btn) self._layout.addStretch(1) def on_desc_btn_toggled(self, checked): if checked: self.play_all_btn.hide() self.desc_btn.setText(self._desc_btn_checked_text) else: self.play_all_btn.show() self.desc_btn.setText(self._desc_btn_unchecked_text) self.toggle_desc_needed.emit() def on_albums_filter_changed(self, index): # ['所有', '专辑', '单曲与EP', '现场', '合辑'] if index == 0: types = [] elif index == 1: types = [AlbumType.standard] elif index == 2: types = [AlbumType.single, AlbumType.ep] elif index == 3: types = [AlbumType.live] else: types = [AlbumType.compilation, AlbumType.retrospective] self.filter_albums_needed.emit(types)
class VideoFinderAddLink(AddLinkWindow): running_thread = None threadPool = {} def __init__(self, parent, receiver_slot, settings, video_dict={}): super().__init__(parent, receiver_slot, settings, video_dict) self.setWindowTitle( QCoreApplication.translate("ytaddlink_src_ui_tr", 'Video Finder')) self.size_label.hide() # empty lists for no_audio and no_video and video_audio files self.no_audio_list = [] self.no_video_list = [] self.video_audio_list = [] self.media_title = '' # add support for other languages locale = str(self.persepolis_setting.value('settings/locale')) QLocale.setDefault(QLocale(locale)) self.translator = QTranslator() if self.translator.load(':/translations/locales/ui_' + locale, 'ts'): QCoreApplication.installTranslator(self.translator) # extension_label self.extension_label = QLabel(self.link_frame) self.change_name_horizontalLayout.addWidget(self.extension_label) # Fetch Button self.url_submit_pushButtontton = QPushButton(self.link_frame) self.link_horizontalLayout.addWidget(self.url_submit_pushButtontton) # Status Box self.status_box_textEdit = QTextEdit(self.link_frame) self.status_box_textEdit.setMaximumHeight(150) self.link_verticalLayout.addWidget(self.status_box_textEdit) # Select format horizontal layout select_format_horizontalLayout = QHBoxLayout() # Selection Label self.select_format_label = QLabel(self.link_frame) select_format_horizontalLayout.addWidget(self.select_format_label) # Selection combobox self.media_comboBox = QComboBox(self.link_frame) self.media_comboBox.setMinimumWidth(200) select_format_horizontalLayout.addWidget(self.media_comboBox) # Duration label self.duration_label = QLabel(self.link_frame) select_format_horizontalLayout.addWidget(self.duration_label) self.format_selection_frame = QFrame(self) self.format_selection_frame.setLayout(select_format_horizontalLayout) self.link_verticalLayout.addWidget(self.format_selection_frame) # advanced_format_selection_checkBox self.advanced_format_selection_checkBox = QCheckBox(self) self.link_verticalLayout.addWidget( self.advanced_format_selection_checkBox) # advanced_format_selection_frame self.advanced_format_selection_frame = QFrame(self) self.link_verticalLayout.addWidget( self.advanced_format_selection_frame) advanced_format_selection_horizontalLayout = QHBoxLayout( self.advanced_format_selection_frame) # video_format_selection self.video_format_selection_label = QLabel( self.advanced_format_selection_frame) self.video_format_selection_comboBox = QComboBox( self.advanced_format_selection_frame) # audio_format_selection self.audio_format_selection_label = QLabel( self.advanced_format_selection_frame) self.audio_format_selection_comboBox = QComboBox( self.advanced_format_selection_frame) for widget in [ self.video_format_selection_label, self.video_format_selection_comboBox, self.audio_format_selection_label, self.audio_format_selection_comboBox ]: advanced_format_selection_horizontalLayout.addWidget(widget) # Set Texts self.url_submit_pushButtontton.setText( QCoreApplication.translate("ytaddlink_src_ui_tr", 'Fetch Media List')) self.select_format_label.setText( QCoreApplication.translate("ytaddlink_src_ui_tr", 'Select a format')) self.video_format_selection_label.setText( QCoreApplication.translate("ytaddlink_src_ui_tr", 'Video format:')) self.audio_format_selection_label.setText( QCoreApplication.translate("ytaddlink_src_ui_tr", 'Audio format:')) self.advanced_format_selection_checkBox.setText( QCoreApplication.translate("ytaddlink_src_ui_tr", 'Advanced options')) # Add Slot Connections self.url_submit_pushButtontton.setEnabled(False) self.change_name_lineEdit.setEnabled(False) self.ok_pushButton.setEnabled(False) self.download_later_pushButton.setEnabled(False) self.format_selection_frame.setEnabled(True) self.advanced_format_selection_frame.setEnabled(False) self.advanced_format_selection_checkBox.toggled.connect( self.advancedFormatFrame) self.url_submit_pushButtontton.clicked.connect(self.submitClicked) self.media_comboBox.activated.connect( partial(self.mediaSelectionChanged, 'video_audio')) self.video_format_selection_comboBox.activated.connect( partial(self.mediaSelectionChanged, 'video')) self.audio_format_selection_comboBox.activated.connect( partial(self.mediaSelectionChanged, 'audio')) self.link_lineEdit.textChanged.disconnect( super().linkLineChanged) # Should be disconnected. self.link_lineEdit.textChanged.connect(self.linkLineChangedHere) self.setMinimumSize(650, 480) self.status_box_textEdit.hide() self.format_selection_frame.hide() self.advanced_format_selection_frame.hide() self.advanced_format_selection_checkBox.hide() if 'link' in video_dict.keys() and video_dict['link']: self.link_lineEdit.setText(video_dict['link']) self.url_submit_pushButtontton.setEnabled(True) else: # check clipboard clipboard = QApplication.clipboard() text = clipboard.text() if (("tp:/" in text[2:6]) or ("tps:/" in text[2:7])): self.link_lineEdit.setText(str(text)) self.url_submit_pushButtontton.setEnabled(True) def advancedFormatFrame(self, button): if self.advanced_format_selection_checkBox.isChecked(): self.advanced_format_selection_frame.setEnabled(True) self.format_selection_frame.setEnabled(False) self.mediaSelectionChanged( 'video', int(self.video_format_selection_comboBox.currentIndex())) else: self.advanced_format_selection_frame.setEnabled(False) self.format_selection_frame.setEnabled(True) self.mediaSelectionChanged('video_audio', int(self.media_comboBox.currentIndex())) def getReadableSize(self, size): try: return '{:1.2f} MB'.format(int(size) / 1048576) except: return str(size) def getReadableDuration(self, seconds): try: seconds = int(seconds) hours = seconds // 3600 seconds = seconds % 3600 minutes = seconds // 60 seconds = seconds % 60 return '{:02d}:{:02d}:{:02d}'.format(hours, minutes, seconds) except: return str(seconds) # Define native slots def urlChanged(self, value): if ' ' in value or value == '': self.url_submit_pushButtontton.setEnabled(False) self.url_submit_pushButtontton.setToolTip( QCoreApplication.translate("ytaddlink_src_ui_tr", 'Please enter a valid video link')) else: self.url_submit_pushButtontton.setEnabled(True) self.url_submit_pushButtontton.setToolTip('') def submitClicked(self, button=None): # Clear media list self.media_comboBox.clear() self.format_selection_frame.hide() self.advanced_format_selection_checkBox.hide() self.advanced_format_selection_frame.hide() self.video_format_selection_comboBox.clear() self.audio_format_selection_comboBox.clear() self.change_name_lineEdit.clear() self.threadPool.clear() self.change_name_checkBox.setChecked(False) self.video_audio_list.clear() self.no_video_list.clear() self.no_audio_list.clear() self.url_submit_pushButtontton.setEnabled(False) self.status_box_textEdit.setText( QCoreApplication.translate("ytaddlink_src_ui_tr", 'Fetching Media Info...')) self.status_box_textEdit.show() self.ok_pushButton.setEnabled(False) self.download_later_pushButton.setEnabled(False) dictionary_to_send = deepcopy(self.plugin_add_link_dictionary) # More options more_options = self.collectMoreOptions() for k in more_options.keys(): dictionary_to_send[k] = more_options[k] dictionary_to_send['link'] = self.link_lineEdit.text() fetcher_thread = MediaListFetcherThread(self.fetchedResult, dictionary_to_send, self) self.parent.threadPool.append(fetcher_thread) self.parent.threadPool[len(self.parent.threadPool) - 1].start() def fileNameChanged(self, value): if value.strip() == '': self.ok_pushButton.setEnabled(False) def mediaSelectionChanged(self, combobox, index): try: if combobox == 'video_audio': if self.media_comboBox.currentText() == 'Best quality': self.change_name_lineEdit.setText(self.media_title) self.extension_label.setText('.' + self.no_audio_list[-1]['ext']) else: self.change_name_lineEdit.setText(self.media_title) self.extension_label.setText( '.' + self.video_audio_list[index]['ext']) self.change_name_checkBox.setChecked(True) elif combobox == 'video': if self.video_format_selection_comboBox.currentText( ) != 'No video': self.change_name_lineEdit.setText(self.media_title) self.extension_label.setText('.' + self.no_audio_list[index - 1]['ext']) self.change_name_checkBox.setChecked(True) else: if self.audio_format_selection_comboBox.currentText( ) != 'No audio': self.change_name_lineEdit.setText(self.media_title) self.extension_label.setText('.' + self.no_video_list[ int(self.audio_format_selection_comboBox. currentIndex()) - 1]['ext']) self.change_name_checkBox.setChecked(True) else: self.change_name_lineEdit.setChecked(False) elif combobox == 'audio': if self.audio_format_selection_comboBox.currentText( ) != 'No audio' and self.video_format_selection_comboBox.currentText( ) == 'No video': self.change_name_lineEdit.setText(self.media_title) self.extension_label.setText('.' + self.no_video_list[index - 1]['ext']) self.change_name_checkBox.setChecked(True) elif (self.audio_format_selection_comboBox.currentText() == 'No audio' and self.video_format_selection_comboBox.currentText() != 'No video') or ( self.audio_format_selection_comboBox.currentText() != 'No audio' and self.video_format_selection_comboBox.currentText() != 'No video'): self.change_name_lineEdit.setText(self.media_title) self.extension_label.setText('.' + self.no_audio_list[ int(self.video_format_selection_comboBox.currentIndex( )) - 1]['ext']) self.change_name_checkBox.setChecked(True) elif self.audio_format_selection_comboBox.currentText( ) == 'No audio' and self.video_format_selection_comboBox.currentText( ) == 'No video': self.change_name_checkBox.setChecked(False) except Exception as ex: logger.sendToLog(ex, "ERROR") def fetchedResult(self, media_dict): self.url_submit_pushButtontton.setEnabled(True) if 'error' in media_dict.keys(): self.status_box_textEdit.setText('<font color="#f11">' + str(media_dict['error']) + '</font>') self.status_box_textEdit.show() else: # Show the media list # add no audio and no video options to the comboboxes self.video_format_selection_comboBox.addItem('No video') self.audio_format_selection_comboBox.addItem('No audio') self.media_title = media_dict['title'] if 'formats' not in media_dict.keys( ) and 'entries' in media_dict.keys(): formats = media_dict['entries'] formats = formats[0] media_dict['formats'] = formats['formats'] elif 'formats' not in media_dict.keys( ) and 'format' in media_dict.keys(): media_dict['formats'] = [media_dict.copy()] try: i = 0 for f in media_dict['formats']: no_audio = False no_video = False text = '' if 'acodec' in f.keys(): # only video, no audio if f['acodec'] == 'none': no_audio = True # resolution if 'height' in f.keys(): text = text + ' ' + '{}p'.format(f['height']) if 'vcodec' in f.keys(): # if f['vcodec'] == 'none' and f['acodec'] != 'none': # continue # No video, show audio bit rate if f['vcodec'] == 'none': text = text + '{}kbps'.format(f['abr']) no_video = True if 'ext' in f.keys(): text = text + ' ' + '.{}'.format(f['ext']) if 'filesize' in f.keys() and f['filesize']: # Youtube api does not supply file size for some formats, so check it. text = text + ' ' + '{}'.format( self.getReadableSize(f['filesize'])) else: # Start spider to find file size input_dict = deepcopy(self.plugin_add_link_dictionary) input_dict['link'] = f['url'] more_options = self.collectMoreOptions() for key in more_options.keys(): input_dict[key] = more_options[key] size_fetcher = FileSizeFetcherThread(input_dict, i) self.threadPool[str(i)] = { 'thread': size_fetcher, 'item_id': i } self.parent.threadPool.append(size_fetcher) self.parent.threadPool[len(self.parent.threadPool) - 1].start() self.parent.threadPool[len(self.parent.threadPool) - 1].FOUND.connect( self.findFileSize) # Add current format to the related comboboxes if no_audio: self.no_audio_list.append(f) self.video_format_selection_comboBox.addItem(text) elif no_video: self.no_video_list.append(f) self.audio_format_selection_comboBox.addItem(text) else: self.video_audio_list.append(f) self.media_comboBox.addItem(text) i = i + 1 self.status_box_textEdit.hide() if 'duration' in media_dict.keys(): self.duration_label.setText( 'Duration ' + self.getReadableDuration(media_dict['duration'])) self.format_selection_frame.show() self.advanced_format_selection_checkBox.show() self.advanced_format_selection_frame.show() self.ok_pushButton.setEnabled(True) self.download_later_pushButton.setEnabled(True) # if we have no options for seperate audio and video, then hide advanced_format_selection... if len(self.no_audio_list) == 0 and len( self.no_video_list) == 0: self.advanced_format_selection_checkBox.hide() self.advanced_format_selection_frame.hide() # set index of comboboxes on best available quality. if len(self.no_audio_list) != 0 and len( self.no_video_list) != 0: self.media_comboBox.addItem('Best quality') self.media_comboBox.setCurrentIndex( len(self.video_audio_list)) elif len(self.video_audio_list) != 0: self.media_comboBox.setCurrentIndex( len(self.video_audio_list) - 1) if len(self.no_audio_list) != 0: self.video_format_selection_comboBox.setCurrentIndex( len(self.no_audio_list)) if len(self.no_video_list) != 0: self.audio_format_selection_comboBox.setCurrentIndex( len(self.no_video_list)) # if we have only audio or we have only video then hide media_comboBox if len(self.video_audio_list) == 0: self.media_comboBox.hide() self.select_format_label.hide() # only video if len(self.no_video_list) != 0 and len( self.no_audio_list) == 0: self.mediaSelectionChanged( 'video', int(self.video_format_selection_comboBox. currentIndex())) self.advanced_format_selection_checkBox.setChecked( True) self.advanced_format_selection_checkBox.hide() # only audio elif len(self.no_video_list) == 0 and len( self.no_audio_list) != 0: self.mediaSelectionChanged( 'audio', int(self.audio_format_selection_comboBox. currentIndex())) self.advanced_format_selection_checkBox.setChecked( True) self.advanced_format_selection_checkBox.hide() # audio and video else: self.mediaSelectionChanged( 'video_audio', int(self.media_comboBox.currentIndex())) except Exception as ex: logger.sendToLog(ex, "ERROR") def findFileSize(self, result): try: item_id = self.threadPool[str(result['thread_key'])]['item_id'] if result['file_size'] and result['file_size'] != '0': text = self.media_comboBox.itemText(item_id) self.media_comboBox.setItemText( item_id, '{} - {}'.format(text, result['file_size'])) except Exception as ex: logger.sendToLog(ex, "ERROR") def linkLineChangedHere(self, lineEdit): if str(lineEdit) == '': self.url_submit_pushButtontton.setEnabled(False) else: self.url_submit_pushButtontton.setEnabled(True) # This method collects additional information like proxy ip, user, password etc. def collectMoreOptions(self): options = { 'ip': None, 'port': None, 'proxy_user': None, 'proxy_passwd': None, 'download_user': None, 'download_passwd': None } if self.proxy_checkBox.isChecked(): options['ip'] = self.ip_lineEdit.text() options['port'] = self.port_spinBox.value() options['proxy_user'] = self.proxy_user_lineEdit.text() options['proxy_passwd'] = self.proxy_pass_lineEdit.text() if self.download_checkBox.isChecked(): options['download_user'] = self.download_user_lineEdit.text() options['download_passwd'] = self.download_pass_lineEdit.text() # These info (keys) are required for spider to find file size, because spider() does not check if key exists. additional_info = [ 'header', 'load_cookies', 'user_agent', 'referer', 'out' ] for i in additional_info: if i not in self.plugin_add_link_dictionary.keys(): options[i] = None return options # user commited information by pressing ok_pushButton, so get information # from VideoFinderAddLink window and return them to the mainwindow with callback! def okButtonPressed(self, button, download_later): link_list = [] # seperate audio format and video format is selected. if self.advanced_format_selection_checkBox.isChecked(): if self.video_format_selection_comboBox.currentText( ) == 'No video' and self.audio_format_selection_comboBox.currentText( ) != 'No audio': # only audio link must be added to the link_list audio_link = self.no_video_list[ self.audio_format_selection_comboBox.currentIndex() - 1]['url'] link_list.append(audio_link) elif self.video_format_selection_comboBox.currentText( ) != 'No video' and self.audio_format_selection_comboBox.currentText( ) == 'No audio': # only video link must be added to the link_list video_link = self.no_audio_list[ self.video_format_selection_comboBox.currentIndex() - 1]['url'] link_list.append(video_link) elif self.video_format_selection_comboBox.currentText( ) != 'No video' and self.audio_format_selection_comboBox.currentText( ) != 'No audio': # video and audio links must be added to the link_list audio_link = self.no_video_list[ self.audio_format_selection_comboBox.currentIndex() - 1]['url'] video_link = self.no_audio_list[ self.video_format_selection_comboBox.currentIndex() - 1]['url'] link_list = [video_link, audio_link] elif self.video_format_selection_comboBox.currentText( ) == 'No video' and self.audio_format_selection_comboBox.currentText( ) == 'No audio': # no video and no video selected! REALY?!. user is DRUNK! close the window! :)) self.close() else: if self.media_comboBox.currentText() == 'Best quality': # the last item in no_video_list and no_audio_list are the best. video_link = self.no_audio_list[-1]['url'] audio_link = self.no_video_list[-1]['url'] link_list = [video_link, audio_link] else: audio_and_video_link = self.video_audio_list[ self.media_comboBox.currentIndex()]['url'] link_list.append(audio_and_video_link) # write user's new inputs in persepolis_setting for next time :) self.persepolis_setting.setValue('add_link_initialization/ip', self.ip_lineEdit.text()) self.persepolis_setting.setValue('add_link_initialization/port', self.port_spinBox.value()) self.persepolis_setting.setValue('add_link_initialization/proxy_user', self.proxy_user_lineEdit.text()) self.persepolis_setting.setValue( 'add_link_initialization/download_user', self.download_user_lineEdit.text()) # get proxy information if not (self.proxy_checkBox.isChecked()): ip = None port = None proxy_user = None proxy_passwd = None else: ip = self.ip_lineEdit.text() if not (ip): ip = None port = self.port_spinBox.value() if not (port): port = None proxy_user = self.proxy_user_lineEdit.text() if not (proxy_user): proxy_user = None proxy_passwd = self.proxy_pass_lineEdit.text() if not (proxy_passwd): proxy_passwd = None # get download username and password information if not (self.download_checkBox.isChecked()): download_user = None download_passwd = None else: download_user = self.download_user_lineEdit.text() if not (download_user): download_user = None download_passwd = self.download_pass_lineEdit.text() if not (download_passwd): download_passwd = None # check that if user limits download speed. if not (self.limit_checkBox.isChecked()): limit = 0 else: if self.limit_comboBox.currentText() == "KiB/s": limit = str(self.limit_spinBox.value()) + str("K") else: limit = str(self.limit_spinBox.value()) + str("M") # get start time for download if user set that. if not (self.start_checkBox.isChecked()): start_time = None else: start_time = self.start_time_qDataTimeEdit.text() # get end time for download if user set that. if not (self.end_checkBox.isChecked()): end_time = None else: end_time = self.end_time_qDateTimeEdit.text() # set name for file(s) if self.change_name_checkBox.isChecked(): name = str(self.change_name_lineEdit.text()) if name == '': name = 'video_finder_file' else: name = 'video_finder_file' # video finder always finds extension # but if it can't find file extension # use mp4 for extension. if str(self.extension_label.text()) == '': extension = '.mp4' else: extension = str(self.extension_label.text()) # did user select seperate audio and video? if len(link_list) == 2: video_name = name + extension audio_name = name + '.' + \ str(self.no_video_list[self.audio_format_selection_comboBox.currentIndex() - 1]['ext']) name_list = [video_name, audio_name] else: name_list = [name + extension] # get number of connections connections = self.connections_spinBox.value() # get download_path download_path = self.download_folder_lineEdit.text() # referer if self.referer_lineEdit.text() != '': referer = self.referer_lineEdit.text() else: referer = None # header if self.header_lineEdit.text() != '': header = self.header_lineEdit.text() else: header = None # user_agent if self.user_agent_lineEdit.text() != '': user_agent = self.user_agent_lineEdit.text() else: user_agent = None # load_cookies if self.load_cookies_lineEdit.text() != '': load_cookies = self.load_cookies_lineEdit.text() else: load_cookies = None add_link_dictionary_list = [] if len(link_list) == 1: # save information in a dictionary(add_link_dictionary). add_link_dictionary = { 'referer': referer, 'header': header, 'user_agent': user_agent, 'load_cookies': load_cookies, 'out': name_list[0], 'start_time': start_time, 'end_time': end_time, 'link': link_list[0], 'ip': ip, 'port': port, 'proxy_user': proxy_user, 'proxy_passwd': proxy_passwd, 'download_user': download_user, 'download_passwd': download_passwd, 'connections': connections, 'limit_value': limit, 'download_path': download_path } add_link_dictionary_list.append(add_link_dictionary) else: video_add_link_dictionary = { 'referer': referer, 'header': header, 'user_agent': user_agent, 'load_cookies': load_cookies, 'out': name_list[0], 'start_time': start_time, 'end_time': end_time, 'link': link_list[0], 'ip': ip, 'port': port, 'proxy_user': proxy_user, 'proxy_passwd': proxy_passwd, 'download_user': download_user, 'download_passwd': download_passwd, 'connections': connections, 'limit_value': limit, 'download_path': download_path } audio_add_link_dictionary = { 'referer': referer, 'header': header, 'user_agent': user_agent, 'load_cookies': load_cookies, 'out': name_list[1], 'start_time': None, 'end_time': end_time, 'link': link_list[1], 'ip': ip, 'port': port, 'proxy_user': proxy_user, 'proxy_passwd': proxy_passwd, 'download_user': download_user, 'download_passwd': download_passwd, 'connections': connections, 'limit_value': limit, 'download_path': download_path } add_link_dictionary_list = [ video_add_link_dictionary, audio_add_link_dictionary ] # get category of download category = str(self.add_queue_comboBox.currentText()) del self.plugin_add_link_dictionary # return information to mainwindow self.callback(add_link_dictionary_list, download_later, category) # close window self.close()
class ActionBar(ui_tools.StyledBar): """ SIGNALS: @changeCurrent(PyQt_PyObject) @runFile(QString) @reopenTab(QString) @recentTabsModified() """ change_current = pyqtSignal('PyQt_PyObject', int) splitEditor = pyqtSignal(bool) runFile = pyqtSignal('QString') closeSplit = pyqtSignal() addToProject = pyqtSignal('QString') showFileInExplorer = pyqtSignal('QString') goToSymbol = pyqtSignal(int) undockEditor = pyqtSignal() reopenTab = pyqtSignal('QString') def __init__(self, main_combo=False): super(ActionBar, self).__init__() # self.setObjectName("actionbar") self.setProperty('gradient', True) hbox = QHBoxLayout(self) hbox.setContentsMargins(0, 0, 0, 0) hbox.setSpacing(0) # self.lbl_checks = QLabel('') # self.lbl_checks.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) # self.lbl_checks.setFixedWidth(48) # self.lbl_checks.setVisible(False) # hbox.addWidget(self.lbl_checks) # self.combo = ComboFiles() self.combo_files = QComboBox() self.combo_files.setProperty("border", True) # self.combo_files.setProperty("border_bottom", True) self.combo_files.setProperty("gradient", True) self.combo_files.setSizeAdjustPolicy( QComboBox.AdjustToMinimumContentsLengthWithIcon) # self.combo.setIconSize(QSize(16, 16)) # model = QStandardItemModel() # self.combo.setModel(model) # self.combo.view().setDragDropMode(QAbstractItemView.InternalMove) self.combo_files.setMaximumWidth(300) self.combo_files.currentIndexChanged[int].connect(self.current_changed) # self.combo.setObjectName("combotab") # self.connect(self.combo, SIGNAL("currentIndexChanged(int)"), # self.current_changed) self.combo_files.setToolTip(translations.TR_COMBO_FILE_TOOLTIP) self.combo_files.setContextMenuPolicy(Qt.CustomContextMenu) self.combo_files.customContextMenuRequested.connect( self._context_menu_requested) hbox.addWidget(self.combo_files) self.symbols_combo = QComboBox() # self.symbols_combo.setStyleSheet("QComboBox { combobox-popup: 0; }") self.symbols_combo.setProperty("border", True) # self.symbols_combo.setProperty("border_bottom", True) self.symbols_combo.setProperty("gradient", True) self.symbols_combo.setSizeAdjustPolicy( QComboBox.AdjustToMinimumContentsLengthWithIcon) # self.symbols_combo.setIconSize(QSize(16, 16)) self.symbols_combo.setObjectName("combo_symbols") self.symbols_combo.activated[int].connect(self.current_symbol_changed) # self.connect(self.symbols_combo, SIGNAL("activated(int)"), # self.current_symbol_changed) hbox.addWidget(self.symbols_combo) self.code_navigator = CodeNavigator() hbox.addWidget(self.code_navigator) # FIXME: set property for other themes self._pos_text = "Line: %d, Col: %d" # self.lbl_position = QLabel(self._pos_text % (0, 0)) # self._go_to_line_widget = go_to_line.GoToLine(self) # self.lbl_position = ui_tools.ClickeableLabel(self._pos_text % (0, 0)) self.lbl_position = QLabel() # self.lbl_position.setProperty("border_bottom", True) self.lbl_position.setProperty("gradient", True) self.lbl_position.setText(self._pos_text % (0, 0)) # self.lbl_position.setAutoFillBackground(True) # self.lbl_position.clicked.connect(self._on_lbl_position_clicked) # FIXME: falla con split. ARREGLADO margin = self.style().pixelMetric( QStyle.PM_LayoutHorizontalSpacing) / 2 self.lbl_position.setContentsMargins(margin, 0, margin, 0) self.lbl_position.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) hbox.addWidget(self.lbl_position) # self.btn_close = QPushButton( # self.style().standardIcon(QStyle.SP_DialogCloseButton), '') # self.btn_close.setIconSize(QSize(16, 16)) self.btn_close = QToolButton() # self.btn_close.setProperty("border_bottom", True) self.btn_close.setProperty("gradient", True) # self.btn_close.setAutoRaise(True) # self.btn_close.setFixedHeight(24) # self.btn_close.setIcon(QIcon(":img/close")) self.btn_close.setIcon( self.style().standardIcon(QStyle.SP_DialogCloseButton)) # ui_tools.colored_icon( # ":img/close", # NTheme.get_color('IconBaseColor'))) if main_combo: # self.btn_close.setObjectName('navigation_button') self.btn_close.setToolTip(translations.TR_CLOSE_FILE) self.btn_close.clicked.connect(self.about_to_close_file) # self.connect(self.btn_close, SIGNAL("clicked()"), # self.about_to_close_file) else: # self.btn_close.setObjectName('close_split') self.btn_close.setToolTip(translations.TR_CLOSE_SPLIT) self.btn_close.clicked.connect(self.close_split) # self.connect(self.btn_close, SIGNAL("clicked()"), # self.close_split) self.btn_close.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) hbox.addWidget(self.btn_close) # def _on_lbl_position_clicked(self): # main_container = IDE.get_service("main_container") # editor_widget = main_container.get_current_editor() # self._go_to_line_widget.set_line_count(editor_widget.line_count()) # self._go_to_line_widget.show() def resizeEvent(self, event): super(ActionBar, self).resizeEvent(event) if event.size().width() < 400: self.symbols_combo.hide() self.code_navigator.hide() self.lbl_position.hide() else: self.symbols_combo.show() self.code_navigator.show() self.lbl_position.show() def add_item(self, text, neditable): """Add a new item to the combo and add the neditable data.""" self.combo_files.addItem(text, neditable) self.combo_files.setCurrentIndex(self.combo_files.count() - 1) def get_editables(self): editables = [] for index in range(self.combo_files.count()): neditable = self.combo_files.itemData(index) editables.append(neditable) return editables def add_symbols(self, symbols): """Add the symbols to the symbols's combo.""" mo = Model(symbols) self.symbols_combo.setModel(mo) # self.symbols_combo.clear() # for symbol in symbols: # data = symbol[1] # if data[1] == 'f': # icon = QIcon(":img/function") # else: # icon = QIcon(":img/class") # self.symbols_combo.addItem(icon, data[0]) def set_current_symbol(self, index): self.symbols_combo.setCurrentIndex(index + 1) def update_item_icon(self, neditable, icon): index = self.combo_files.findData(neditable) self.combo_files.setItemIcon(index, icon) def update_item_text(self, neditable, text): index = self.combo_files.findData(neditable) self.combo_files.setItemText(index, text) def current_changed(self, index): """Change the current item in the combo.""" neditable = self.combo_files.itemData(index) self.change_current.emit(neditable, index) # self.emit(SIGNAL("changeCurrent(PyQt_PyObject, int)"), neditable, index) def current_symbol_changed(self, index): """Change the current symbol in the combo.""" if index == 0: return self.goToSymbol.emit(index - 1) def update_line_col(self, line, col): """Update the line and column position.""" self.lbl_position.setText(self._pos_text % (line, col)) def _context_menu_requested(self, point): """Display context menu for the combo file.""" if self.combo_files.count() == 0: # If there is not an Editor opened, don't show the menu return menu = QMenu() # actionAdd = menu.addAction(translations.TR_ADD_TO_PROJECT) # actionRun = menu.addAction(translations.TR_RUN_FILE) # menuSyntax = menu.addMenu(translations.TR_CHANGE_SYNTAX) show_folder = menu.addAction("Show Containing Folder") # self._create_menu_syntax(menuSyntax) menu.addSeparator() # actionClose = menu.addAction(translations.TR_CLOSE_FILE) # actionCloseAll = menu.addAction(translations.TR_CLOSE_ALL_FILES) # actionCloseAllNotThis = menu.addAction( # translations.TR_CLOSE_OTHER_FILES) # menu.addSeparator() # actionSplitH = menu.addAction(translations.TR_SPLIT_VERTICALLY) # actionSplitV = menu.addAction(translations.TR_SPLIT_HORIZONTALLY) # menu.addSeparator() # actionCopyPath = menu.addAction( # translations.TR_COPY_FILE_PATH_TO_CLIPBOARD) # actionShowFileInExplorer = menu.addAction( # translations.TR_SHOW_FILE_IN_EXPLORER) # actionReopen = menu.addAction(translations.TR_REOPEN_FILE) action_undock = menu.addAction(translations.TR_UNDOCK_EDITOR) # if len(settings.LAST_OPENED_FILES) == 0: # actionReopen.setEnabled(False) # Connect actions action_undock.triggered.connect(self._undock_editor) show_folder.triggered.connect(self._show_containing_folder) # self.connect(actionSplitH, SIGNAL("triggered()"), # lambda: self._split(False)) # self.connect(actionSplitV, SIGNAL("triggered()"), # lambda: self._split(True)) # self.connect(actionRun, SIGNAL("triggered()"), # self._run_this_file) # self.connect(actionAdd, SIGNAL("triggered()"), # self._add_to_project) # self.connect(actionClose, SIGNAL("triggered()"), # self.about_to_close_file) # self.connect(actionCloseAllNotThis, SIGNAL("triggered()"), # self._close_all_files_except_this) # self.connect(actionCloseAll, SIGNAL("triggered()"), # self._close_all_files) # self.connect(actionCopyPath, SIGNAL("triggered()"), # self._copy_file_location) # self.connect(actionShowFileInExplorer, SIGNAL("triggered()"), # self._show_file_in_explorer) # self.connect(actionReopen, SIGNAL("triggered()"), # self._reopen_last_tab) # self.connect(actionUndock, SIGNAL("triggered()"), # self._undock_editor) menu.exec_(QCursor.pos()) def _show_containing_folder(self): # FIXME: mover y cross platform main_container = IDE.get_service("main_container") editor_widget = main_container.get_current_editor() filename = editor_widget.file_path import subprocess from ninja_ide.core.file_handling import file_manager folder = file_manager.get_folder(filename) subprocess.call(["xdg-open", folder]) def _create_menu_syntax(self, menuSyntax): """Create Menu with the list of syntax supported.""" syntax = list(settings.SYNTAX.keys()) syntax.sort() for syn in syntax: menuSyntax.addAction(syn) # self.connect(menuSyntax, SIGNAL("triggered(QAction*)"), # self._reapply_syntax) def _reapply_syntax(self, syntaxAction): # TODO if [self.currentIndex(), syntaxAction] != self._resyntax: self._resyntax = [self.currentIndex(), syntaxAction] # self.emit(SIGNAL("syntaxChanged(QWidget, QString)"), # self.currentWidget(), syntaxAction.text()) def set_current_file(self, neditable): index = self.combo_files.findData(neditable) self.combo_files.setCurrentIndex(index) def set_current_by_index(self, index): self.combo_files.setCurrentIndex(index) @pyqtSlot() def about_to_close_file(self, index=None): """Close the NFile object.""" if index is None: index = self.combo_files.currentIndex() neditable = self.combo_files.itemData(index) if neditable: neditable.nfile.close() def close_split(self): self.closeSplit.emit() # self.emit(SIGNAL("closeSplit()")) def close_file(self, neditable): """Receive the confirmation to close the file.""" index = self.combo_files.findData(neditable) self.combo_files.removeItem(index) return index def _run_this_file(self): """Execute the current file.""" neditable = self.combo.itemData(self.combo.currentIndex()) print("Emitir runFile") # self.emit(SIGNAL("runFile(QString)"), neditable.file_path) def _add_to_project(self): """Emit a signal to let someone handle the inclusion of the file inside a project.""" neditable = self.combo.itemData(self.combo.currentIndex()) print("Emitir adToProject") # self.emit(SIGNAL("addToProject(QString)"), neditable.file_path) def _show_file_in_explorer(self): '''Triggered when the "Show File in Explorer" context menu action is selected. Emits the "showFileInExplorer(QString)" signal with the current file's full path as argument.''' neditable = self.combo.itemData(self.combo.currentIndex()) print("Emitir showFileInExplorer") # self.emit(SIGNAL("showFileInExplorer(QString)"), neditable.file_path) def _reopen_last_tab(self): print("Emitir reopenTab y recentTabsModified") # self.emit(SIGNAL("reopenTab(QString)"), # settings.LAST_OPENED_FILES.pop()) # self.emit(SIGNAL("recentTabsModified()")) def _undock_editor(self): self.undockEditor.emit() def _split(self, orientation): print("emitir splitEditor") # self.emit(SIGNAL("splitEditor(bool)"), orientation) def _copy_file_location(self): """Copy the path of the current opened file to the clipboard.""" neditable = self.combo.itemData(self.combo.currentIndex()) QApplication.clipboard().setText(neditable.file_path, QClipboard.Clipboard) def _close_all_files(self): """Close all the files opened.""" for i in range(self.combo.count()): self.about_to_close_file(0) def _close_all_files_except_this(self): """Close all the files except the current one.""" neditable = self.combo.itemData(self.combo.currentIndex()) for i in reversed(list(range(self.combo.count()))): ne = self.combo.itemData(i) if ne is not neditable: self.about_to_close_file(i)
class LaserRangeFinder(PluginBase): def __init__(self, *args): super().__init__(BrickletLaserRangeFinder, *args) self.lrf = self.device # the firmware version of a EEPROM Bricklet can (under common circumstances) # not change during the lifetime of an EEPROM Bricklet plugin. therefore, # it's okay to make final decisions based on it here self.has_sensor_hardware_version_api = self.firmware_version >= (2, 0, 3) self.has_configuration_api = self.firmware_version >= (2, 0, 3) self.cbe_distance = CallbackEmulator(self.lrf.get_distance, None, self.cb_distance, self.increase_error_count) self.cbe_velocity = CallbackEmulator(self.lrf.get_velocity, None, self.cb_velocity, self.increase_error_count) self.current_distance = CurveValueWrapper() # int, cm self.current_velocity = CurveValueWrapper() # float, m/s plots_distance = [('Distance', Qt.red, self.current_distance, format_distance)] plots_velocity = [('Velocity', Qt.red, self.current_velocity, '{:.2f} m/s'.format)] self.plot_widget_distance = PlotWidget('Distance [cm]', plots_distance, y_resolution=1.0) self.plot_widget_velocity = PlotWidget('Velocity [m/s]', plots_velocity, y_resolution=0.01) self.mode_label = QLabel('Mode:') self.mode_combo = QComboBox() self.mode_combo.addItem("Distance: 1cm resolution, 40m max") self.mode_combo.addItem("Velocity: 0.10 m/s resolution, 12.70m/s max") self.mode_combo.addItem("Velocity: 0.25 m/s resolution, 31.75m/s max") self.mode_combo.addItem("Velocity: 0.50 m/s resolution, 63.50m/s max") self.mode_combo.addItem("Velocity: 1.00 m/s resolution, 127.00m/s max") self.mode_combo.currentIndexChanged.connect(self.mode_changed) self.mode_combo.hide() self.label_average_distance = QLabel('Moving Average for Distance:') self.spin_average_distance = QSpinBox() self.spin_average_distance.setMinimum(0) self.spin_average_distance.setMaximum(50) self.spin_average_distance.setSingleStep(1) self.spin_average_distance.setValue(10) self.spin_average_distance.editingFinished.connect(self.spin_average_finished) self.label_average_velocity = QLabel('Moving Average for Velocity:') self.spin_average_velocity = QSpinBox() self.spin_average_velocity.setMinimum(0) self.spin_average_velocity.setMaximum(50) self.spin_average_velocity.setSingleStep(1) self.spin_average_velocity.setValue(10) self.spin_average_velocity.editingFinished.connect(self.spin_average_finished) self.enable_laser = QCheckBox("Enable Laser") self.enable_laser.stateChanged.connect(self.enable_laser_changed) self.label_acquisition_count = QLabel('Acquisition Count:') self.spin_acquisition_count = QSpinBox() self.spin_acquisition_count.setMinimum(1) self.spin_acquisition_count.setMaximum(255) self.spin_acquisition_count.setSingleStep(1) self.spin_acquisition_count.setValue(128) self.enable_qick_termination = QCheckBox("Quick Termination") self.label_threshold = QLabel('Threshold:') self.threshold = QCheckBox("Automatic Threshold") self.spin_threshold = QSpinBox() self.spin_threshold.setMinimum(1) self.spin_threshold.setMaximum(255) self.spin_threshold.setSingleStep(1) self.spin_threshold.setValue(1) self.label_frequency = QLabel('Frequency [Hz]:') self.frequency = QCheckBox("Automatic Frequency (Disable for Velocity)") self.spin_frequency = QSpinBox() self.spin_frequency.setMinimum(10) self.spin_frequency.setMaximum(500) self.spin_frequency.setSingleStep(1) self.spin_frequency.setValue(10) self.spin_acquisition_count.editingFinished.connect(self.configuration_changed) self.enable_qick_termination.stateChanged.connect(self.configuration_changed) self.spin_threshold.editingFinished.connect(self.configuration_changed) self.threshold.stateChanged.connect(self.configuration_changed) self.spin_frequency.editingFinished.connect(self.configuration_changed) self.frequency.stateChanged.connect(self.configuration_changed) layout_h1 = QHBoxLayout() layout_h1.addWidget(self.plot_widget_distance) layout_h1.addWidget(self.plot_widget_velocity) layout_h2 = QHBoxLayout() layout_h2.addWidget(self.mode_label) layout_h2.addWidget(self.mode_combo) layout_h2.addWidget(self.label_average_distance) layout_h2.addWidget(self.spin_average_distance) layout_h2.addWidget(self.label_average_velocity) layout_h2.addWidget(self.spin_average_velocity) layout_h2.addStretch() layout_h2.addWidget(self.enable_laser) layout_h3 = QHBoxLayout() layout_h3.addWidget(self.label_frequency) layout_h3.addWidget(self.spin_frequency) layout_h3.addWidget(self.frequency) layout_h3.addStretch() layout_h3.addWidget(self.enable_qick_termination) layout_h4 = QHBoxLayout() layout_h4.addWidget(self.label_threshold) layout_h4.addWidget(self.spin_threshold) layout_h4.addWidget(self.threshold) layout_h4.addStretch() layout_h4.addWidget(self.label_acquisition_count) layout_h4.addWidget(self.spin_acquisition_count) self.widgets_distance = [self.plot_widget_distance, self.spin_average_distance, self.label_average_distance] self.widgets_velocity = [self.plot_widget_velocity, self.spin_average_velocity, self.label_average_velocity] for w in self.widgets_distance: w.hide() for w in self.widgets_velocity: w.hide() line = QFrame() line.setObjectName("line") line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) layout = QVBoxLayout(self) layout.addLayout(layout_h1) layout.addWidget(line) layout.addLayout(layout_h2) layout.addLayout(layout_h3) layout.addLayout(layout_h4) def start(self): if self.has_sensor_hardware_version_api: async_call(self.lrf.get_sensor_hardware_version, None, self.get_sensor_hardware_version_async, self.increase_error_count) else: self.get_sensor_hardware_version_async(1) if self.has_configuration_api: async_call(self.lrf.get_configuration, None, self.get_configuration_async, self.increase_error_count) async_call(self.lrf.get_mode, None, self.get_mode_async, self.increase_error_count) async_call(self.lrf.is_laser_enabled, None, self.enable_laser.setChecked, self.increase_error_count) async_call(self.lrf.get_moving_average, None, self.get_moving_average_async, self.increase_error_count) self.cbe_distance.set_period(25) self.cbe_velocity.set_period(25) self.plot_widget_distance.stop = False self.plot_widget_velocity.stop = False def stop(self): self.cbe_distance.set_period(0) self.cbe_velocity.set_period(0) self.plot_widget_distance.stop = True self.plot_widget_velocity.stop = True def destroy(self): pass @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickletLaserRangeFinder.DEVICE_IDENTIFIER def enable_laser_changed(self, state): if state == Qt.Checked: self.lrf.enable_laser() else: self.lrf.disable_laser() def mode_changed(self, value): if value < 0 or value > 4: return self.lrf.set_mode(value) if value == 0: for w in self.widgets_velocity: w.hide() for w in self.widgets_distance: w.show() else: for w in self.widgets_distance: w.hide() for w in self.widgets_velocity: w.show() def cb_distance(self, distance): self.current_distance.value = distance def cb_velocity(self, velocity): self.current_velocity.value = velocity / 100.0 def configuration_changed(self): acquisition_count = self.spin_acquisition_count.value() enable_quick_termination = self.enable_qick_termination.isChecked() if self.threshold.isChecked(): threshold = 0 else: threshold = self.spin_threshold.value() if self.frequency.isChecked(): frequency = 0 for w in self.widgets_velocity: w.hide() else: frequency = self.spin_frequency.value() for w in self.widgets_velocity: w.show() self.spin_threshold.setDisabled(threshold == 0) self.spin_frequency.setDisabled(frequency == 0) self.lrf.set_configuration(acquisition_count, enable_quick_termination, threshold, frequency) def get_configuration_async(self, conf): self.spin_acquisition_count.blockSignals(True) self.spin_acquisition_count.setValue(conf.acquisition_count) self.spin_acquisition_count.blockSignals(False) self.enable_qick_termination.blockSignals(True) self.enable_qick_termination.setChecked(conf.enable_quick_termination) self.enable_qick_termination.blockSignals(False) self.spin_threshold.blockSignals(True) self.spin_threshold.setValue(conf.threshold_value) self.spin_threshold.setDisabled(conf.threshold_value == 0) self.spin_threshold.blockSignals(False) self.spin_frequency.blockSignals(True) self.spin_frequency.setValue(conf.measurement_frequency) self.spin_frequency.setDisabled(conf.measurement_frequency == 0) self.spin_frequency.blockSignals(False) self.threshold.blockSignals(True) self.threshold.setChecked(conf.threshold_value == 0) self.threshold.blockSignals(False) self.frequency.blockSignals(True) self.frequency.setChecked(conf.measurement_frequency == 0) self.frequency.blockSignals(False) self.configuration_changed() def get_sensor_hardware_version_async(self, value): if value == 1: self.mode_combo.show() self.mode_label.show() self.label_acquisition_count.hide() self.spin_acquisition_count.hide() self.enable_qick_termination.hide() self.label_threshold.hide() self.spin_threshold.hide() self.threshold.hide() self.label_frequency.hide() self.spin_frequency.hide() self.frequency.hide() else: self.mode_combo.hide() self.mode_label.hide() self.label_acquisition_count.show() self.spin_acquisition_count.show() self.enable_qick_termination.show() self.label_threshold.show() self.spin_threshold.show() self.threshold.show() self.label_frequency.show() self.spin_frequency.show() self.frequency.show() for w in self.widgets_distance: w.show() for w in self.widgets_velocity: w.show() def get_mode_async(self, value): self.mode_combo.setCurrentIndex(value) self.mode_changed(value) def get_moving_average_async(self, avg): self.spin_average_distance.setValue(avg.distance_average_length) self.spin_average_velocity.setValue(avg.velocity_average_length) def spin_average_finished(self): self.lrf.set_moving_average(self.spin_average_distance.value(), self.spin_average_velocity.value())
class Layout(QMainWindow): def __init__(self): super().__init__() self.pos = conf.position self.res = conf.resize self.statusText = 'Kullanıma Hazır !' self.initUI() def setURL(self,code): if len(code) == 11 : return conf.app.youTube_host + code def codeURL(self,url): url_data = urllib.parse.urlparse(url) query = urllib.parse.parse_qs(url_data.query) if len(query["v"][0]) and len(query["v"][0]) == 11 : return self.setURL(query["v"][0]) return False def getSearch(self): searchTerm = self.searchBox.text() self.searchBtn.setDisabled(True) if len(searchTerm) == 0 : print('Temizlendi') self.infoClear() elif len(searchTerm) != 0 and self.searchBtn.isEnabled() == False : self.searchBtn.setDisabled(False) if len(searchTerm) == 11 : code = self.setURL(searchTerm) self.getVideo(code) elif len(searchTerm) == 43 : code = self.codeURL(searchTerm) if code == False : self.statusBar().showMessage('Lütfen geçerli bir Youtube bağlantısı yada Video kodu girin !') self.getVideo(code) elif len(searchTerm) == 83 : code = self.codeURL(searchTerm) if code == False : self.statusBar().showMessage('Lütfen geçerli bir Youtube bağlantısı yada Video kodu girin !') self.getVideo(code) else : self.statusBar().showMessage('Lütfen geçerli bir Youtube bağlantısı yada Video kodu girin !') def getVideo(self,code): self.setDisabled(True) self.statusBar().showMessage('Yükleniyor !') self.yt = YouTube(code) videos = self.yt.get_videos() quality = ['Kalite'] for v in videos : if v.extension == 'mp4' : quality.append( v.resolution) quality = sorted(set(quality),reverse=True) self.quality.clear() self.quality.addItems(quality) self.quality.model().item(0).setEnabled(False) self.quality.show() self.filename = self.yt.filename self.info.setText(self.yt.filename) self.downloadBtn.show() self.statusBar().showMessage('Yüklendi !') self.setDisabled(False) def infoClear(self): self.downloadBtn.setDisabled(True) self.quality.clear() self.quality.hide() self.info.clear() self.downloadBtn.setDisabled(True) self.downloadBtn.hide() def searchChange(self): searchTerm = self.searchBox.text() if len(searchTerm) == 0 : self.infoClear() self.searchBtn.setDisabled(True) self.searchBtn.setDisabled(True) self.statusBar().showMessage(self.statusText) elif len(searchTerm) != 0 : self.statusBar().showMessage('Kullanıma Hazır !') self.searchBtn.setDisabled(False) def toolBarButtons(self): # Search Button self.searchBtn = QPushButton(conf.app.toolBar.searchBtn.title,self) self.searchBtn.clicked.connect(self.getSearch) self.searchBtn.setDisabled(True) self.searchBtn.move(conf.app.toolBar.searchBtn.pos.x,conf.app.toolBar.searchBtn.pos.y) # Download Button # downloadBtn = QPushButton(conf.app.toolBar.downloadBtn.title,self) # downloadBtn.move(conf.app.toolBar.downloadBtn.pos.x,conf.app.toolBar.downloadBtn.pos.y) def toolBar(self): self.toolBarButtons() self.searchBox = QLineEdit(self) self.searchBox.setFocus(True) self.searchBox.setFixedSize(conf.app.toolBar.searchBox.size.w,conf.app.toolBar.searchBox.size.h) self.searchBox.setClearButtonEnabled(True) self.searchBox.returnPressed.connect(self.searchChange) self.searchBox.textEdited.connect(self.searchChange) self.searchBox.setPlaceholderText(conf.app.toolBar.searchBox.placeholder) self.searchBox.move(conf.app.toolBar.searchBox.pos.x,conf.app.toolBar.searchBox.pos.y) def setStatusBar(self): self.statusBar().showMessage(self.statusText) # self.downloadBtn.setDisabled(False) def selectedQuality(self,text): infoText = self.filename self.info.setText(infoText + ' ' + text) self.downloadBtn.setDisabled(False) def disabledAll(self): self.setDisabled(True) def enableAll(self): self.setEnabled(True) def completed(self,path): self.enableAll() self.statusBar().showMessage(conf.app.download_dir + self.filename + '.mp4 indirildi !') self.infoClear() self.searchBtn.setDisabled(True) self.searchBox.clear() self.searchBox.setFocus(True) def downloadVideo(self): self.disabledAll() self.statusBar().showMessage('İndiriliyor...!') if self.isEnabled() == False : video = self.yt.get(conf.app.video.type,self.quality.currentText()) sleep(5) video.download(path=conf.app.download_dir,force_overwrite=True,on_finish=self.completed) def initUI(self): self.toolBar() self.setStatusBar() self.info = QLabel(self) self.info.move(120,50) self.info.setMinimumWidth(450) self.quality = QComboBox(self) self.quality.move(120,80) self.quality.hide() self.quality.activated[str].connect(self.selectedQuality) self.downloadBtn = QPushButton('İndir',self) self.downloadBtn.move(250,80) self.downloadBtn.setDisabled(True) self.downloadBtn.hide() self.downloadBtn.clicked.connect(self.downloadVideo) self.setGeometry(self.pos.x,self.pos.y,self.res.w,self.res.h) self.setMaximumSize(self.res.w,self.res.h) self.setMinimumSize(self.res.w,self.res.h) self.setWindowTitle(conf.app.title + " - " + conf.app.version) self.show()
class Window(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.lineinp = QLineEdit(self) self.lineinp.setPlaceholderText("Enter the site's URL here") self.boxinp = QComboBox(self) self.boxinp.addItems(['LiveLib', 'ReadRate', 'Libs', 'Readly']) self.prsbtn = QPushButton('Parse!', self) self.prsbtn.clicked.connect(self.prsbuttonClicked) self.wtfbtn = QPushButton('WTF', self) self.wtfbtn.clicked.connect(self.wtfbuttonClicked) self.datalist = QListWidget(self) self.msgbox = QMessageBox() self.msgbtn = QPushButton('Попробовать снова') self.msgbox.addButton(self.msgbtn, QMessageBox.DestructiveRole) self.msgbox.setWindowTitle('Ой, что-то не так') self.msgbox.setWindowIcon(QIcon('sad.png')) self.center(self.msgbox) grid = QGridLayout() grid.addWidget(self.lineinp, 1, 0, 1, 2) grid.addWidget(self.boxinp, 2, 0, 1, 2) grid.addWidget(self.prsbtn, 3, 0) grid.addWidget(self.wtfbtn, 3, 1) grid.addWidget(self.datalist, 4, 0, 4, 2) self.setLayout(grid) self.boxinp.hide() self.resize(600, 600) self.center(self) self.setWindowTitle('My big fully-functional parser') self.setWindowIcon(QIcon('www.png')) self.show() def center(self, obj): qr = obj.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft()) def wtfbuttonClicked(self): if self.boxinp.isVisible(): self.boxinp.hide() self.lineinp.show() else: self.boxinp.show() self.lineinp.hide() def prsbuttonClicked(self): self.datalist.clear() if self.lineinp.isVisible(): self.setTopByLine() else: self.setTopByBox() def connection_try(self, currentsite): try: data = currentsite.get_books_list() except requests.exceptions.ConnectionError: self.msgbox.setText('Ошибка сети') self.msgbox.setInformativeText('Проверьте подключение к интернету') self.msgbox.show() else: self.datalist.addItems(data) def setTopByBox(self): sitename = self.boxinp.currentText() currentsite = backend.sites[sitename] self.connection_try(currentsite) # На самом деле очевидно, что данный парсер с его архитектурой # весьма глупо реализовывать через ввод URL # данная возможность предусмотренна исключетельно ради примера использования QLineEdit def setTopByLine(self): siteurl = self.lineinp.text() if siteurl in backend.urls: currentsite = backend.urls[siteurl] self.connection_try(currentsite) else: self.msgbox.setText('Что такое?') self.msgbox.setInformativeText('Введите нормальный URL') self.msgbtn.clicked.connect(lambda: self.prsbtn.setText('Исправил, проверяйте')) self.msgbox.show()
class SongsTableToolbar(QWidget): play_all_needed = pyqtSignal() filter_albums_needed = pyqtSignal([list]) filter_text_changed = pyqtSignal([str]) def __init__(self, parent=None): super().__init__(parent) self._tmp_buttons = [] self.play_all_btn = TextButton('播放全部', self) self.play_all_btn.clicked.connect(self.play_all_needed.emit) self.play_all_btn.setObjectName('play_all') # album filters self.filter_albums_combobox = QComboBox(self) self.filter_albums_combobox.addItems( ['所有专辑', '标准', '单曲与EP', '现场', '合辑']) self.filter_albums_combobox.currentIndexChanged.connect( self.on_albums_filter_changed) # 8 works on macOS, don't know if it works on various Linux DEs self.filter_albums_combobox.setMinimumContentsLength(8) self.filter_albums_combobox.hide() self._setup_ui() def albums_mode(self): self._before_change_mode() self.filter_albums_combobox.show() def songs_mode(self): self._before_change_mode() self.play_all_btn.show() def artists_mode(self): self._before_change_mode() def enter_state_playall_start(self): self.play_all_btn.setEnabled(False) # currently, this is called only when feeluown is fetching songs, # so when we enter state_playall_start, we set play all btn text # to this. self.play_all_btn.setText('获取所有歌曲...') def enter_state_playall_end(self): self.play_all_btn.setText('获取所有歌曲...done') self.play_all_btn.setEnabled(True) self.play_all_btn.setText('播放全部') def add_tmp_button(self, button): """Append text button""" if button not in self._tmp_buttons: # FIXME(cosven): the button inserted isn't aligned with other buttons self._layout.insertWidget(len(self._tmp_buttons) + 1, button) self._tmp_buttons.append(button) def _setup_ui(self): self._layout = QHBoxLayout(self) # left margin of meta widget is 30, we align with it # bottom margin of meta widget is 15, we should be larger than that self._layout.setContentsMargins(30, 15, 30, 10) self._layout.addWidget(self.play_all_btn) self._layout.addStretch(0) self._layout.addWidget(self.filter_albums_combobox) def _before_change_mode(self): """filter all filter buttons""" for button in self._tmp_buttons: self._layout.removeWidget(button) button.close() self._tmp_buttons.clear() self.filter_albums_combobox.hide() self.play_all_btn.hide() def on_albums_filter_changed(self, index): # ['所有', '专辑', '单曲与EP', '现场', '合辑'] if index == 0: types = [] elif index == 1: types = [AlbumType.standard] elif index == 2: types = [AlbumType.single, AlbumType.ep] elif index == 3: types = [AlbumType.live] else: types = [AlbumType.compilation, AlbumType.retrospective] self.filter_albums_needed.emit(types)
class MainWindow(QWidget): """ This class contain the GUI and the functions for the Main window \n and uses all the other classes.""" def __init__(self): super(MainWindow, self).__init__() """Overall layout of the main window.""" self.setWindowTitle('Plot segmentation') self.resize(self.sizeHint()) ## initialization self.field_image = None self.displaySize = 400 self.threshold = 0.20 self.noise = 200 self.pix4D = None self.rawImgFold = None ## definition self.text_intro = QLabel('LOAD FIELD IMAGE') self.text_intro.setAlignment(Qt.AlignCenter) self.text_screenSize = QLabel('Select your screen resolution:') self.text_screenSize2 = QLabel('(If the size is not in the list, please choose a smaller size.)') self.comboBox_screenSize = QComboBox() self.comboBox_screenSize.addItem('1024 x 640 pixels') self.comboBox_screenSize.addItem('1280 x 800 pixels') self.comboBox_screenSize.addItem('1440 x 900 pixels') self.comboBox_screenSize.addItem('1680 x 1050 pixels') self.comboBox_screenSize.addItem('2048 x 1152 pixels') self.comboBox_screenSize.addItem('2560 x 1140 pixels') self.comboBox_screenSize.addItem('3200 x 1800 pixels') self.text_fieldImage = QLabel('Choose the field image: ') self.button_fieldImage = QPushButton('Choose') self.text_image = QLabel('Image chosen:') self.text_imagePath = QLabel(str(self.field_image)) self.button_drawField = QPushButton('Draw field shape') self.button_getBinary = QPushButton('Convert to binary') self.check_binary = QCheckBox('Check this if the chosen image is already a binary') self.text_threshold = QLabel('ExG threshold to create binary:') self.text_threshold2 = QLabel('0.20 usually works. Set to 1.00 for automatic.') self.spinbox_threshold = QDoubleSpinBox() self.spinbox_threshold.setRange(0.00, 1.00) self.spinbox_threshold.setSingleStep(0.05) self.spinbox_threshold.setValue(0.20) self.text_noise = QLabel('Minimum feature size for noise removal (px):') self.spinbox_noise = QSpinBox() self.spinbox_noise.setRange(1, 10000) self.spinbox_noise.setValue(200) self.text_plot = QLabel('PLOT PARAMETERS') self.text_plot.setAlignment(Qt.AlignCenter) self.text_nbOfRowPerPlot = QLabel('Number of plant rows per plot:') self.spinbox_nbOfRowPerPlot = QSpinBox() self.spinbox_nbOfRowPerPlot.setRange(1, 100) self.spinbox_nbOfRowPerPlot.setSingleStep(1) self.spinbox_nbOfRowPerPlot.setValue(1) self.text_nbOfColumnPerPlot = QLabel('Number of ranges per plot:') self.spinbox_nbOfColumnPerPlot = QSpinBox() self.spinbox_nbOfColumnPerPlot.setRange(1, 100) self.spinbox_nbOfColumnPerPlot.setSingleStep(1) self.spinbox_nbOfColumnPerPlot.setValue(1) self.text_plotArrangment = QLabel('Global orientation of the ranges:') self.radio_horizontal = QRadioButton('Horizontal\t\t\t') self.radio_horizontal.setChecked(True) self.radio_vertical = QRadioButton('Vertical') self.radio_vertical.setChecked(False) self.button_apply = QPushButton('Identify plots') self.text_intro_revCal = QLabel('CALCULATE PLOT COORDINATES IN RAW IMAGES') self.text_intro_revCal.setAlignment(Qt.AlignCenter) self.text_pix4D = QLabel('Pix4D project folder:') self.button_pix4D = QPushButton('Choose') self.text_rawImgFold = QLabel('Raw images folder:') self.button_rawImgFold = QPushButton('Choose') self.button_apply_revCal = QPushButton('Apply') ## connections self.button_fieldImage.clicked.connect(self.fieldImage_clicked) self.button_drawField.clicked.connect(self.drawField_clicked) self.comboBox_screenSize.activated.connect(self.ScreenSizeFunction) self.button_getBinary.clicked.connect(self.getBinary_clicked) self.button_apply.clicked.connect(self.application) self.button_pix4D.clicked.connect(self.button_pix4D_clicked) self.button_rawImgFold.clicked.connect(self.button_rawImgFold_clicked) self.button_apply_revCal.clicked.connect(self.button_apply_revCal_clicked) ## options self.text_screenSize.hide() self.text_screenSize2.hide() self.comboBox_screenSize.hide() self.check_binary.hide() self.text_threshold.hide() self.text_threshold2.hide() self.spinbox_threshold.hide() self.text_noise.hide() self.spinbox_noise.hide() self.button_drawField.hide() self.text_imagePath.hide() self.text_image.hide() self.text_plot.hide() self.button_getBinary.hide() self.text_nbOfColumnPerPlot.hide() self.spinbox_nbOfColumnPerPlot.hide() self.text_nbOfRowPerPlot.hide() self.spinbox_nbOfRowPerPlot.hide() self.button_apply.hide() self.text_plotArrangment.hide() self.radio_horizontal.hide() self.radio_vertical.hide() self.text_intro_revCal.hide() self.text_pix4D.hide() self.button_pix4D.hide() self.text_rawImgFold.hide() self.button_rawImgFold.hide() self.button_apply_revCal.hide() ## layout self.layout = QGridLayout() self.layout.addWidget(self.text_intro, 1, 0, 1, -1) self.layout.addWidget(self.text_fieldImage, 2, 0) self.layout.addWidget(self.button_fieldImage, 2, 1, 1, -1) self.layout.addWidget(self.text_image, 3, 0) self.layout.addWidget(self.text_imagePath, 3, 1, 1, -1) self.layout.addWidget(self.check_binary, 4, 1, 1, -1) self.layout.addWidget(self.text_noise, 5, 0) self.layout.addWidget(self.spinbox_noise, 5, 1) self.layout.addWidget(self.text_screenSize, 6, 0) self.layout.addWidget(self.comboBox_screenSize, 6, 1) self.layout.addWidget(self.text_screenSize2, 6, 2, 1, 3) self.layout.addWidget(self.button_drawField, 7, 0, 1, -1) self.layout.addWidget(self.text_threshold, 8, 0) self.layout.addWidget(self.spinbox_threshold, 8, 1) self.layout.addWidget(self.text_threshold2, 8, 2, 1, -1) self.layout.addWidget(self.button_getBinary, 9, 0, 1, -1) self.layout.addWidget(self.text_plot,10, 0, 1, -1) self.layout.addWidget(self.text_nbOfRowPerPlot, 11, 0) self.layout.addWidget(self.spinbox_nbOfRowPerPlot, 11, 1, 1, -1) self.layout.addWidget(self.text_nbOfColumnPerPlot, 12, 0) self.layout.addWidget(self.spinbox_nbOfColumnPerPlot, 12, 1, 1, -1) self.layout.addWidget(self.text_plotArrangment, 13, 0) self.layout.addWidget(self.radio_horizontal, 13, 1) self.layout.addWidget(self.radio_vertical, 13, 2) self.layout.addWidget(self.button_apply, 14, 0, 1, -1) self.layout.addWidget(self.text_intro_revCal, 15, 0, 1, -1) self.layout.addWidget(self.text_pix4D, 16, 0) self.layout.addWidget(self.button_pix4D, 16, 1, 1, -1) self.layout.addWidget(self.text_rawImgFold, 17, 0) self.layout.addWidget(self.button_rawImgFold, 17, 1, 1, -1) self.layout.addWidget(self.button_apply_revCal, 18, 0, 1, -1) self.setLayout(self.layout) self.show() def ScreenSizeFunction(self): """ This function is part of the class 'MainWindow'. \n It is linked to the change of the combo box self.comboBox_screenSize \n It decides the maximum size for the display of pictures depending on the inputted size of the screen """ if self.comboBox_screenSize.currentText() == '1024 x 640 pixels': self.displaySize = 600 if self.comboBox_screenSize.currentText() == '1280 x 800 pixels': self.displaySize = 800 if self.comboBox_screenSize.currentText() == '1440 x 900 pixels': self.displaySize = 900 if self.comboBox_screenSize.currentText() == '1680 x 1050 pixels': self.displaySize = 1000 if self.comboBox_screenSize.currentText() == '2048 x 1152 pixels': self.displaySize = 1100 if self.comboBox_screenSize.currentText() == '2560 x 1140 pixels': self.displaySize = 1100 if self.comboBox_screenSize.currentText() == '3200 x 1800 pixels': self.displaySize = 1700 def fieldImage_clicked(self): """ This function is part of the class 'MainWindow' \n It is connected to the button button_fieldImage and allows the user to chose the image of the whole field on which all the program is based""" self.field_image, _ = QFileDialog.getOpenFileName(self, "Select the field image", "",".tif or .tiff or .jpg or .jpeg or .png (*.tif *.tiff *.TIF *.TIFF *.jpg *.jpeg *.JPG *.JPEG *.PNG *.png)", options=QFileDialog.DontUseNativeDialog) self.field_image = Path(self.field_image) self.text_imagePath.setText(str(self.field_image)) if self.field_image.is_file(): self.check_binary.show() self.text_noise.show() self.spinbox_noise.show() self.text_imagePath.show() self.text_image.show() self.text_screenSize.show() self.text_screenSize2.show() self.comboBox_screenSize.show() self.button_drawField.show() else: self.check_binary.hide() self.text_noise.hide() self.spinbox_noise.hide() self.text_imagePath.hide() self.text_image.hide() self.text_screenSize.hide() self.text_screenSize2.hide() self.comboBox_screenSize.hide() self.button_drawField.hide() self.coord = [] self.text_threshold.hide() self.text_threshold2.hide() self.spinbox_threshold.hide() self.button_getBinary.hide() self.text_plot.hide() self.text_nbOfRowPerPlot.hide() self.spinbox_nbOfRowPerPlot.hide() self.text_nbOfColumnPerPlot.hide() self.spinbox_nbOfColumnPerPlot.hide() self.button_apply.hide() self.text_plotArrangment.hide() self.radio_horizontal.hide() self.radio_vertical.hide() self.text_intro_revCal.hide() self.text_pix4D.hide() self.button_pix4D.hide() self.text_rawImgFold.hide() self.button_rawImgFold.hide() self.button_apply_revCal.hide() def drawField_clicked(self): """This function is part of the class 'MainWindow' \n It is connected to the button button_drawField and opens the beforehand chosen image of fieldImage_clicked into a new window so the user can select the field points as they wish. The image is then binarized using ExGreen calculation and cropped to avoid useless data storage""" # instructions QMessageBox.about(self, 'Information', "A drawing window will appear. \nTo (Q)uit without saving, press Q.\nTo (R)estart, press R. \nWhen you are (D)one, press D. \n\nPlease mark the corners of the field. \nNo need to close the polygon.") # initialization self.coord = [] self.YN_binary = self.check_binary.isChecked() self.img = cv2.imread(str(self.field_image)) img_name = self.field_image.stem WindowsName = 'Mark the corners of the field. (Q)uit (R)estart (D)one' # make a repository self.main_folder = self.field_image.parent / str('Micro_plots_' + img_name) if self.main_folder.is_dir(): rmtree(self.main_folder, ignore_errors = True) try: self.main_folder.mkdir() except PermissionError: QMessageBox.about(self, 'Information', "Previous results for this image already existed and have been erased.") self.main_folder.mkdir() except FileExistsError: QMessageBox.about(self, 'Information', "Results for this image already exist. Please delete or rename it and try again.") return # resize the image according to the screen size if len(self.img[:, 0]) >= len(self.img[0,:]) : #if the picture's height is bigger than its width self.H = self.displaySize coeff = self.H/len(self.img[:, 0]) self.W = int(coeff*len(self.img[0, :])) else: # if width is bigger than height self.W = self.displaySize coeff = self.W/len(self.img[0, :]) self.H = int(coeff*len(self.img[:, 0])) self.img = cv2.resize(self.img, (self.W, self.H)) # if binary is [0,1], map 1's to 255 if np.amax(self.img) == 1 : self.img [self.img == 1] = 255 # display the picture in a new window cv2.namedWindow(WindowsName) cv2.setMouseCallback(WindowsName, self.draw_point, param = None) # events while drawing (infinite loop) while (1): # show the image window cv2.imshow(WindowsName, self.img) key = cv2.waitKey(20) & 0xFF # to restart the drawing if key == ord('r') or key == ord('R'): # reload the original image (without any points on it) self.img = cv2.imread(str(self.field_image)) self.img = cv2.resize(self.img, (self.W, self.H)) cv2.namedWindow(WindowsName, cv2.WINDOW_NORMAL) # define the name of the window again cv2.setMouseCallback(WindowsName, self.draw_point, param = None) # call the function self.coord = [] # do not save any coordinates # to exit and stop the drawing mode if key == ord('q') or key == ord('Q'): self.coord = [] # no pixels are saved QMessageBox.about(self, 'Information', "No corners were selected.") # close the window cv2.destroyAllWindows() cv2.waitKey(1) self.text_threshold.hide() self.text_threshold2.hide() self.spinbox_threshold.hide() self.button_getBinary.hide() self.text_plot.hide() self.text_nbOfRowPerPlot.hide() self.spinbox_nbOfRowPerPlot.hide() self.text_nbOfColumnPerPlot.hide() self.spinbox_nbOfColumnPerPlot.hide() self.button_apply.hide() self.text_plotArrangment.hide() self.radio_horizontal.hide() self.radio_vertical.hide() self.text_intro_revCal.hide() self.text_pix4D.hide() self.button_pix4D.hide() self.text_rawImgFold.hide() self.button_rawImgFold.hide() self.button_apply_revCal.hide() return # to finish the drawing and save the points drawn if key == ord('d') or key == ord('D'): # field must be at least rectangular if len(self.coord) < 3: QMessageBox.about(self, 'Information', "Please select at least 3 points. \nIf you want to escape, press 'e' key.") else: ## when done, saving the images and producing exG + binary images # close the drawing with the last magenta line cv2.line(self.img, self.coord[-1], self.coord[0], (255, 0, 255), 1) cv2.imshow(WindowsName, self.img) QMessageBox.about(self, 'Information', "Selected points are: \n" + str(self.coord) + '\n\nThe image will be processed. \nPress OK and wait a few seconds.') # save the coordinate image cv2.imwrite(str(self.main_folder / 'Field_points.jpg'), self.img) cv2.destroyWindow(WindowsName) self.img = get_drawn_image(self.field_image, self.coord, coeff) if self.YN_binary: # get rid of the useless black pixels coords = np.argwhere(self.img) y0, x0 = coords.min(axis = 0) y1, x1 = coords.max(axis = 0) + 1 self.img = self.img[y0:y1, x0:x1] # apply the noise removal B = (self.img != 0) self.img_binary = morphology.remove_small_objects(B, min_size = int(self.noise))*255 # save binary image cv2.imwrite(str(self.main_folder / 'Binary_image.tiff'), self.img_binary) # save the value of cutted black parts for the end of the program (shp files) self.y_offset, self.x_offset = y0, x0 self.text_plot.show() self.text_nbOfRowPerPlot.show() self.spinbox_nbOfRowPerPlot.show() self.text_nbOfColumnPerPlot.show() self.spinbox_nbOfColumnPerPlot.show() self.button_apply.show() self.text_plotArrangment.show() self.radio_horizontal.show() self.radio_vertical.show() self.text_threshold.hide() self.text_threshold2.hide() self.spinbox_threshold.hide() self.button_getBinary.hide() else: self.text_threshold.show() self.text_threshold2.show() self.spinbox_threshold.show() self.button_getBinary.show() self.text_intro_revCal.hide() self.text_pix4D.hide() self.button_pix4D.hide() self.text_rawImgFold.hide() self.button_rawImgFold.hide() self.button_apply_revCal.hide() return def getBinary_clicked(self): """This function is part of the class 'MainWindow' \n It is connected to the button button_getBinary and opens the beforehand chosen image of fieldImage_clicked into a new window so the user can select the field points as they wish. The image is then binarized using ExGreen calculation and cropped to avoid useless data storage""" self.threshold = self.spinbox_threshold.value() self.noise = self.spinbox_noise.value() # get coordinates of the first non-black pixels coords = np.argwhere(self.img) try: y0, x0, z = coords.min(axis = 0) y1, x1, z = coords.max(axis = 0) + 1 # generate a binary image self.img_exG, self.img_binary = get_binary(self.img, self.noise, self.threshold) # cut all images according to avoid useless black pixels self.img = self.img[y0:y1, x0:x1] self.img_exG = self.img_exG[y0:y1, x0:x1] self.img_binary = self.img_binary[y0:y1, x0:x1] # save outputs cv2.imwrite(str(self.main_folder / 'ExcessGreen.tiff'), self.img_exG) cv2.imwrite(str(self.main_folder / 'Field_area.tiff'), self.img) # show binary and ask to accept/reject QMessageBox.about(self, 'Information', "The binary will be displayed. \nTo (A)ccept it, press A.\nTo (R)etry with a different threshold, press R.") while (1): # show the image window self.img_binary_show = cv2.resize(self.img_binary, (self.W, self.H)) cv2.imshow('Binary. (A)ccept (R)etry', self.img_binary_show) key = cv2.waitKey(20) & 0xFF # to retry with different values if key == ord('r') or key == ord('R'): cv2.destroyAllWindows() self.text_plot.hide() self.text_nbOfRowPerPlot.hide() self.spinbox_nbOfRowPerPlot.hide() self.text_nbOfColumnPerPlot.hide() self.spinbox_nbOfColumnPerPlot.hide() self.button_apply.hide() self.text_plotArrangment.hide() self.radio_horizontal.hide() self.radio_vertical.hide() self.text_intro_revCal.hide() self.text_pix4D.hide() self.button_pix4D.hide() self.text_rawImgFold.hide() self.button_rawImgFold.hide() self.button_apply_revCal.hide() return if key == ord('a') or key == ord('A'): cv2.destroyAllWindows() break except ValueError: QMessageBox.about(self, 'Information', "It seems that your image is already a binary. It will be treated as a binary for the rest of the program.") self.YN_binary == True y0, x0 = coords.min(axis = 0) y1, x1 = coords.max(axis = 0) + 1 self.img = self.img[y0:y1, x0:x1] # apply the noise removal B = (self.img != 0) self.img_binary = morphology.remove_small_objects(B, min_size = int(self.noise))*255 # save the value of cutted black parts for the end of the program (shp files) self.y_offset, self.x_offset = y0, x0 # displays buttons useful for next steps self.text_plot.show() self.text_nbOfRowPerPlot.show() self.spinbox_nbOfRowPerPlot.show() self.text_nbOfColumnPerPlot.show() self.spinbox_nbOfColumnPerPlot.show() self.button_apply.show() self.text_plotArrangment.show() self.radio_horizontal.show() self.radio_vertical.show() self.text_intro_revCal.hide() self.text_pix4D.hide() self.button_pix4D.hide() self.text_rawImgFold.hide() self.button_rawImgFold.hide() self.button_apply_revCal.hide() def draw_point (self, event, x, y, flags, param): """ This function is part of the class 'MainWindow' and is used in the function 'drawField_clicked'. It draws a red circle everytime the right button of the mouse is clicked down. If there is more than one point, a magenta line will link the two latest points clicked. Inputs : 5 event : mouth clicked down x : position on the x-axis y : position on the y-axis (going down) flags : param : None [could pass a specific color if needed] """ if event == cv2.EVENT_LBUTTONDOWN: #when the button is pushed, the first pixel is recorded and a circle is drawn on the picture self.coord.append((int(x), int(y))) cv2.circle(self.img, (x,y), 6, (0, 0, 255), -1) #draw the circle if len(self.coord) > 1: cv2.line(self.img, self.coord[-2], self.coord[-1], (255, 0, 255), 1) def application(self): """ This function is part of the class 'MainWindow'. It is linked to the button 'button_apply' and starts the image processing (i.e. clustering, cropping, *.shp files, reverse calculation) """ if self.radio_horizontal.isChecked() == False and self.radio_vertical.isChecked() == False: QMessageBox.about(self, 'Information', "Please indicate if the ranges are more vertically or horizontally oriented. \nIf no particular orientation stands out, choose any.") else: img_raster = rasterio.open(self.field_image) aff = img_raster.transform self.crs = img_raster.crs if type(self.crs) == type(None): aff = 0 img_raster.close() nbRow = self.spinbox_nbOfRowPerPlot.value() nbColumn = self.spinbox_nbOfColumnPerPlot.value() if self.radio_horizontal.isChecked() == True: orientation = 'H' elif self.radio_vertical.isChecked() == True: orientation = 'V' # inform the user the program is finished output = MPE(self.img_binary, self.main_folder, self.img, self.YN_binary, nbRow, nbColumn, orientation, self.noise, self.field_image, aff, self.y_offset, self.x_offset) if output == '1': QMessageBox.about(self, 'Information', 'Sorry, no range has been detected. Please change the input parameters and retry.') self.text_intro_revCal.hide() self.text_pix4D.hide() self.button_pix4D.hide() self.text_rawImgFold.hide() self.button_rawImgFold.hide() self.button_apply_revCal.hide() if output == '2': QMessageBox.about(self, 'Information', 'Sorry, no row has been detected. Please change the input parameters and retry.') self.text_intro_revCal.hide() self.text_pix4D.hide() self.button_pix4D.hide() self.text_rawImgFold.hide() self.button_rawImgFold.hide() self.button_apply_revCal.hide() elif output == 'OK' : QMessageBox.about(self, 'Information', '''Micro-plot extraction finished!''') # if the original image is georeferenced if type(self.crs) != type(None): # unlock inputs for reverse calculation self.text_intro_revCal.show() self.text_pix4D.show() self.button_pix4D.show() self.text_rawImgFold.show() self.button_rawImgFold.show() self.button_apply_revCal.show() else : QMessageBox.about(self, 'Information', 'The original image is not georeferenced. Thus, reverse calculation cannot be performed.') # make sure everything is unchecked/back to the original value self.spinbox_nbOfRowPerPlot.setValue(1) self.spinbox_nbOfColumnPerPlot.setValue(1) self.radio_horizontal.setChecked(True) self.radio_vertical.setChecked(False) def button_pix4D_clicked(self): self.pix4D = QFileDialog.getExistingDirectory(self, "Select the pix4D project folder") self.pix4D = Path(self.pix4D) def button_rawImgFold_clicked(self): self.rawImgFold = QFileDialog.getExistingDirectory(self, "Select the raw images folder") self.rawImgFold = Path(self.rawImgFold) def button_apply_revCal_clicked(self): if self.pix4D is None or self.rawImgFold is None: QMessageBox.about(self, 'Error', 'There are missing parameters. Please make sure you provided all the inputs.') else : revCal_csv = ReverseCalculation(self.main_folder, self.pix4D, self.rawImgFold) QMessageBox.about(self, 'Information', 'Reverse calculation finished! Output: ' + str(revCal_csv)) self.pix4D = None self.rawImgFold = None
class UiManagerWindow(QWidget): def __init__(self, login): super().__init__() self.user = login self.admin = False self.ok = 0 self.ip = "0.0.0.0:5555" self.sockIn = network.connect_InSocket(address='0.0.0.0', port=5556) self.sockOut = network.connect_OutSocket(address=self.ip.split(':')[0], port=int( self.ip.split(':')[1])) self.choosen_functional = "" self.login_admins, self.admins, self.banned_admin = [[], [], []] self.init_functional_buttons() self.initUI() self.hide_all_widgets() self.check_filter_country_on = False self.check_filter_city_on = False def check_filter_country_change(self): if self.check_filter_country_on: self.check_filter_country_on = False else: self.check_filter_country_on = True self.show_hotel_funtional() def check_filter_city_change(self): if self.check_filter_city_on: self.check_filter_city_on = False else: self.check_filter_city_on = True self.show_hotel_funtional() def send_to_server(self, msg): msg = json.dumps(msg) network.sock_send(self.sockOut, msg) try: self.sockIn.settimeout(2) data, address = network.read_sock(self.sockIn) self.sockIn.settimeout(None) except socket.timeout: self.info('Сервер отключен! Проверьте соединение', True) return "Error" msg = json.loads(data) return msg def disconnect_server(self): # network.sock_send(self.sockOut, json.dumps({"key": "login"})) network.alive = False network.close_sock(self.sockIn) network.close_sock(self.sockOut) def closeEvent(self, QCloseEvent): self.disconnect_server() def info(self, inf, is_bad): self.info_label.setText( f"Инфо: {inf} ({str(datetime.now().strftime('%Y-%m-%d %H:%M').split()[1])})" ) self.info_label.resize(self.info_label.sizeHint()) if is_bad: self.info_label.setStyleSheet('color: red') else: self.info_label.setStyleSheet('color: green') def initUI(self): self.setGeometry(400, 400, 900, 600) self.setWindowTitle('Система отеля (управляющий)') self.info_label = QLabel("Инфо:", self) self.info_label.move(150, 10) self.info_label.resize(self.info_label.sizeHint()) self.info_label.setAutoFillBackground(True) p = self.info_label.palette() p.setColor(self.info_label.backgroundRole(), Qt.gray) self.info_label.setPalette(p) # Управление администраторами гостиницы self.login_of_admin_label = QLabel("Логин:", self) self.login_of_admin_label.move(10, 70) self.login_of_admin_label.resize(self.login_of_admin_label.sizeHint()) self.login_of_admin_linde_edit = QLineEdit(self) self.login_of_admin_linde_edit.move(175, 70) self.login_of_admin_linde_edit.resize(200, 20) self.password_admin_label = QLabel("Пароль:", self) self.password_admin_label.move(10, 100) self.password_admin_label.resize(self.password_admin_label.sizeHint()) self.password_admin_linde_edit = QLineEdit(self) self.password_admin_linde_edit.move(175, 100) self.password_admin_linde_edit.resize(200, 20) self.password_admin_linde_edit2 = QLineEdit(self) self.password_admin_linde_edit2.move(395, 100) self.password_admin_linde_edit2.resize(200, 20) self.suname_admin_label = QLabel("Фамилия:", self) self.suname_admin_label.move(10, 130) self.suname_admin_label.resize(self.suname_admin_label.sizeHint()) self.suname_admin_linde_edit = QLineEdit(self) self.suname_admin_linde_edit.move(175, 130) self.suname_admin_linde_edit.resize(200, 20) self.suname_admin_linde_edit2 = QLineEdit(self) self.suname_admin_linde_edit2.move(395, 130) self.suname_admin_linde_edit2.resize(200, 20) self.name_admin_label = QLabel("Имя:", self) self.name_admin_label.move(10, 160) self.name_admin_label.resize(self.name_admin_label.sizeHint()) self.name_admin_linde_edit = QLineEdit(self) self.name_admin_linde_edit.move(175, 160) self.name_admin_linde_edit.resize(200, 20) self.name_admin_linde_edit2 = QLineEdit(self) self.name_admin_linde_edit2.move(395, 160) self.name_admin_linde_edit2.resize(200, 20) self.otchestvo_admin_label = QLabel("Отчество:", self) self.otchestvo_admin_label.move(10, 190) self.otchestvo_admin_label.resize( self.otchestvo_admin_label.sizeHint()) self.otchestvo_admin_linde_edit = QLineEdit(self) self.otchestvo_admin_linde_edit.move(175, 190) self.otchestvo_admin_linde_edit.resize(200, 20) self.otchestvo_admin_linde_edit2 = QLineEdit(self) self.otchestvo_admin_linde_edit2.move(395, 190) self.otchestvo_admin_linde_edit2.resize(200, 20) self.number_of_prhone_admin_label = QLabel("Номер телефона:", self) self.number_of_prhone_admin_label.move(10, 220) self.number_of_prhone_admin_label.resize( self.number_of_prhone_admin_label.sizeHint()) self.number_of_prhone_admin_linde_edit = QLineEdit(self) self.number_of_prhone_admin_linde_edit.move(175, 220) self.number_of_prhone_admin_linde_edit.resize(200, 20) self.number_of_prhone_admin_linde_edit2 = QLineEdit(self) self.number_of_prhone_admin_linde_edit2.move(395, 220) self.number_of_prhone_admin_linde_edit2.resize(200, 20) self.hotel_admin_label = QLabel("Гостиница:", self) self.hotel_admin_label.move(10, 250) self.hotel_admin_label.resize(self.hotel_admin_label.sizeHint()) self.hotel_admin_linde_edit = QLineEdit(self) self.hotel_admin_linde_edit.move(175, 250) self.hotel_admin_linde_edit.resize(200, 20) self.hotel_admin_linde_edit2 = QLineEdit(self) self.hotel_admin_linde_edit2.move(395, 250) self.hotel_admin_linde_edit2.resize(200, 20) self.admin_list = QComboBox(self) self.admin_list.move(390, 65) self.admin_list.resize(200, 30) self.admin_list.currentTextChanged.connect(self.update_admins) # self.admin_list.addItems() self.admin_list2 = QComboBox(self) self.admin_list2.move(600, 65) self.admin_list2.resize(200, 30) # self.admin_list2.addItems() self.add_admin = QPushButton("Зарегистрировать\nадминистратора", self) self.add_admin.move(175, 270) self.add_admin.resize(200, 50) self.add_admin.pressed.connect(self.addadmin) self.download_admin = QPushButton( "Загрузить xls файл\nс администраторами", self) self.download_admin.move(10, 350) self.download_admin.resize(200, 50) self.download_admin.pressed.connect(self.downoladadmin) self.delete_admin = QPushButton("Удалить администратора", self) self.delete_admin.move(600, 90) self.delete_admin.resize(200, 30) self.delete_admin.pressed.connect(self.deleteadmin) self.remake_admin = QPushButton( "Обновить информацию\nоб администраторе", self) self.remake_admin.move(395, 270) self.remake_admin.resize(200, 50) self.remake_admin.pressed.connect(self.change_info_admin) self.tableWidget_admin = QTableWidget(self) self.tableWidget_admin.setColumnCount(9) self.tableWidget_admin.move(250, 350) self.tableWidget_admin.resize(800, 200) self.tableWidget_admin.setHorizontalHeaderItem( 0, QTableWidgetItem('логин')) self.tableWidget_admin.setHorizontalHeaderItem( 1, QTableWidgetItem('пароль')) self.tableWidget_admin.setHorizontalHeaderItem( 2, QTableWidgetItem('фамилия')) self.tableWidget_admin.setHorizontalHeaderItem(3, QTableWidgetItem('имя')) self.tableWidget_admin.setHorizontalHeaderItem( 4, QTableWidgetItem('отчество')) self.tableWidget_admin.setHorizontalHeaderItem( 5, QTableWidgetItem('номер_телефона')) self.tableWidget_admin.setHorizontalHeaderItem( 6, QTableWidgetItem('гостиница')) self.tableWidget_admin.setHorizontalHeaderItem( 7, QTableWidgetItem('заблокирован')) self.tableWidget_admin.setHorizontalHeaderItem( 8, QTableWidgetItem('причина_блокировки')) # Гостиница self.number_of_hotel_label = QLabel("Номер гостиницы в сети:", self) self.number_of_hotel_label.move(10, 70) self.number_of_hotel_label.resize( self.number_of_hotel_label.sizeHint()) self.number_of_hotel_linde_edit = QLineEdit(self) self.number_of_hotel_linde_edit.move(175, 70) self.number_of_hotel_linde_edit.resize(200, 20) self.level_hotel_label = QLabel("Количество этажей:", self) self.level_hotel_label.move(10, 100) self.level_hotel_label.resize(self.level_hotel_label.sizeHint()) self.level_hotel_linde_edit = QLineEdit(self) self.level_hotel_linde_edit.move(175, 100) self.level_hotel_linde_edit.resize(200, 20) self.level_hotel_linde_edit2 = QLineEdit(self) self.level_hotel_linde_edit2.move(395, 100) self.level_hotel_linde_edit2.resize(200, 20) self.room_hotel_label = QLabel("Количество номеров:", self) self.room_hotel_label.move(10, 130) self.room_hotel_label.resize(self.room_hotel_label.sizeHint()) self.room_hotel_linde_edit = QLineEdit(self) self.room_hotel_linde_edit.move(175, 130) self.room_hotel_linde_edit.resize(200, 20) self.room_hotel_linde_edit2 = QLineEdit(self) self.room_hotel_linde_edit2.move(395, 130) self.room_hotel_linde_edit2.resize(200, 20) self.country_hotel_label = QLabel("Страна:", self) self.country_hotel_label.move(10, 160) self.country_hotel_label.resize(self.country_hotel_label.sizeHint()) self.country_hotel_linde_edit = QLineEdit(self) self.country_hotel_linde_edit.move(175, 160) self.country_hotel_linde_edit.resize(200, 20) self.country_hotel_linde_edit2 = QLineEdit(self) self.country_hotel_linde_edit2.move(395, 160) self.country_hotel_linde_edit2.resize(200, 20) self.city_hotel_label = QLabel("Город:", self) self.city_hotel_label.move(10, 190) self.city_hotel_label.resize(self.city_hotel_label.sizeHint()) self.city_hotel_linde_edit = QLineEdit(self) self.city_hotel_linde_edit.move(175, 190) self.city_hotel_linde_edit.resize(200, 20) self.city_hotel_linde_edit2 = QLineEdit(self) self.city_hotel_linde_edit2.move(395, 190) self.city_hotel_linde_edit2.resize(200, 20) self.street_hotel_label = QLabel("Улица:", self) self.street_hotel_label.move(10, 220) self.street_hotel_label.resize(self.street_hotel_label.sizeHint()) self.street_hotel_linde_edit = QLineEdit(self) self.street_hotel_linde_edit.move(175, 220) self.street_hotel_linde_edit.resize(200, 20) self.street_hotel_linde_edit2 = QLineEdit(self) self.street_hotel_linde_edit2.move(395, 220) self.street_hotel_linde_edit2.resize(200, 20) self.house_hotel_label = QLabel("Дом:", self) self.house_hotel_label.move(10, 250) self.house_hotel_label.resize(self.house_hotel_label.sizeHint()) self.house_hotel_linde_edit = QLineEdit(self) self.house_hotel_linde_edit.move(175, 250) self.house_hotel_linde_edit.resize(200, 20) self.house_hotel_linde_edit2 = QLineEdit(self) self.house_hotel_linde_edit2.move(395, 250) self.house_hotel_linde_edit2.resize(200, 20) self.hotels_list = QComboBox(self) self.hotels_list.move(390, 65) self.hotels_list.resize(200, 30) self.hotels_list.currentTextChanged.connect(self.update_hotels) #self.hotels_list.addItems() self.hotels_list2 = QComboBox(self) self.hotels_list2.move(600, 65) self.hotels_list2.resize(200, 30) # self.hotels_list2.addItems() self.add_hotel = QPushButton("Создать гостиницу", self) self.add_hotel.move(175, 270) self.add_hotel.resize(200, 30) self.add_hotel.pressed.connect(self.addhotel) self.delete_hotel = QPushButton("Удалить гостиницу", self) self.delete_hotel.move(600, 90) self.delete_hotel.resize(200, 30) self.delete_hotel.pressed.connect(self.deletehotel) self.remake_hotel = QPushButton("Редактировать гостиницу", self) self.remake_hotel.move(395, 270) self.remake_hotel.resize(200, 30) self.remake_hotel.pressed.connect(self.change_info_hotel) self.label_filter = QLabel("Фильтры:", self) self.label_filter.move(10, 350) self.label_filter.resize(self.label_filter.sizeHint()) self.label_filter_country = QLabel("Страна:", self) self.label_filter_country.move(10, 380) self.label_filter_country.resize(self.label_filter.sizeHint()) self.box_filter_country = QComboBox(self) self.box_filter_country.move(60, 375) self.box_filter_country.resize(100, 30) self.check_filter_country = QCheckBox(self) self.check_filter_country.move(170, 380) self.check_filter_country.resize(self.label_filter.sizeHint()) self.check_filter_country.stateChanged.connect( self.check_filter_country_change) self.label_filter_city = QLabel("Город:", self) self.label_filter_city.move(10, 410) self.label_filter_city.resize(self.label_filter.sizeHint()) self.box_filter_city = QComboBox(self) self.box_filter_city.move(60, 405) self.box_filter_city.resize(100, 30) self.check_filter_city = QCheckBox(self) self.check_filter_city.move(170, 410) self.check_filter_city.resize(self.label_filter.sizeHint()) self.check_filter_city.stateChanged.connect( self.check_filter_city_change) # Блокировка self.admins_label = QLabel("Пользователи:", self) self.admins_label.move(20, 70) self.admins_label.resize(self.admins_label.sizeHint()) self.admins_list = QComboBox(self) self.admins_list.move(115, 65) self.admins_list.resize(200, 30) self.admins_list.addItems(self.login_admins) self.button_block = QPushButton("Заблокировать пользователя", self) self.button_block.move(190, 100) self.button_block.resize(300, 30) self.button_block.pressed.connect(self.block_admin) self.prichina = QLabel("Причина:", self) self.prichina.move(330, 70) self.prichina.resize(self.prichina.sizeHint()) self.prichina_line_edit = QLineEdit(self) self.prichina_line_edit.move(400, 68) self.prichina_line_edit.resize(200, 20) self.tableWidget_hotel = QTableWidget(self) self.tableWidget_hotel.setColumnCount(7) self.tableWidget_hotel.move(250, 350) self.tableWidget_hotel.resize(800, 200) self.tableWidget_hotel.setHorizontalHeaderItem( 0, QTableWidgetItem('название гостиницы')) self.tableWidget_hotel.setHorizontalHeaderItem( 1, QTableWidgetItem('количество этажей')) self.tableWidget_hotel.setHorizontalHeaderItem( 2, QTableWidgetItem('количество номеров')) self.tableWidget_hotel.setHorizontalHeaderItem( 3, QTableWidgetItem('страна')) self.tableWidget_hotel.setHorizontalHeaderItem( 4, QTableWidgetItem('город')) self.tableWidget_hotel.setHorizontalHeaderItem( 5, QTableWidgetItem('улица')) self.tableWidget_hotel.setHorizontalHeaderItem(6, QTableWidgetItem('дом')) # неудачные попытки входа self.tableWidget_bt = QTableWidget(self) self.tableWidget_bt.setColumnCount(3) self.tableWidget_bt.move(10, 60) self.tableWidget_bt.resize(500, 400) self.tableWidget_bt.setHorizontalHeaderItem(0, QTableWidgetItem('Логин')) self.tableWidget_bt.setHorizontalHeaderItem(1, QTableWidgetItem('Пароль')) self.tableWidget_bt.setHorizontalHeaderItem(2, QTableWidgetItem('Время')) def init_functional_buttons(self): self.label_functional = QLabel("Функционал:", self) self.label_functional.move(10, 10) self.label_functional.resize(self.label_functional.sizeHint()) self.radio_button_1 = QRadioButton( "Управление администраторами гостиниц", self) self.radio_button_1.move(10, 30) self.radio_button_2 = QRadioButton("Гостиница", self) self.radio_button_2.move(310, 30) self.radio_button_3 = QRadioButton("Блокировка", self) self.radio_button_3.move(410, 30) self.radio_button_4 = QRadioButton("Просмотр неудачных попыток входа", self) self.radio_button_4.move(510, 30) self.button_group = QButtonGroup() self.button_group.addButton(self.radio_button_1) self.button_group.addButton(self.radio_button_2) self.button_group.addButton(self.radio_button_3) self.button_group.addButton(self.radio_button_4) self.button_group.buttonClicked.connect(self.choose) def choose(self, button): self.choosen_functional = button.text() self.hide_all_widgets() if self.choosen_functional == "Блокировка": self.show_block_funtional() elif self.choosen_functional == "Гостиница": self.show_hotel_funtional() elif self.choosen_functional == "Управление администраторами гостиниц": self.show_admin_funtional() elif self.choosen_functional == "Просмотр неудачных попыток входа": self.show_bad_try() def hide_all_widgets(self): self.admins_label.hide() self.admins_list.hide() self.button_block.hide() self.prichina.hide() self.prichina_line_edit.hide() self.label_filter.hide() self.number_of_hotel_label.hide() self.number_of_hotel_linde_edit.hide() self.level_hotel_label.hide() self.level_hotel_linde_edit.hide() self.room_hotel_label.hide() self.room_hotel_linde_edit.hide() self.country_hotel_label.hide() self.country_hotel_linde_edit.hide() self.city_hotel_label.hide() self.city_hotel_linde_edit.hide() self.street_hotel_label.hide() self.street_hotel_linde_edit.hide() self.house_hotel_label.hide() self.house_hotel_linde_edit.hide() self.remake_hotel.hide() self.delete_hotel.hide() self.add_hotel.hide() self.hotels_list2.hide() self.hotels_list.hide() self.level_hotel_linde_edit2.hide() self.room_hotel_linde_edit2.hide() self.country_hotel_linde_edit2.hide() self.city_hotel_linde_edit2.hide() self.street_hotel_linde_edit2.hide() self.house_hotel_linde_edit2.hide() self.tableWidget_hotel.hide() self.label_filter_country.hide() self.box_filter_country.hide() self.check_filter_country.hide() self.label_filter_city.hide() self.box_filter_city.hide() self.check_filter_city.hide() self.download_admin.hide() self.login_of_admin_label.hide() self.login_of_admin_linde_edit.hide() self.password_admin_label.hide() self.password_admin_linde_edit.hide() self.password_admin_linde_edit2.hide() self.suname_admin_label.hide() self.suname_admin_linde_edit.hide() self.suname_admin_linde_edit2.hide() self.name_admin_label.hide() self.name_admin_linde_edit.hide() self.name_admin_linde_edit2.hide() self.otchestvo_admin_label.hide() self.otchestvo_admin_linde_edit.hide() self.otchestvo_admin_linde_edit2.hide() self.number_of_prhone_admin_label.hide() self.number_of_prhone_admin_linde_edit.hide() self.number_of_prhone_admin_linde_edit2.hide() self.hotel_admin_label.hide() self.hotel_admin_linde_edit.hide() self.hotel_admin_linde_edit2.hide() self.admin_list.hide() self.admin_list2.hide() self.add_admin.hide() self.delete_admin.hide() self.remake_admin.hide() self.tableWidget_admin.hide() self.tableWidget_bt.hide() def show_hotel_funtional(self): answer = self.send_to_server({"key": 'hotels_download'}) if answer != "Error": self.name_hotel, self.hotels = answer hotels = self.hotels if self.check_filter_country_on: hotels = [ i for i in hotels if i[3] == self.box_filter_country.currentText() ] if self.check_filter_city_on: hotels = [ i for i in hotels if i[4] == self.box_filter_city.currentText() ] self.tableWidget_hotel.show() self.tableWidget_hotel.setRowCount(len(hotels)) for i in range(len(hotels)): for j in range(7): itm = QTableWidgetItem(hotels[i][j]) itm.setFlags(QtCore.Qt.ItemIsEnabled) self.tableWidget_hotel.setItem(i, j, itm) self.tableWidget_hotel.resizeColumnsToContents() self.hotels_list.clear() self.hotels_list.addItems(self.name_hotel) self.hotels_list2.clear() self.hotels_list2.addItems(self.name_hotel) self.box_filter_country.clear() self.box_filter_city.clear() self.box_filter_country.addItems([i[3] for i in self.hotels]) self.box_filter_city.addItems([i[4] for i in self.hotels]) hotel2 = "No" for i in self.hotels: if str(i[0]) == str(self.hotels_list.currentText()): hotel2 = i else: if hotel2 == "No": hotel2 = ['' for i in range(7)] hotel2 = [i if i else '' for i in hotel2] self.label_filter.show() self.label_filter_country.show() self.box_filter_country.show() self.check_filter_country.show() self.label_filter_city.show() self.box_filter_city.show() self.check_filter_city.show() self.number_of_hotel_label.show() self.number_of_hotel_linde_edit.show() self.level_hotel_label.show() self.level_hotel_linde_edit.show() self.room_hotel_label.show() self.room_hotel_linde_edit.show() self.country_hotel_label.show() self.country_hotel_linde_edit.show() self.city_hotel_label.show() self.city_hotel_linde_edit.show() self.street_hotel_label.show() self.street_hotel_linde_edit.show() self.house_hotel_label.show() self.house_hotel_linde_edit.show() self.remake_hotel.show() self.delete_hotel.show() self.add_hotel.show() self.hotels_list2.show() self.hotels_list.show() self.level_hotel_linde_edit2.show() self.level_hotel_linde_edit2.setText(str(hotel2[1])) self.room_hotel_linde_edit2.show() self.room_hotel_linde_edit2.setText(str(hotel2[2])) self.country_hotel_linde_edit2.show() self.country_hotel_linde_edit2.setText(str(hotel2[3])) self.city_hotel_linde_edit2.show() self.city_hotel_linde_edit2.setText(str(hotel2[4])) self.street_hotel_linde_edit2.show() self.street_hotel_linde_edit2.setText(str(hotel2[5])) self.house_hotel_linde_edit2.show() self.house_hotel_linde_edit2.setText(str(hotel2[6])) def show_admin_funtional(self): answer = self.send_to_server({"key": 'admin_download'}) if answer != "Error": self.login_admins, self.admins, self.not_banned_admin = answer self.tableWidget_admin.show() self.tableWidget_admin.setRowCount(len(self.admins)) for i in range(len(self.admins)): for j in range(9): itm = QTableWidgetItem(self.admins[i][j]) itm.setFlags(QtCore.Qt.ItemIsEnabled) self.tableWidget_admin.setItem(i, j, itm) self.tableWidget_admin.resizeColumnsToContents() self.admin_list2.clear() self.admin_list2.addItems(self.login_admins) self.admin_list.clear() self.admin_list.addItems(self.login_admins) admin = "No" for i in self.admins: if str(i[0]) == str(self.admin_list.currentText()): admin = i else: if admin == "No": admin = ['' for i in range(7)] admin = [i if i else '' for i in admin] self.login_of_admin_label.show() self.login_of_admin_linde_edit.show() self.password_admin_label.show() self.password_admin_linde_edit.show() self.password_admin_linde_edit2.show() self.password_admin_linde_edit2.setText(str(admin[1])) self.suname_admin_label.show() self.suname_admin_linde_edit.show() self.suname_admin_linde_edit2.show() self.suname_admin_linde_edit2.setText(str(admin[2])) self.name_admin_label.show() self.name_admin_linde_edit.show() self.name_admin_linde_edit2.show() self.name_admin_linde_edit2.setText(str(admin[3])) self.otchestvo_admin_label.show() self.download_admin.show() self.otchestvo_admin_linde_edit.show() self.otchestvo_admin_linde_edit2.show() self.otchestvo_admin_linde_edit2.setText(str(admin[4])) self.number_of_prhone_admin_label.show() self.number_of_prhone_admin_linde_edit.show() self.number_of_prhone_admin_linde_edit2.show() self.number_of_prhone_admin_linde_edit2.setText(str(admin[5])) self.hotel_admin_label.show() self.hotel_admin_linde_edit.show() self.hotel_admin_linde_edit2.show() self.hotel_admin_linde_edit2.setText(str(admin[6])) self.admin_list.show() self.admin_list2.show() self.add_admin.show() self.delete_admin.show() self.remake_admin.show() def addadmin(self): login = self.login_of_admin_linde_edit.text() password = self.password_admin_linde_edit.text() surname = self.suname_admin_linde_edit.text() name = self.name_admin_linde_edit.text() father_name = self.otchestvo_admin_linde_edit.text() number_of_phone = self.number_of_prhone_admin_linde_edit.text() hotel = self.hotel_admin_linde_edit.text() if login and password and surname and name and father_name and number_of_phone and hotel: admin = [ login, password, surname, name, father_name, number_of_phone, hotel ] admin = "|||".join(admin) ok = self.send_to_server({"key": "add_admin", "login": admin}) if ok: self.info("Администратор успешно зарегистрирован", False) else: self.info("Администратор не был зарегистрирован", True) else: self.info("Введенные данные некорректны", True) self.show_admin_funtional() def change_info_admin(self): login = self.admin_list.currentText() password = self.password_admin_linde_edit2.text() surname = self.suname_admin_linde_edit2.text() name = self.name_admin_linde_edit2.text() father_name = self.otchestvo_admin_linde_edit2.text() number_of_phone = self.number_of_prhone_admin_linde_edit2.text() hotel = self.hotel_admin_linde_edit2.text() if login and password and surname and name and father_name and number_of_phone and hotel: admin = [ login, password, surname, name, father_name, number_of_phone, hotel ] admin = "|||".join(admin) ok = self.send_to_server({ "key": "change_info_admin", "login": admin }) if ok: self.info("Информация об администраторе успешно обновлена", False) else: self.info("Информация об администраторе не обновлена", True) else: self.info("Введенные данные некорректны", True) self.show_admin_funtional() def addhotel(self): name = self.number_of_hotel_linde_edit.text() levels = self.level_hotel_linde_edit2.text() rooms = self.room_hotel_linde_edit2.text() country = self.country_hotel_linde_edit2.text() city = self.city_hotel_linde_edit2.text() street = self.street_hotel_linde_edit2.text() house = self.house_hotel_linde_edit2.text() if name and levels and rooms and country and city and street and house: hotel = [name, levels, rooms, country, city, street, house] hotel = "|||".join(hotel) ok = self.send_to_server({"key": "add_hotel", "name": hotel}) if ok: self.info("Гостиница успешно добавлена", False) else: self.info("Гостиница не была добавлена", True) else: self.info("Введенные данные некорректны", True) self.show_hotel_funtional() def change_info_hotel(self): name = self.hotels_list.currentText() levels = self.level_hotel_linde_edit2.text() rooms = self.room_hotel_linde_edit2.text() country = self.country_hotel_linde_edit2.text() city = self.city_hotel_linde_edit2.text() street = self.street_hotel_linde_edit2.text() house = self.house_hotel_linde_edit2.text() if name and levels and rooms and country and city and street and house: hotel = [name, levels, rooms, country, city, street, house] hotel = "|||".join(hotel) ok = self.send_to_server({ "key": "change_info_hotel", "name": hotel }) if ok: self.info("Информация о гостинице успешно обновлена", False) else: self.info("Информация о гостинице не обновлена", True) else: self.info("Введенные данные некорректны", True) self.show_hotel_funtional() def block_admin(self): admin = self.admins_list.currentText() reason = self.prichina_line_edit.text() ok = self.send_to_server({ "key": "ban_admin", "login": admin, "reason": reason }) if ok: self.info("Пользователь успешно добавлен в список заблокированных", False) else: self.info("Пользователь не добавлен в список заблокированных", True) self.show_block_funtional() def deleteadmin(self): admin = self.admin_list2.currentText() ok = self.send_to_server({"key": "delete_admin", "login": admin}) if ok: self.info("Администратор успешно удален", False) else: self.info("Администратор не удален", True) self.show_admin_funtional() def deletehotel(self): name = self.hotels_list2.currentText() rooms = self.send_to_server({"key": "rooms"}) for i in rooms: if i[0] == name: self.info( "Гостиница не удалена, так как она связана с номерами", True) return ok = self.send_to_server({"key": "delete_hotel", "name": name}) if ok: self.info("Гостиница успешно удалена", False) else: self.info("Гостиница не удалена", True) self.show_hotel_funtional() def show_block_funtional(self): answer = self.send_to_server({"key": 'admin_download'}) if answer != "Error": self.login_admins, self.admins, self.not_banned_admin = answer self.admins_list.clear() self.admins_list.addItems(self.not_banned_admin) self.admins_label.show() self.admins_list.show() self.button_block.show() self.prichina.show() self.prichina_line_edit.show() def update_admins(self): admin = "No" for i in self.admins: if str(i[0]) == str(self.admin_list.currentText()): admin = i else: if admin == "No": admin = ['' for i in range(7)] admin = [i if i else '' for i in admin] self.password_admin_linde_edit2.setText(str(admin[1])) self.suname_admin_linde_edit2.setText(str(admin[2])) self.name_admin_linde_edit2.setText(str(admin[3])) self.otchestvo_admin_linde_edit2.setText(str(admin[4])) self.number_of_prhone_admin_linde_edit2.setText(str(admin[5])) self.hotel_admin_linde_edit2.setText(str(admin[6])) def update_hotels(self): hotel2 = "No" for i in self.hotels: if str(i[0]) == str(self.hotels_list.currentText()): hotel2 = i else: if hotel2 == "No": hotel2 = ['' for i in range(7)] hotel2 = [i if i else '' for i in hotel2] self.level_hotel_linde_edit2.setText(str(hotel2[1])) self.room_hotel_linde_edit2.setText(str(hotel2[2])) self.country_hotel_linde_edit2.setText(str(hotel2[3])) self.city_hotel_linde_edit2.setText(str(hotel2[4])) self.street_hotel_linde_edit2.setText(str(hotel2[5])) self.house_hotel_linde_edit2.setText(str(hotel2[6])) def downoladadmin(self): location = QFileDialog.getOpenFileName(self, 'Open file')[0] try: admins = read_info_about_administrators(location) except: self.info("Возникла ошибка при загрузке данных", True) return oks = [] for i in admins: if all(i): admin = "|||".join(i) ok = self.send_to_server({"key": "add_admin", "login": admin}) oks.append(ok) if all(oks): self.info("Информация загружена успешна", False) else: self.info("Не вся информация была загружена", True) self.show_admin_funtional() def show_bad_try(self): answer = self.send_to_server({"key": 'bad_try_download'}) if answer != "Error": self.bad_try = answer self.tableWidget_bt.show() self.tableWidget_bt.setRowCount(len(self.bad_try)) for i in range(len(self.bad_try)): for j in range(3): itm = QTableWidgetItem(self.bad_try[i][j]) itm.setFlags(QtCore.Qt.ItemIsEnabled) self.tableWidget_bt.setItem(i, j, itm) self.tableWidget_bt.resizeColumnsToContents()
class MainView(base, form): def __init__(self, pipeline, parent=None): super(base, self).__init__(parent) self.setupUi(self) self.pipeline = pipeline self.pip_widgets = [] self.default_pips = [] self.draw_ui() self.connect_ui() def register_observers(self): pass def connect_ui(self): """ This function connects the ui using signals from the ui elements and its method counterparts. """ self.input_btn.clicked.connect(self.set_input_url) self.output_btn.clicked.connect(self.set_output_url) self.save_btn.clicked.connect(self.save_pipeline) self.load_favorite_pipelines() self.fav_pips_combo_box.activated.connect(self.select_default_pip) self.run_btn.clicked.connect(self.run) self.delete_btn.clicked.connect(self.trash_pipeline) self.add_btn.clicked.connect(lambda: self.add_pipe_entry_new()) def draw_ui(self): """ This function draws all additional UI elements. If you want the application to display any additional things like a button you can either add it in the QtDesigner or declare it here. """ # *TODO* Create these ones with Qt Designer and put them into select_cat_alg_vbox_layout. I failed self.ComboxCategories = QComboBox() self.stackedWidgetComboxesAlgorithms = QStackedWidget() self.select_cat_alg_vbox_layout.addWidget(self.ComboxCategories) self.select_cat_alg_vbox_layout.addWidget(self.stackedWidgetComboxesAlgorithms) self.ComboxCategories.hide() """ This function is concerned with drawing all non static elements into the GUI. """ """self.set_pip_title("A. Junius2") self.set_preset(["A.Junius", "test", "test", "test"]) self.add_pip_entry("../assets/images/P.png", "Preprocessing - adaptive trehsold watershed") self.add_pip_entry("../assets/images/P.png", "Preprocessing - adaptive trehsold watershed") self.add_pip_entry("../assets/images/P.png", "Preprocessing - adaptive trehsold watershed") self.add_pip_entry("../assets/images/P.png", "Preprocessing - adaptive trehsold watershed") self.add_pip_entry("../assets/images/P.png", "Preprocessing - adaptive trehsold watershed") self.add_pip_entry("../assets/images/P.png", "Preprocessing - adaptive trehsold watershed") self.add_pip_entry("../assets/images/P.png", "Preprocessing - adaptive trehsold watershed") self.add_cat_image("../assets/images/seg_fav.jpeg", "Preprocessing") self.add_cat_image("../assets/images/wing.jpeg", "Preprocessing") self.add_cat_image("../assets/images/wing.jpeg", "Preprocessing") self.add_cat_image("../assets/images/wing.jpeg", "Preprocessing") self.add_cat_image("../assets/images/wing.jpeg", "Preprocessing") self.add_cat_image("../assets/images/wing.jpeg", "Preprocessing") self.add_cat_image("../assets/images/wing.jpeg", "Preprocessing") self.main_image_label.setPixmap(QtGui.QPixmap("wing.jpeg")) category_combo_box = ComboBoxWidget("type") category_combo_box.add_item("Preprocessing", "../assets/images/P.png") category_combo_box.add_item("Segmentation", "../assets/images/S.png") category_combo_box.add_item("Graph Detection", "../assets/images/D.png") category_combo_box.add_item("Graph Filtering", "../assets/images/F.png") alg_combo_box = ComboBoxWidget("algorithm") alg_combo_box.add_item("Otsus") alg_combo_box.add_item("Guo Hall") alg_combo_box.add_item("Adaptive Treshold") slider_1 = SliderWidget("slider1das", 0, 10, 1, 4, True) slider_2 = SliderWidget("slider1", 0, 10, 2, 4, False) slider_3 = SliderWidget("sliderböadsad", 0, 10, 1, 4, True) slider_4 = SliderWidget("sliderböadsad", 0, 10, 1, 4, True) slider_5 = SliderWidget("sliderböadsad", 0, 10, 1, 4, True) checkbox_1 = CheckBoxWidget("checkbox1", True) self.setting_widget_vbox_layout.addWidget(category_combo_box) self.setting_widget_vbox_layout.addWidget(alg_combo_box) self.setting_widget_vbox_layout.addWidget(slider_1) self.setting_widget_vbox_layout.addWidget(slider_2) self.setting_widget_vbox_layout.addWidget(slider_3) self.setting_widget_vbox_layout.addWidget(slider_4) self.setting_widget_vbox_layout.addWidget(slider_5) self.setting_widget_vbox_layout.addWidget(checkbox_1) self.setting_widget_vbox_layout.setAlignment(Qt.AlignTop)""" def set_pip_title(self, title): """ Sets the title of the current selected pipeline in the ui. Args: | *title*: the title of the pipeline | *label_ref*: the reference to the label. """ self.current_pip_label.setText(title) def load_dark_theme(self, application): """ This function is called to load the white theme with all its icons for the buttons and the css file. Args: application: the cureent app instance """ # load buttons pixmap_icon = QtGui.QPixmap("./assets/images/add_white.png") q_icon = QtGui.QIcon(pixmap_icon) self.add_btn.setIcon(q_icon) pixmap_icon = QtGui.QPixmap("./assets/images/trash_white.png") q_icon = QtGui.QIcon(pixmap_icon) self.delete_btn.setIcon(q_icon) pixmap_icon = QtGui.QPixmap("./assets/images/diskette_white.png") q_icon = QtGui.QIcon(pixmap_icon) self.save_btn.setIcon(q_icon) pixmap_icon = QtGui.QPixmap("./assets/images/up-arrow_white.png") q_icon = QtGui.QIcon(pixmap_icon) self.input_btn.setIcon(q_icon) pixmap_icon = QtGui.QPixmap("./assets/images/folder_white.png") q_icon = QtGui.QIcon(pixmap_icon) self.output_btn.setIcon(q_icon) @pyqtSlot(int) def select_default_pip(self, index): """ This is the slot for the Pipeline combobox in the ui Args: index: index of the option currently selected """ # delete current pipeline self.trash_pipeline() # get url and name name, url = self.default_pips[index - 1] # parse the json in the model self.pipeline.load_pipeline_json(url) print("PARSER" + str(self.pipeline.executed_cats[0].active_algorithm)) print("PARSER" + str(self.pipeline.executed_cats[1].active_algorithm)) # set the title self.set_pip_title(name) # Create an entry in the pipeline widget for every step in the pipeline for i in range(0, len(self.pipeline.executed_cats)): self.add_pipe_entry_new(i) self.scroll_down_pip() """for widget in alg_widgets: self.setting_widget_vbox_layout.addWidget(widget)""" def trash_pipeline(self): """ This method clears the complete pipeline while users clicked the trash button. """ # remove all entries in the pipeline list while self.pip_widget_vbox_layout.count(): child = self.pip_widget_vbox_layout.takeAt(0) child.widget().deleteLater() while self.stackedWidget_Settings.currentWidget() is not None: self.stackedWidget_Settings.removeWidget(self.stackedWidget_Settings.currentWidget()) self.settings_collapsable.setTitle("") # remove the pipeline name self.set_pip_title("") # remove all entries int the executed_cats of the model pipeline del self.pipeline.executed_cats[:] # remove all widgets del self.pip_widgets[:] # remove category algorith dropdown self.remove_cat_alg_dropdown() # remove all entries from the pipeline model del self.pipeline.executed_cats[:] @pyqtSlot() def run(self): """ This method runs the the pipeline by calling the process methode in pipeline """ self.pipeline.process() @pyqtSlot() def set_input_url(self): """ This method sets the url for the input image in the pipeline. """ url = QtWidgets.QFileDialog.getOpenFileNames() if url[0]: print(url[0]) print(url[0][0]) self.lineEdit.setText(url[0][0]) self.pipeline.set_input(url[0][0]) @pyqtSlot() def set_output_url(self): """ This method sets the url for the output folder in the pipeline. Args: url: the url to the output folder a user selected in the ui """ url = QtWidgets.QFileDialog.getExistingDirectory() if url: print(url) print(url) self.custom_line_edit.setText(url) self.pipeline.set_output_dir(url) def load_favorite_pipelines(self): """ Scans the directory for default pipelines to display all available items """ self.fav_pips_combo_box.addItem("Please Select") # scan the directory for default pipelines for file in os.listdir("./_default_pipelines"): if file.endswith(".json"): name = file.split(".")[0] url = os.path.abspath("./_default_pipelines" + "/" + file) self.default_pips.append([name, url]) self.fav_pips_combo_box.addItem(name) @pyqtSlot() def save_pipeline(self): """ Saves the pipeline as a json at the users file system. """ url = str(QtWidgets.QFileDialog.getSaveFileName()[0]) split_list = url.split("/") name = split_list[len(split_list) - 1].split(".")[0] del split_list[len(split_list) - 1] url = url.replace(name, "") self.pipeline.save_pipeline_json(name, url) @pyqtSlot(int) def remove_pip_entry(self, pipe_entry_widget, settings_widget, cat=None): """ Removes the pip entry at the given position in the ui Args: pipeline_index (object): settings_widget: position: position at which the pip entry gets removed """ # remove pipeline entry widget from ui self.pip_widget_vbox_layout.removeWidget(pipe_entry_widget) pipe_entry_widget.deleteLater() # remove it settings widgets from ui if settings_widget is not None: if self.stackedWidget_Settings.currentWidget() == settings_widget: self.stackedWidget_Settings.hide() self.remove_cat_alg_dropdown() self.settings_collapsable.setTitle("Settings") self.stackedWidget_Settings.removeWidget(settings_widget) # remove in model if cat is not None: print("Remove entry at pos " + str(self.pipeline.get_index(cat)) + " " + str(cat)) self.pipeline.delete_category(self.pipeline.get_index(cat)) def change_pip_entry_alg(self, position, new_category, new_algorithm, pipe_entry_widget, settings_widget): """ Changes the selected algorithm of the pipeline entry at the position. Afterwards create all widgets for this algorithm instance Args: position: the position of the pipeline entry algorithm: the selected algorithm for this category """ print("Position to be changed:" + str(position)) print("Pipeline length: " + str(len(self.pipeline.executed_cats))) old_cat = self.pipeline.executed_cats[position] old_alg = old_cat.active_algorithm print("Old Cat found in pipeline: " + str(old_cat)) print("Old Alg: found in pipeline:" + str(old_alg)) print("New Category given:" + str(new_category)) print("New Algorithm given:" + str(new_algorithm)) # set in model self.pipeline.change_category(new_category, position) self.pipeline.change_algorithm(new_algorithm, position) new_cat = self.pipeline.executed_cats[position] new_alg = new_cat.active_algorithm # change settings widgets self.remove_pip_entry(pipe_entry_widget, settings_widget) (new_pipe_entry_widget, new_settings_widget) = self.add_pipe_entry_new(position) self.stackedWidget_Settings.show() self.stackedWidget_Settings.setCurrentIndex(position) self.settings_collapsable.setTitle(new_alg.get_name() + " Settings") self.remove_cat_alg_dropdown() self.create_cat_alg_dropdown(position, new_pipe_entry_widget, new_settings_widget) self.set_cat_alg_dropdown(new_cat, new_alg) print("New Cat found in pipeline: " + str(new_cat)) print("New Alg found in pipeline: " + str(new_alg)) def load_settings_widgets_from_pipeline_groupbox(self, position): """ Extracts all widgets from a single algorithm and returns a QBoxLayout Args: alg: the alg instance we extract from Returns: a QBoxLayout containing all widgets for this particular alg. """ alg = self.pipeline.executed_cats[position].active_algorithm print("alg " + str(alg)) print("cat " + str(self.pipeline.executed_cats[position])) empty_flag = True groupOfSliders = QGroupBox() sp = QSizePolicy() sp.setVerticalPolicy(QSizePolicy.Preferred) # groupOfSliders.setSizePolicy(sp) groupOfSliderssLayout = QBoxLayout(QBoxLayout.TopToBottom) groupOfSliderssLayout.setContentsMargins(0, -0, -0, 0) groupOfSliderssLayout.setAlignment(Qt.AlignTop) groupOfSliderssLayout.setSpacing(0) print("Build Slider @ "+ str(position)) # create integer sliders for slider in alg.integer_sliders: empty_flag = False print("slider.value " + str(slider.value)) print("slider " + str(slider)) #print(alg.get_name() + ": add slider (int).") groupOfSliderssLayout.addWidget( SliderWidget(slider.name, slider.lower, slider.upper, slider.step_size, slider.value, slider.set_value, False)) # create float sliders for slider in alg.float_sliders: empty_flag = False #print(alg.get_name() + ": add slider (float).") groupOfSliderssLayout.addWidget( SliderWidget(slider.name, slider.lower, slider.upper, slider.step_size, slider.value, slider.set_value, True), 0, Qt.AlignTop) # create checkboxes for checkbox in alg.checkboxes: empty_flag = False #print(alg.get_name() + ": add checkbox.") groupOfSliderssLayout.addWidget(CheckBoxWidget(checkbox.name, checkbox.value, checkbox.set_value), 0, Qt.AlignTop) # create dropdowns for combobox in alg.drop_downs: empty_flag = False #print(alg.get_name() + ": add combobox.") groupOfSliderssLayout.addWidget( ComboBoxWidget(combobox.name, combobox.options, combobox.set_value, combobox.value), 0, Qt.AlignTop) if empty_flag: label = QLabel() label.setText("This algorithm has no Settings.") groupOfSliderssLayout.addWidget(label, 0, Qt.AlignHCenter) groupOfSliders.setLayout(groupOfSliderssLayout) return groupOfSliders def create_cat_alg_dropdown(self, cat_position, pipe_entry_widget, settings_widget): """ Args: last_cat (object): """ layout = self.select_cat_alg_vbox_layout cat = self.pipeline.executed_cats[cat_position] last_cat = None # Show only allowed categories in dropdown if len(self.pipeline.executed_cats) > 1: last_cat = self.pipeline.executed_cats[cat_position - 1] # Combobox for selecting Category self.ComboxCategories.show() self.ComboxCategories.setFixedHeight(30) self.ComboxCategories.addItem("<Please Select Category>") self.stackedWidgetComboxesAlgorithms = QStackedWidget() self.stackedWidgetComboxesAlgorithms.setFixedHeight(30) self.stackedWidgetComboxesAlgorithms.hide() def setCurrentIndexCat(index): #print("Set Cat") if self.ComboxCategories.currentIndex() == 0: self.stackedWidgetComboxesAlgorithms.hide() else: self.stackedWidgetComboxesAlgorithms.show() self.stackedWidgetComboxesAlgorithms.setCurrentIndex(index - 1) for category_name in self.pipeline.report_available_cats(last_cat): # Add Category to combobox self.ComboxCategories.addItem(category_name) tmp1 = QComboBox() tmp1.addItem("<Please Select Algorithm>") tmp1.setFixedHeight(30) category = self.pipeline.get_category(category_name) #self.current_index = -1 def setCurrentIndexAlg(index): if self.ComboxCategories.currentIndex() == 0 or self.stackedWidgetComboxesAlgorithms.currentWidget().currentIndex() == 0: pass else: #self.current_index != index: self.change_pip_entry_alg(self.pipeline.get_index(cat), self.ComboxCategories.currentText(), self.stackedWidgetComboxesAlgorithms.currentWidget().currentText(), pipe_entry_widget, settings_widget) #self.current_index = index tmp1.activated.connect(setCurrentIndexAlg) for algorithm_name in self.pipeline.get_all_algorithm_list(category): tmp1.addItem(algorithm_name) self.stackedWidgetComboxesAlgorithms.addWidget(tmp1) layout.addWidget(self.ComboxCategories) layout.addWidget(self.stackedWidgetComboxesAlgorithms) self.ComboxCategories.activated.connect(setCurrentIndexCat) def set_cat_alg_dropdown(self, category, algorithm): indexC = self.ComboxCategories.findText(category.get_name()) #print("IndexC " + str(indexC)) self.ComboxCategories.setCurrentIndex(indexC) self.stackedWidgetComboxesAlgorithms.show() self.stackedWidgetComboxesAlgorithms.setCurrentIndex(indexC - 1) indexA = self.stackedWidgetComboxesAlgorithms.currentWidget().findText(algorithm.get_name()) #print("IndexA " + str(indexA)) self.stackedWidgetComboxesAlgorithms.currentWidget().setCurrentIndex(indexA) def remove_cat_alg_dropdown(self): """ Returns: object: """ self.ComboxCategories.clear() while self.stackedWidgetComboxesAlgorithms.currentWidget() is not None: self.stackedWidgetComboxesAlgorithms.removeWidget(self.stackedWidgetComboxesAlgorithms.currentWidget()) while self.select_cat_alg_vbox_layout.count(): child = self.select_cat_alg_vbox_layout.takeAt(0) child.widget().hide() def scroll_down_pip(self): self.pip_scroll.verticalScrollBar().setSliderPosition(self.pip_scroll.verticalScrollBar().maximum()) def add_pipe_entry_new(self, position=None): """ Creates a entry in the ui pipeline with a given position in pipeline. It also creates the corresponding settings widget. """ # create an widget that displays the pip entry in the ui and connect the remove button pip_main_widget = QWidget() pip_main_widget.setFixedHeight(70) pip_main_widget.setFixedWidth(300) pip_main_layout = QHBoxLayout() pip_main_widget.setLayout(pip_main_layout) new_marker = False if position is None: position = len(self.pipeline.executed_cats) cat = self.pipeline.new_category(position) label = "<Click to specify new step>" icon = None new_marker = True else: cat = self.pipeline.executed_cats[position] alg = cat.active_algorithm label = alg.get_name() icon = cat.get_icon() new_marker = False pixmap = QPixmap(icon) pixmap_scaled_keeping_aspec = pixmap.scaled(30, 30, QtCore.Qt.KeepAspectRatio) pixmap_label = QtWidgets.QLabel() pixmap_label.setPixmap(pixmap_scaled_keeping_aspec) pip_up_down = QWidget() pip_up_down.setFixedHeight(70) pip_up_down_layout = QVBoxLayout() pip_up_down.setLayout(pip_up_down_layout) up_btn = QToolButton() dw_btn = QToolButton() up_btn.setArrowType(Qt.UpArrow) up_btn.setFixedHeight(25) dw_btn.setArrowType(Qt.DownArrow) dw_btn.setFixedHeight(25) pip_up_down_layout.addWidget(up_btn) pip_up_down_layout.addWidget(dw_btn) string_label = QLabel() string_label.setText(label) string_label.setFixedWidth(210) btn = QtWidgets.QPushButton() btn.setFixedSize(20, 20) pixmap_icon = QtGui.QPixmap("./assets/images/delete_x_white.png") q_icon = QtGui.QIcon(pixmap_icon) btn.setIcon(q_icon) pip_main_layout.addWidget(pip_up_down, Qt.AlignVCenter) pip_main_layout.addWidget(pixmap_label, Qt.AlignVCenter) pip_main_layout.addWidget(string_label, Qt.AlignLeft) pip_main_layout.addWidget(btn, Qt.AlignVCenter) self.pip_widget_vbox_layout.insertWidget(position, pip_main_widget) # Create the corresponding settings widget and connect it self.settings_collapsable.setTitle("Settings") self.stackedWidget_Settings.hide() settings_main_widget = None if not new_marker: settings_main_widget = self.load_settings_widgets_from_pipeline_groupbox(position) self.stackedWidget_Settings.insertWidget(position, settings_main_widget) def show_settings(): # Set background color while widget is selected. Doesn't work because of theme? *TODO* p = pip_main_widget.palette() p.setColor(pip_main_widget.backgroundRole(), Qt.red) pip_main_widget.setPalette(p) if not new_marker: self.stackedWidget_Settings.show() self.stackedWidget_Settings.setCurrentIndex(self.pipeline.get_index(cat)) self.settings_collapsable.setTitle(alg.get_name() + " Settings") else: self.stackedWidget_Settings.hide() # Create drop down for cats and algs self.remove_cat_alg_dropdown() self.create_cat_alg_dropdown(self.pipeline.get_index(cat), pip_main_widget, settings_main_widget) if not new_marker: self.set_cat_alg_dropdown(cat, alg) # Connect Button to remove step from pipeline def delete_button_clicked(): self.remove_cat_alg_dropdown() self.remove_pip_entry(pip_main_widget, settings_main_widget, cat) self.clickable(pixmap_label).connect(show_settings) self.clickable(string_label).connect(show_settings) btn.clicked.connect(delete_button_clicked) return (pip_main_widget, settings_main_widget) def add_pip_entry_empty(self): """ Creates an blank entry in the ui pipeline since the user still needs to specify a type and an algorithm of the category. It also creates the corresponding settings widget. """ # create an widget that displays the pip entry in the ui and connect the remove button pip_main_widget = QWidget() pip_main_widget.setFixedHeight(70) pip_main_widget.setFixedWidth(300) pip_main_layout = QHBoxLayout() pip_main_widget.setLayout(pip_main_layout) label = "<Click to specify new step>" icon = None pixmap = QPixmap(icon) pixmap_scaled_keeping_aspec = pixmap.scaled(30, 30, QtCore.Qt.KeepAspectRatio) pixmap_label = QtWidgets.QLabel() pixmap_label.setPixmap(pixmap_scaled_keeping_aspec) pip_up_down = QWidget() pip_up_down.setFixedHeight(70) pip_up_down_layout = QVBoxLayout() pip_up_down.setLayout(pip_up_down_layout) up_btn = QToolButton() dw_btn = QToolButton() up_btn.setArrowType(Qt.UpArrow) up_btn.setFixedHeight(25) dw_btn.setArrowType(Qt.DownArrow) dw_btn.setFixedHeight(25) pip_up_down_layout.addWidget(up_btn) pip_up_down_layout.addWidget(dw_btn) string_label = QLabel() string_label.setText(label) string_label.setFixedWidth(210) btn = QtWidgets.QPushButton() btn.setFixedSize(20, 20) pixmap_icon = QtGui.QPixmap("./assets/images/delete_x_white.png") q_icon = QtGui.QIcon(pixmap_icon) btn.setIcon(q_icon) pip_main_layout.addWidget(pip_up_down, Qt.AlignVCenter) pip_main_layout.addWidget(pixmap_label, Qt.AlignVCenter) pip_main_layout.addWidget(string_label, Qt.AlignLeft) pip_main_layout.addWidget(btn, Qt.AlignVCenter) cat_position = len(self.pipeline.executed_cats) self.pip_widget_vbox_layout.insertWidget(cat_position, pip_main_widget) index = self.pip_widget_vbox_layout.indexOf(pip_main_widget) #print(index) # Create the corresponding empty settings widget and connect it # settings = self.load_widgets_from_cat_groupbox(cat_position) *TODO* EMPTY self.settings_collapsable.setTitle("Settings") self.stackedWidget_Settings.hide() # Add new step to pipeline new_category = self.pipeline.new_category(cat_position) print("Create new entry " + str(new_category)) print("Pipeline length: " + str(len(self.pipeline.executed_cats)) + ".") settings_main_widget = None # Connect pipeline entry with corresponding settings widget def show_settings(): #print("click") self.stackedWidget_Settings.show() self.remove_cat_alg_dropdown() # Create drop down for cats and algs self.create_cat_alg_dropdown(self.pipeline.get_index(new_category), pip_main_widget, settings_main_widget) self.stackedWidget_Settings.hide() # Connect Button to remove step from pipeline def delete_button_clicked(): self.remove_cat_alg_dropdown() self.remove_pip_entry(pip_main_widget, settings_main_widget, new_category) self.clickable(pixmap_label).connect(show_settings) self.clickable(string_label).connect(show_settings) btn.clicked.connect(delete_button_clicked) self.scroll_down_pip() def add_pip_entry(self, cat_position): """ Creates a entry in the ui pipeline with a given position in pipeline. It also creates the corresponding settings widget. """ # create an widget that displays the pip entry in the ui and connect the remove button pip_main_widget = QWidget() pip_main_widget.setFixedHeight(70) pip_main_widget.setFixedWidth(300) pip_main_layout = QHBoxLayout() pip_main_widget.setLayout(pip_main_layout) cat = self.pipeline.executed_cats[cat_position] alg = cat.active_algorithm label = alg.get_name() icon = cat.get_icon() pixmap = QPixmap(icon) pixmap_scaled_keeping_aspec = pixmap.scaled(30, 30, QtCore.Qt.KeepAspectRatio) pixmap_label = QtWidgets.QLabel() pixmap_label.setPixmap(pixmap_scaled_keeping_aspec) pip_up_down = QWidget() pip_up_down.setFixedHeight(70) pip_up_down_layout = QVBoxLayout() pip_up_down.setLayout(pip_up_down_layout) up_btn = QToolButton() dw_btn = QToolButton() up_btn.setArrowType(Qt.UpArrow) up_btn.setFixedHeight(25) dw_btn.setArrowType(Qt.DownArrow) dw_btn.setFixedHeight(25) pip_up_down_layout.addWidget(up_btn) pip_up_down_layout.addWidget(dw_btn) string_label = QLabel() string_label.setText(label) string_label.setFixedWidth(210) btn = QtWidgets.QPushButton() btn.setFixedSize(20, 20) pixmap_icon = QtGui.QPixmap("./assets/images/delete_x_white.png") q_icon = QtGui.QIcon(pixmap_icon) btn.setIcon(q_icon) pip_main_layout.addWidget(pip_up_down, Qt.AlignVCenter) pip_main_layout.addWidget(pixmap_label, Qt.AlignVCenter) pip_main_layout.addWidget(string_label, Qt.AlignLeft) pip_main_layout.addWidget(btn, Qt.AlignVCenter) self.pip_widget_vbox_layout.insertWidget(cat_position, pip_main_widget) index = self.pip_widget_vbox_layout.indexOf(pip_main_widget) #print(index) # Create the corresponding settings widget and connect it settings_main_widget = self.load_settings_widgets_from_pipeline_groupbox(cat_position) self.settings_collapsable.setTitle("Settings") self.stackedWidget_Settings.hide() self.stackedWidget_Settings.insertWidget(cat_position, settings_main_widget) #print("Read from pipeline entry " + str(cat)) #print("Pipeline length: " + str(len(self.pipeline.executed_cats)) + ".") def show_settings(): # Set background color while widget is selected. Doesn't work because of theme? *TODO* p = pip_main_widget.palette() p.setColor(pip_main_widget.backgroundRole(), Qt.red) pip_main_widget.setPalette(p) self.stackedWidget_Settings.show() self.stackedWidget_Settings.setCurrentIndex(self.pipeline.get_index(cat)) self.settings_collapsable.setTitle(alg.get_name() + " Settings") self.remove_cat_alg_dropdown() # Create drop down for cats and algs self.create_cat_alg_dropdown(self.pipeline.get_index(cat), pip_main_widget, settings_main_widget) #print(cat) #print(alg) self.set_cat_alg_dropdown(cat, alg) # Connect Button to remove step from pipeline def delete_button_clicked(): self.remove_pip_entry(pip_main_widget, settings_main_widget, cat) self.clickable(pixmap_label).connect(show_settings) self.clickable(string_label).connect(show_settings) btn.clicked.connect(delete_button_clicked) return (pip_main_widget, settings_main_widget) # https://wiki.python.org/moin/PyQt/Making%20non-clickable%20widgets%20clickable def clickable(self, widget): """ Convert any widget to a clickable widget. """ class Filter(QObject): clicked = pyqtSignal() def eventFilter(self, obj, event): if obj == widget: if event.type() == QEvent.MouseButtonPress: if obj.rect().contains(event.pos()): self.clicked.emit() # The developer can opt for .emit(obj) to get the object within the slot. return True return False filter = Filter(widget) widget.installEventFilter(filter) return filter.clicked
class userWindow(QWidget): def __init__(self, con): super().__init__() self.con = con self.setGeometry(1500, 400, 900, 500) self.setFixedSize(self.size()) self.setWindowTitle('Пользователи') self.add_btn = QPushButton('Добавить пользователя', self) self.add_btn.move(20, 460) self.add_btn.resize(200, 30) self.add_btn.clicked.connect(self.add_clicked) self.delete_btn = QPushButton('Удалить пользователя', self) self.delete_btn.move(320, 460) self.delete_btn.resize(200, 30) self.delete_btn.clicked.connect(self.delete_clicked) self.title_label = QLabel('', self) self.title_label.move(580, 30) self.title_label.setFont(QFont('Helvetica', 18)) self.title_label_delete = QLabel('', self) self.title_label_delete.move(630, 30) self.title_label_delete.setFont(QFont('Helvetica', 18)) self.login_label = QLabel('Логин', self) self.login_label.move(570, 100) self.password_label = QLabel('Пароль', self) self.password_label.move(570, 150) self.log_id_combobox = QComboBox(self) self.log_id_combobox.move(675, 100) self.log_id_combobox.resize(163, 20) self.log_id_edit = QLineEdit(self) self.log_id_edit.move(680, 300) self.log_id_edit.resize(150, 20) self.password = QLineEdit(self) self.password.move(680, 150) self.password.resize(150, 20) self.login = QLineEdit(self) self.login.move(680, 100) self.login.resize(150, 20) self.apply_btn1 = QPushButton('', self) self.apply_btn1.move(670, 200) self.apply_btn1.resize(165, 30) self.commit_btn = QPushButton('Сохранить', self) self.commit_btn.move(570, 460) self.commit_btn.resize(150, 30) self.commit_btn.clicked.connect(self.commit_clicked) self.rollback_btn = QPushButton('Отменить', self) self.rollback_btn.move(740, 460) self.rollback_btn.resize(150, 30) self.rollback_btn.clicked.connect(self.rollback_clicked) self.apply_btn1.clicked.connect(self.apply1_clicked) self.table = QTableWidget(self) self.table.setColumnCount(3) self.table.resize(520, 450) self.table.setColumnWidth(0, 30) self.table.setColumnWidth(1, 220) self.table.setColumnWidth(2, 250) self.update_table() self.update_combobox() self.hide_all() def update_table(self): cur = self.con.cursor() cur.execute('select count(*) from Users_GUI') self.N_ROWS = cur.fetchone()[0] self.table.setRowCount(self.N_ROWS) self.table.setHorizontalHeaderLabels(['ID', 'Логин', 'Хеш пароля']) cur.execute('select * from Users_GUI') l = cur.fetchall() ll = [] for el in l: ll.append(list(el)) for i in range(0, self.N_ROWS): for j in range(0, 3): self.table.setItem(i, j, QTableWidgetItem(str(ll[i][j]))) def add_clicked(self): self.hide_all() self.title_label.setText('Введите нового пользователя') self.title_label.show() self.login_label.show() self.password_label.show() self.login.show() self.password.show() self.apply_btn1.setText('Добавить') self.rollback_btn.setText('Отменить') self.apply_btn1.show() self.rollback_btn.show() self.commit_btn.show() ##self.update_combobox() def delete_clicked(self): self.hide_all() self.title_label_delete.setText('Удалите пользователя') self.title_label_delete.show() self.login_label.show() self.log_id_combobox.show() self.apply_btn1.setText('Удалить') self.rollback_btn.setText('Отменить') self.apply_btn1.show() self.rollback_btn.show() self.commit_btn.show() self.update_combobox() def update_combobox(self): cur = self.con.cursor() self.log_id_combobox.clear() cur.execute("select id, user_name from users_gui order by id") l = cur.fetchall() for id in l: self.log_id_combobox.addItem('{} - {}'.format(id[0], id[1])) self.log_id_combobox.setCurrentIndex(0) def hide_all(self): self.title_label.setVisible(False) self.title_label_delete.setVisible(False) self.login_label.setVisible(False) self.password_label.setVisible(False) self.log_id_combobox.hide() self.password.hide() self.login.hide() self.log_id_edit.hide() self.apply_btn1.hide() self.rollback_btn.hide() self.commit_btn.hide() ##self.update_table() def apply1_clicked(self): if self.apply_btn1.text() == 'Добавить': self.add_user() elif self.apply_btn1.text() == 'Удалить': self.delete_user() def commit_clicked(self): self.con.commit() def rollback_clicked(self): self.con.rollback() self.update_table() self.update_combobox() def delete_user(self): try: cur = self.con.cursor() query = r"DELETE from Users_GUI " \ r"where id = {}".format(self.log_id_combobox.currentText().split()[0]) cur.execute(query) self.update_table() self.update_combobox() self.update_table() except: error_d = QMessageBox() error_d.setIcon(QMessageBox.Critical) error_d.setText("Ошибка удаления данных") error_d.setWindowTitle("Ошибка!") error_d.exec_() def add_user(self): try: curs = self.con.cursor() query =r"INSERT INTO Users_GUI (user_name, password_user) " \ r"VALUES ('{}', ORA_HASH('{}'))".format(self.login.text(), self.password.text()) curs.execute(query) self.update_table() except: error_d = QMessageBox() error_d.setIcon(QMessageBox.Critical) error_d.setWindowTitle("Ошибка!") error_d.setText("Такой пользователь уже есть в базе данных!") error_d.exec_() return
class ActionBar(QFrame): """ SIGNALS: @changeCurrent(PyQt_PyObject) @runFile(QString) @reopenTab(QString) @recentTabsModified() """ change_current = pyqtSignal('PyQt_PyObject', int) splitEditor = pyqtSignal(bool) runFile = pyqtSignal('QString') closeSplit = pyqtSignal() addToProject = pyqtSignal('QString') showFileInExplorer = pyqtSignal('QString') goToSymbol = pyqtSignal(int) undockEditor = pyqtSignal() reopenTab = pyqtSignal('QString') closeImageViewer = pyqtSignal(int) needUpdateFocus = pyqtSignal() def __init__(self, main_combo=False): super(ActionBar, self).__init__() self.setAutoFillBackground(True) self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) self.setObjectName("actionbar") hbox = QHBoxLayout(self) hbox.setContentsMargins(1, 0, 0, 0) hbox.setSpacing(1) self.combo_files = ComboFiles(self) self.combo_files.setObjectName("combotab") # self.combo_files.setSizePolicy( # QSizePolicy.Expanding, QSizePolicy.Fixed) self.combo_files.setSizeAdjustPolicy( QComboBox.AdjustToMinimumContentsLengthWithIcon) self.combo_files.setMaximumWidth(400) self.combo_files.currentIndexChanged[int].connect(self.current_changed) self.combo_files.setToolTip(translations.TR_COMBO_FILE_TOOLTIP) self.combo_files.setContextMenuPolicy(Qt.CustomContextMenu) self.combo_files.customContextMenuRequested.connect( self._context_menu_requested) hbox.addWidget(self.combo_files) self.symbols_combo = QComboBox() self.symbols_combo.setObjectName("combo_symbols") # For correctly style sheet self.symbols_combo.setItemDelegate(QStyledItemDelegate()) self.symbols_combo.setModel(Model([])) self.symbols_combo.setSizeAdjustPolicy( QComboBox.AdjustToMinimumContentsLengthWithIcon) self.symbols_combo.activated[int].connect(self.current_symbol_changed) hbox.addWidget(self.symbols_combo) # Code Navigator actions self.code_navigator = CodeNavigator() hbox.addWidget(self.code_navigator) # Image Viewer actions self.image_viewer_controls = ImageViewerControls() self.image_viewer_controls.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Fixed) self.image_viewer_controls.setVisible(False) hbox.addWidget(self.image_viewer_controls) self._pos_text = "Line: %d, Col: %d" self.lbl_position = QLabel() self.lbl_position.setObjectName("position") self.lbl_position.setText(self._pos_text % (0, 0)) margin = self.style().pixelMetric( QStyle.PM_LayoutHorizontalSpacing) / 2 self.lbl_position.setContentsMargins(margin, 0, margin, 0) self.lbl_position.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) hbox.addWidget(self.lbl_position) self.btn_close = QPushButton() self.btn_close.setIcon( self.style().standardIcon(QStyle.SP_DialogCloseButton)) if main_combo: self.btn_close.setObjectName('close_button_combo') self.btn_close.setToolTip(translations.TR_CLOSE_FILE) self.btn_close.clicked.connect(self.about_to_close_file) else: self.btn_close.setObjectName('close_split') self.btn_close.setToolTip(translations.TR_CLOSE_SPLIT) self.btn_close.clicked.connect(lambda: self.closeSplit.emit()) self.btn_close.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Minimum) hbox.addWidget(self.btn_close) # Added for set language def resizeEvent(self, event): super(ActionBar, self).resizeEvent(event) if event.size().width() < 400: self.symbols_combo.hide() self.code_navigator.hide() self.lbl_position.hide() elif not self.image_viewer_controls.isVisible(): self.symbols_combo.show() self.code_navigator.show() self.lbl_position.show() def add_item(self, text, neditable): """Add a new item to the combo and add the neditable data.""" self.combo_files.addItem(text, neditable) self.combo_files.setCurrentIndex(self.combo_files.count() - 1) def get_editables(self): editables = [] for index in range(self.combo_files.count()): neditable = self.combo_files.itemData(index) editables.append(neditable) return editables def add_symbols(self, symbols): """Add the symbols to thcurrente symbols's combo.""" mo = Model(symbols) self.symbols_combo.setModel(mo) def set_current_symbol(self, index): self.symbols_combo.setCurrentIndex(index + 1) def update_item_icon(self, neditable, icon): index = self.combo_files.findData(neditable) self.combo_files.setItemIcon(index, icon) def update_item_text(self, neditable, text): index = self.combo_files.findData(neditable) self.combo_files.setItemText(index, text) def current_changed(self, index): """Change the current item in the combo.""" if index != -1: neditable = self.combo_files.itemData(index) self.change_current.emit(neditable, index) def current_symbol_changed(self, index): """Change the current symbol in the combo.""" if index == 0: return self.goToSymbol.emit(index - 1) def set_language_combo_changed(self, index): """Change the current language of editor.""" self._setter_language.set_language_to_editor(index) def update_line_col(self, line, col): """Update the line and column position.""" self.lbl_position.setText(self._pos_text % (line, col)) def _context_menu_requested(self, point): """Display context menu for the combo file.""" if self.combo_files.count() == 0: # If there is not an Editor opened, don't show the menu return menu = QMenu() action_add = menu.addAction(translations.TR_ADD_TO_PROJECT) action_run = menu.addAction(translations.TR_RUN_FILE) action_show_folder = menu.addAction( translations.TR_SHOW_CONTAINING_FOLDER) menu.addSeparator() action_close = menu.addAction(translations.TR_CLOSE_FILE) action_close_all = menu.addAction(translations.TR_CLOSE_ALL_FILES) action_close_all_not_this = menu.addAction( translations.TR_CLOSE_OTHER_FILES) menu.addSeparator() action_copy_path = menu.addAction( translations.TR_COPY_FILE_PATH_TO_CLIPBOARD) action_show_file_in_explorer = menu.addAction( translations.TR_SHOW_FILE_IN_EXPLORER) action_reopen = menu.addAction(translations.TR_REOPEN_FILE) action_undock = menu.addAction(translations.TR_UNDOCK_EDITOR) main_container = IDE.get_service("main_container") if not main_container.last_opened_files: action_reopen.setEnabled(False) # set language action # Connect actions action_close.triggered.connect(self.about_to_close_file) action_close_all.triggered.connect(self._close_all_files) action_close_all_not_this.triggered.connect( self._close_all_files_except_this) action_run.triggered.connect(self._run_this_file) action_undock.triggered.connect(self._undock_editor) action_show_folder.triggered.connect(self._show_containing_folder) action_copy_path.triggered.connect(self._copy_file_location) action_show_file_in_explorer.triggered.connect( self._show_file_in_explorer) action_add.triggered.connect(self._add_to_project) action_reopen.triggered.connect(self._reopen_last_tab) # self.connect(actionSplitH, SIGNAL("triggered()"), # lambda: self._split(False)) # self.connect(actionSplitV, SIGNAL("triggered()"), # lambda: self._split(True)) menu.exec_(QCursor.pos()) def _set_list_languages(self, menu_set_language): for lang in self._setter_language.get_list_of_language(): if lang is None: continue action = menu_set_language.addAction(lang) action.triggered.connect(lambda checked, language=lang: self._set_language_action(language)) def _set_language_action(self, language): self._setter_language.set_language_to_editor(language) def _show_containing_folder(self): main_container = IDE.get_service("main_container") editor_widget = main_container.get_current_editor() filename = editor_widget.file_path file_manager.show_containing_folder(filename) def _create_menu_syntax(self, menuSyntax): """Create Menu with the list of syntax supported.""" syntax = sorted(settings.SYNTAX.keys()) for syn in syntax: menuSyntax.addAction(syn) # self.connect(menuSyntax, SIGNAL("triggered(QAction*)"), # self._reapply_syntax) def _reapply_syntax(self, syntaxAction): # TODO if [self.currentIndex(), syntaxAction] != self._resyntax: self._resyntax = [self.currentIndex(), syntaxAction] # self.emit(SIGNAL("syntaxChanged(QWidget, QString)"), # self.currentWidget(), syntaxAction.text()) def set_current_file(self, neditable): index = self.combo_files.findData(neditable) self.combo_files.setCurrentIndex(index) def set_current_by_index(self, index): self.combo_files.setCurrentIndex(index) @pyqtSlot() def about_to_close_file(self, index=None): """Close the NFile or ImageViewer object.""" parent = self.parent().parentWidget() # Splitter if parent.count() > 1: return if index is None: index = self.combo_files.currentIndex() if index == -1: return neditable = self.combo_files.itemData(index) if neditable: neditable.nfile.close() else: # Image viewer self.combo_files.removeItem(index) self.closeImageViewer.emit(index) def close_split(self): self.closeSplit.emit() def close_file(self, neditable): """Receive the confirmation to close the file.""" index = self.combo_files.findData(neditable) self.combo_files.removeItem(index) return index def _run_this_file(self): """Execute the current file""" neditable = self.combo_files.itemData(self.combo_files.currentIndex()) self.runFile.emit(neditable.file_path) def _add_to_project(self): """Emit a signal to let someone handle the inclusion of the file inside a project.""" neditable = self.combo_files.itemData(self.combo_files.currentIndex()) self.addToProject.emit(neditable.file_path) def _show_file_in_explorer(self): """Triggered when the "Show File in Explorer" context menu action is selected. Emits the "showFileInExplorer(QString)" signal with the current file's full path as argument.""" neditable = self.combo_files.itemData(self.combo_files.currentIndex()) self.showFileInExplorer.emit(neditable.file_path) def _reopen_last_tab(self): main_container = IDE.get_service("main_container") last_closed = main_container.last_opened_files[0] self.reopenTab.emit(last_closed) def _undock_editor(self): self.undockEditor.emit() def _split(self, orientation): print("emitir splitEditor") def _copy_file_location(self): """Copy the path of the current opened file to the clipboard.""" neditable = self.combo_files.itemData(self.combo_files.currentIndex()) QApplication.clipboard().setText(neditable.file_path, QClipboard.Clipboard) def _close_all_files(self): """Close all the files opened.""" for i in range(self.combo_files.count()): self.about_to_close_file(0) def _close_all_files_except_this(self): """Close all the files except the current one.""" neditable = self.combo_files.itemData(self.combo_files.currentIndex()) for i in reversed(list(range(self.combo_files.count()))): ne = self.combo_files.itemData(i) if ne is not neditable: self.about_to_close_file(i)
class ConfigTab(TraceDocks): ## The constructor # initialize the super-class, assign a name and first configItems def __init__(self,parent): super(ConfigTab, self).__init__(parent,'ConfigTab') self.tabName = 'ConfigTab' self.logger.logEvent('Creating Tab now: '+ self.tabName) # Set a couple of default-values, in case the configParser does not work self.snifferConfig.configBaud = 1000000 self.snifferConfig.configCom = 'COM4' self.snifferConfig.configMode = 'Singleshot' self.snifferConfig.configParity = 'None' self.snifferConfig.configStopBits = 0 self.snifferConfig.configTimeBytes = 2 self.snifferConfig.configTrigger = 'Start' self.snifferConfig.configLogCheck = 0 self.snifferConfig.configIncTimeCheck = 0 self.snifferConfig.configTickToMsLine = 1000 self.snifferConfig.configSingleDurLine = 3000 self.snifferConfig.configMaxTickCountVal = 65536 self.snifferConfig.configUpDownState = 'Up' self.snifferConfig.configCurrentTheme = 'Dark' # By parsing the config now, we assure that we re-load everything # the way we left it self.snifferConfig.parseConfigFromFile() # Create necessary Lists self.COMList = OsSniffer.OS_SerialPortList() self.BAUDList = ['110','300','600','1200','2400','4800','9600','14400','19200','38400','57600','115200','128000','256000','921600','1000000','2000000'] self.STOPList = ['0','1','2'] self.PARITYList = ['None','Even','Odd'] self.MODEList = ['Singleshot','Continuous','Trigger'] self.TRIGGERList = [] for triggers in Globals.tspDict.items(): self.TRIGGERList.append(triggers[1][0]) self.INACTIVEList = ['INACTIVE'] # We need a list for the items and one for the actual Values ## Create the visible UI def setConfigTabLayout(self): # Create Configurations Tab --------------------### # Create Layouts self.Vlayout = QVBoxLayout() self.H1layout = QHBoxLayout() self.H1layout.setSpacing(10) self.H1SubV1Layout = QVBoxLayout() self.H1SubV1H1Layout = QHBoxLayout() self.H1SubV1H2Layout = QHBoxLayout() self.H1SubV1H3Layout = QHBoxLayout() self.H1SubV1H4Layout = QHBoxLayout() self.H1SubV1H5Layout = QHBoxLayout() self.H1SubV2Layout = QVBoxLayout() self.H1SubV2H1Layout = QHBoxLayout() self.H1SubV2H2Layout = QHBoxLayout() self.H1SubV2H3Layout = QHBoxLayout() self.H1SubV2H4Layout = QHBoxLayout() self.H1SubV2H5Layout = QHBoxLayout() self.H1SubV2H6Layout = QHBoxLayout() self.H1SubV2H7Layout = QHBoxLayout() self.H1SubV2H8Layout = QHBoxLayout() #------------------------------------ # Create Widgets TextBox #------------------------------------ # First Buttons self.saveLogButt = QPushButton('Save Logfile') self.saveConfigButt = QPushButton('Save Configuration') self.toggleThemeButt = QPushButton('Toggle Theme') self.refreshComButt = QPushButton('Refresh COM') # Then Checkbox and Comboboxes self.saveLogCheck = QCheckBox('Activate Logging') self.saveIncTimeCheck = QCheckBox('Save Inc_Tick Data') self.labelSerial = QLabel('Serial Configuration') self.labelCOM = QLabel('COM-PORT') self.labelBAUD = QLabel('BAUD-RATE') self.labelSTOP= QLabel('STOP-BITS') self.labelPARITY= QLabel('PARITY') self.labelMeasure = QLabel('Measurement Configuration') self.labelMODE = QLabel('MEASUREMENT MODE') self.labelSINGLETIME = QLabel('MEASUREMENT TIME') self.labelTRIGGER = QLabel('TRIGGER TYPE') self.labelRATIO = QLabel('TICK TO MS RATIO') self.labelMaxTickCount = QLabel('MAX TICKOUT VAL') self.labelUpDownCount = QLabel('SELECT UP OR DOWN COUNTER') self.inputSingleDurBox = QLineEdit() self.inputSingleDurBox.setText('Duration(ticks)') #self.inputSingleDurBox.setMaximumWidth(20) self.inputTickToMsBox = QLineEdit() self.inputTickToMsBox.setText('Set Ticks to Ms Ratio') #self.inputTickToMsBox.setMaximumWidth(200) self.inputMaxTickCount = QLineEdit() self.inputMaxTickCount.setText('Set Maximum Tickcount Val') self.comboMODE = QComboBox() self.comboMODE.addItems(self.MODEList) self.comboCOM = QComboBox() self.comboCOM.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.comboCOM.addItems(self.COMList) self.comboBAUD = QComboBox() self.comboBAUD.addItems(self.BAUDList) self.comboBAUD.setEditable(True) self.comboSTOP = QComboBox() self.comboSTOP.addItems(self.STOPList) self.comboPARITY = QComboBox() self.comboPARITY.addItems(self.PARITYList) self.comboTRIGGER = QComboBox() self.comboTRIGGER.addItems(self.TRIGGERList) self.upCountRadio = QRadioButton('Up',self) self.downCountRadio = QRadioButton('Down', self) # We need to sync the UI before connecting any slots in order to prevent accidental stateChanges. self.syncUiToConfig() #--- SIGNAL/SLOT CONNECTIONS ---# # Button Signal/Slot connections self.saveLogButt.clicked.connect(self.saveLog) for keys, values in dockDict.items(): # We need to connect EVERY tab in order to save the ConfigurationData self.saveConfigButt.clicked.connect(values.snifferConfig.saveConfigToFile) self.saveConfigButt.clicked.connect(self.snifferConfig.saveConfigToFile) self.toggleThemeButt.clicked.connect(self.toggleTheme) self.refreshComButt.clicked.connect(self.refreshCom) # Checkbox Signal/Slot connections self.saveLogCheck.stateChanged.connect(self.checkSaveLogChanged) self.saveIncTimeCheck.stateChanged.connect(self.checkSaveInctimeChanged) # Lineedit Signal/Slot connections self.inputSingleDurBox.textChanged.connect(self.lineSingleDurChanged) self.inputTickToMsBox.textChanged.connect(self.lineTickToMsChanged) self.inputMaxTickCount.textChanged.connect(self.lineMaxTickCountChanged) # Combobox Signal/Slot connections self.comboMODE.currentIndexChanged[int].connect(self.comboModeChanged) self.comboCOM.currentIndexChanged[int].connect(self.comboComChanged) self.comboBAUD.currentIndexChanged[int].connect(self.comboBaudChanged) self.comboBAUD.currentTextChanged.connect(self.comboBaudChanged) self.comboSTOP.currentIndexChanged[int].connect(self.comboStopBitsChanged) self.comboPARITY.currentIndexChanged[int].connect(self.comboParityChanged) self.comboTRIGGER.currentIndexChanged[int].connect(self.comboTriggerChanged) # Radio button connections self.upCountRadio.clicked.connect(self.upCountRadioSelected) self.downCountRadio.clicked.connect(self.downCountRadioSelected) # Add the Widgets to the corresponding Layouts self.H1SubV1H1Layout.addWidget(self.labelCOM) self.H1SubV1H1Layout.addWidget(self.refreshComButt) self.H1SubV1H1Layout.addWidget(self.comboCOM) self.H1SubV1H2Layout.addWidget(self.labelBAUD) self.H1SubV1H2Layout.addWidget(self.comboBAUD) self.H1SubV1H3Layout.addWidget(self.labelSTOP) self.H1SubV1H3Layout.addWidget(self.comboSTOP) self.H1SubV1H4Layout.addWidget(self.labelPARITY) self.H1SubV1H4Layout.addWidget(self.comboPARITY) self.H1SubV1Layout.addWidget(self.labelSerial) self.H1SubV1Layout.addLayout(self.H1SubV1H1Layout) self.H1SubV1Layout.addLayout(self.H1SubV1H2Layout) self.H1SubV1Layout.addLayout(self.H1SubV1H3Layout) self.H1SubV1Layout.addLayout(self.H1SubV1H4Layout) self.H1SubV1Layout.addStretch() self.H1SubV2H1Layout.addWidget(self.labelMODE) self.H1SubV2H1Layout.addWidget(self.comboMODE) self.H1SubV2H2Layout.addWidget(self.labelSINGLETIME) self.H1SubV2H2Layout.addWidget(self.inputSingleDurBox) self.H1SubV2H3Layout.addWidget(self.labelTRIGGER) self.H1SubV2H3Layout.addWidget(self.comboTRIGGER) self.H1SubV2H5Layout.addWidget(self.saveIncTimeCheck) self.H1SubV2H5Layout.addWidget(self.saveLogCheck) self.H1SubV2H5Layout.addWidget(self.saveLogButt) self.H1SubV2H5Layout.addWidget(self.toggleThemeButt) self.H1SubV2H6Layout.addWidget(self.labelRATIO) self.H1SubV2H6Layout.addWidget(self.inputTickToMsBox) self.H1SubV2H7Layout.addWidget(self.labelMaxTickCount) self.H1SubV2H7Layout.addWidget(self.inputMaxTickCount) self.H1SubV2H8Layout.addWidget(self.labelUpDownCount) self.H1SubV2H8Layout.addWidget(self.upCountRadio) self.H1SubV2H8Layout.addWidget(self.downCountRadio) self.H1SubV2Layout.addWidget(self.labelMeasure) self.H1SubV2Layout.addLayout(self.H1SubV2H1Layout) self.H1SubV2Layout.addLayout(self.H1SubV2H2Layout) self.H1SubV2Layout.addLayout(self.H1SubV2H3Layout) self.H1SubV2Layout.addLayout(self.H1SubV2H4Layout) self.H1SubV2Layout.addLayout(self.H1SubV2H5Layout) self.H1SubV2Layout.addLayout(self.H1SubV2H6Layout) self.H1SubV2Layout.addLayout(self.H1SubV2H7Layout) self.H1SubV2Layout.addLayout(self.H1SubV2H8Layout) self.H1SubV2Layout.addStretch() self.H1layout.addLayout(self.H1SubV1Layout) self.H1layout.addStretch() self.H1layout.addLayout(self.H1SubV2Layout) self.Vlayout.addLayout(self.H1layout) self.Vlayout.addStretch() self.Vlayout.addWidget(self.saveConfigButt) self.dockContents.setLayout(self.Vlayout) # -- ! We need callbacks to update the actual Values ! --# #---CREATE COMBOBOX Callbacks---# ## CB: comboCOM // Serial COM-Port def comboComChanged(self): self.snifferConfig.configCom = self.COMList[self.comboCOM.currentIndex()] self.logger.logEvent('changed COM-Port to - '+ self.snifferConfig.configCom) ## CB: comboBAUD // Serial BAUD-Rate def comboBaudChanged(self): self.snifferConfig.configBaud = self.comboBAUD.currentText() self.logger.logEvent('changed BAUD-Rate to - '+ self.snifferConfig.configBaud) ## CB: comboSTOP // Serial STOP-bit count def comboStopBitsChanged(self): self.snifferConfig.configStopBits = self.STOPList[self.comboSTOP.currentIndex()] self.logger.logEvent('changed STOP-Bits to - '+ self.snifferConfig.configStopBits) ## CB: comboPARTIY // Serial Parity-bit (odd/even/none) def comboParityChanged(self): self.snifferConfig.configParity = self.PARITYList[self.comboPARITY.currentIndex()] self.logger.logEvent('changed PARITY to - '+ self.snifferConfig.configParity) ## CB: comboMODE // Measurement mode def comboModeChanged(self): # Check which box is checked in order to show the user the necessary info self.snifferConfig.configMode = self.MODEList[self.comboMODE.currentIndex()] if self.snifferConfig.configMode == self.MODEList[0]: self.inputSingleDurBox.show() self.labelSINGLETIME.show() self.comboTRIGGER.hide() self.labelTRIGGER.hide() if self.snifferConfig.configMode == self.MODEList[1]: self.inputSingleDurBox.hide() self.labelSINGLETIME.hide() self.comboTRIGGER.hide() self.labelTRIGGER.hide() if self.snifferConfig.configMode == self.MODEList[2]: self.inputSingleDurBox.show() self.labelSINGLETIME.show() self.comboTRIGGER.show() self.labelTRIGGER.show() self.logger.logEvent('changed Measurement-mode to - '+ self.snifferConfig.configMode) ## CB: comboTRIGGER // the Trigger the measurement waits for (only in TRIGGER-measmode) def comboTriggerChanged(self): self.snifferConfig.configTrigger = self.TRIGGERList[self.comboTRIGGER.currentIndex()] self.logger.logEvent('changed TriggerType to - '+ self.snifferConfig.configTrigger) #---CREATE THEME Callbacks---# ## CB: Toggles the theme between dark and light mode # @details This happens by calling the appropriate function of the parent (QMainwindow), so that the theme # is changed globally def toggleTheme(self): if(self.snifferConfig.configCurrentTheme == 'Light'): self.parent.loadTheme('Dark') #self.parent.tabStart.startStopAnalyzingButt.setStyleSheet('QPushButton:focus {border: 2px solid; border-color: limegreen; background-color: #31363b; border-radius:100px}') else: self.parent.loadTheme('Light') #self.parent.tabStart.startStopAnalyzingButt.setStyleSheet('QPushButton:focus {border: 2px solid; border-color: limegreen; background-color: white; border-radius:100px}') #self.parent.setStartStopButtonStyle() #---CREATE CHECKBOX Callbacks---# ## CB: Handle the SaveLog checkbox event (Toggle) def checkSaveLogChanged(self): self.snifferConfig.configLogCheck ^= 1 if(self.snifferConfig.configLogCheck == 1): self.logger.enableLogs() else: self.logger.disableLogs() self.logger.logEvent('changed LogCheckbox to - '+ str(self.snifferConfig.configLogCheck)) ## CB: Handle the SaveInctime checkbox event (Toggle) def checkSaveInctimeChanged(self): self.snifferConfig.configIncTimeCheck ^= 1 self.logger.logEvent('changed Save Time-Increment Checkbox to - '+ str(self.snifferConfig.configIncTimeCheck)) #---CREATE LINEEDIT Callbacks---# ## CB: Handle the SingleDur lineedit callback (adjust singleshot duration) def lineSingleDurChanged(self): self.snifferConfig.configSingleDurLine = self.inputSingleDurBox.text() self.logger.logEvent('changed Singleshot Duration to - '+ str(self.snifferConfig.configSingleDurLine)) ## CB: Handle the TickToMs lineedit callback (adjust ticks per ms) def lineTickToMsChanged(self): self.snifferConfig.configTickToMsLine = self.inputTickToMsBox.text() self.logger.logEvent('changed Tick To Ms Ratio to - '+ str(self.snifferConfig.configTickToMsLine)) ## CB: Handle the MaxTickCount lineedit callback (adjust maximum tickcount value) def lineMaxTickCountChanged(self): self.snifferConfig.configMaxTickCountVal = self.inputMaxTickCount.text() self.logger.logEvent('changed Max Tickcount Value to - '+ str(self.snifferConfig.configTickToMsLine)) #---CREATE PUSHBUTTON Callbacks---# ## CB: Handle the refreshCOM pushbutton callback (refresh all com-ports) def refreshCom(self): self.COMList = OsSniffer.OS_SerialPortList() self.comboCOM.clear() self.comboCOM.addItems(self.COMList) self.snifferConfig.configCom = self.COMList[self.comboCOM.currentIndex()] #---CREATE RADIO Callbacks---# ## Select upCount def upCountRadioSelected(self): self.snifferConfig.configUpDownState = 'Up' self.logger.logEvent('changed Up/Down Radio to - '+ str(self.snifferConfig.configUpDownState)) ## Select downCount def downCountRadioSelected(self): self.snifferConfig.configUpDownState = 'Down' self.logger.logEvent('changed Up/Down Radio to - '+ str(self.snifferConfig.configUpDownState)) #---CONTENT FUNCTIONS---# ## CB: Saves all logs saved in the logList to a output-file def saveLog(self): print('Trying to save logs') if(len(snifferLogList) == 0): self.displayException('Global Logging List empty. Did you enable the checkbox?') else: self.saveLogDirectory, self.purge = QFileDialog.getSaveFileName(self, 'Save File', '', 'Logfile (*.slog)') print(self.saveLogDirectory) self.logFile = open(self.saveLogDirectory,'a+') for logTuple in snifferLogList: self.logFile.write(str(logTuple[0])+', '+str(logTuple[1])+'\n') self.logFile.close() # --- MANDATORY UI FUNCTIONS --- # # -------------------------------# ## Read out all components of snifferConfig and set the UI elements according to # the saved values. def syncUiToConfig(self): self.inputSingleDurBox.setText(str(self.snifferConfig.configSingleDurLine)) self.inputTickToMsBox.setText(str(self.snifferConfig.configTickToMsLine)) self.inputMaxTickCount.setText(str(self.snifferConfig.configMaxTickCountVal)) self.saveLogCheck.setChecked(self.snifferConfig.configLogCheck) self.saveIncTimeCheck.setChecked(self.snifferConfig.configIncTimeCheck) if self.snifferConfig.configUpDownState == 'Up': self.upCountRadio.click() elif self.snifferConfig.configUpDownState == 'Down': self.downCountRadio.click() else: print('Error, neither up nor down in config') try: self.comboCOM.setCurrentIndex(self.COMList.index(self.snifferConfig.configCom)) except Exception as valException: print('Exception when syncing UI in Configtab: comboCOM - snifferConfig Error') self.comboCOM.setCurrentIndex(0) try: self.comboMODE.setCurrentIndex(self.MODEList.index(self.snifferConfig.configMode)) except Exception as valException: print('Exception when syncing UI in Configtab: comboMODE - snifferConfig Error') self.comboMODE.setCurrentIndex(0) try: self.comboBAUD.setCurrentIndex(self.BAUDList.index(str(self.snifferConfig.configBaud))) except Exception as valException: print('Exception when syncing UI in Configtab: comboBAUD - snifferConfig Error') self.comboBAUD.setCurrentIndex(0) try: self.comboPARITY.setCurrentIndex(self.PARITYList.index(self.snifferConfig.configParity)) except Exception as valException: print('Exception when syncing UI in Configtab: comboPARITY - snifferConfig Error') self.comboPARITY.setCurrentIndex(0) try: self.comboSTOP.setCurrentIndex(self.STOPList.index(str(self.snifferConfig.configStopBits))) except Exception as valException: print('Exception when syncing UI in Configtab: comboSTOP - snifferConfig Error') self.comboSTOP.setCurrentIndex(0) try: self.comboTRIGGER.setCurrentIndex(self.TRIGGERList.index(self.snifferConfig.configTrigger.upper())) except Exception as valException: print('Exception when syncing UI in Configtab: comboTRIGGER - snifferConfig Error') self.comboTRIGGER.setCurrentIndex(0)