class Ui_Widget(object): """ Klasa definiująca GUI """ def setupUi(self, Widget): # widgety rysujące kształty, instancje klasy Ksztalt self.ksztalt1 = Ksztalt(self, Ksztalty.Polygon) self.ksztalt2 = Ksztalt(self, Ksztalty.Ellipse) self.ksztaltAktywny = self.ksztalt1 # przyciski CheckBox ### uklad = QVBoxLayout() # układ pionowy self.grupaChk = QButtonGroup() for i, v in enumerate(('Kwadrat', 'Koło', 'Trójkąt', 'Linia')): self.chk = QCheckBox(v) self.grupaChk.addButton(self.chk, i) uklad.addWidget(self.chk) self.grupaChk.buttons()[self.ksztaltAktywny.ksztalt].setChecked(True) # CheckBox do wyboru aktywnego kształtu self.ksztaltChk = QCheckBox('<=') self.ksztaltChk.setChecked(True) uklad.addWidget(self.ksztaltChk) # układ poziomy dla kształtów oraz przycisków CheckBox ukladH1 = QHBoxLayout() ukladH1.addWidget(self.ksztalt1) ukladH1.addLayout(uklad) ukladH1.addWidget(self.ksztalt2) # koniec CheckBox ### self.setLayout(ukladH1) # przypisanie układu do okna głównego self.setWindowTitle('Widżety')
class Ui_Widget(object): """ Klasa definiująca GUI """ def setupUi(self, Widget): # widgety rysujące kształty, instancje klasy Ksztalt self.ksztalt1 = Ksztalt(self, Ksztalty.Polygon) self.ksztalt2 = Ksztalt(self, Ksztalty.Ellipse) self.ksztaltAktywny = self.ksztalt1 # przyciski CheckBox ### uklad = QVBoxLayout() # układ pionowy self.grupaChk = QButtonGroup() for i, v in enumerate(('Kwadrat', 'Koło', 'Trójkąt', 'Linia')): self.chk = QCheckBox(v) self.grupaChk.addButton(self.chk, i) uklad.addWidget(self.chk) self.grupaChk.buttons()[self.ksztaltAktywny.ksztalt].setChecked(True) # CheckBox do wyboru aktywnego kształtu self.ksztaltChk = QCheckBox('<=') self.ksztaltChk.setChecked(True) uklad.addWidget(self.ksztaltChk) # układ poziomy dla kształtów oraz przycisków CheckBox ukladH1 = QHBoxLayout() ukladH1.addWidget(self.ksztalt1) ukladH1.addLayout(uklad) ukladH1.addWidget(self.ksztalt2) # koniec CheckBox ### self.setLayout(ukladH1) # przypisanie układu do okna głównego self.setWindowTitle('Widżety')
def __init__(self): global poollabel,leniency super().__init__() self.inittray() self.setWindowTitle('PyRsi') layout=QVBoxLayout(); #label poollabel=QLabel(describe()) layout.addWidget(poollabel) #radio group leniency=QButtonGroup(self) lax=QRadioButton("Lax (2:1)") leniency.addButton(lax) layout.addWidget(lax) normal=QRadioButton("Normal (1:1)") leniency.addButton(normal) layout.addWidget(normal) normal.setChecked(True) cautious=QRadioButton("Cautious (2:3)") leniency.addButton(cautious) layout.addWidget(cautious) severe=QRadioButton("Severe (1:2)") leniency.addButton(severe) layout.addWidget(severe) if 'data' in config: leniency.buttons()[int(config['data']['leniency'])].setChecked(True) #add / remove time self.addbuton(f"Add {INCREMENT} minutes",layout,self.moretime) self.addbuton(f"Remove {INCREMENT} minutes",layout,self.lesstime) #hide to tray self.addbuton("Hide",layout,self.totray) self.setLayout(layout)
class Window(QWidget): def __init__(self): super().__init__() self.title = "PyQt ButtonGroup" self.top = 100 self.left = 100 self.width = 400 self.height = 300 self.buttongroup = QButtonGroup() self.hbox = QHBoxLayout() self.label = QLabel(self) self.InitWindow() def InitWindow(self): self.setWindowIcon(QtGui.QIcon("home.png")) self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) #self.buttongroup.buttonClicked[int].connect(self.onButtonClicked) self.buttongroup.buttonPressed[int].connect(self.onButtonPressed) self.buttongroup.buttonReleased[int].connect(self.onButtonReleased) self.buttonGroup() self.hbox.addWidget(self.label) self.setLayout(self.hbox) self.show() def buttonGroup(self): button = QPushButton('Python') self.buttongroup.addButton(button, 1) self.hbox.addWidget(button) button2 = QPushButton('Java') self.buttongroup.addButton(button2, 2) self.hbox.addWidget(button2) button3 = QPushButton('C++') self.buttongroup.addButton(button3, 3) self.hbox.addWidget(button3) def onButtonClicked(self, id): for button in self.buttongroup.buttons(): if button is self.buttongroup.button(id): self.label.setText(button.text() + ' was clicked') def onButtonPressed(self, id): for button in self.buttongroup.buttons(): if button is self.buttongroup.button(id): self.label.setText(button.text() + ' was pressed!') def onButtonReleased(self, id): for button in self.buttongroup.buttons(): if button is self.buttongroup.button(id): self.label.setText(button.text() + ' was released!')
class ButtonBar(QFrame): buttonClicked = pyqtSignal( str, int ) # Indicates the iteration number and iteration name of the button that was clicked def __init__(self, items: t_.Sequence[str], parent=None): super().__init__(parent=parent) # self.setFrameStyle(QFrame.Panel) self._bGroup = QButtonGroup(self) l = QHBoxLayout(self) for i, itemName in enumerate(items): b = QPushButton(itemName, parent=self) b.setCheckable(True) # Toggleable self._bGroup.addButton(b, id=i) l.addWidget(b) self._selectedButtonId = self._bGroup.id(self._bGroup.buttons()[0]) self._bGroup.buttons()[0].click( ) # Make sure at least one button is selected. self._bGroup.buttonClicked.connect(self._buttonSelected) l.setSpacing(1) # Move buttons close together l.setContentsMargins(0, 0, 0, 0) w = QFrame(self) w.setFrameStyle(QFrame.Box) w.setLayout(l) scrollArea = QScrollArea(parent=self) scrollArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) scrollArea.setStyleSheet("""QScrollBar:horizontal { height:10px; }""") scrollArea.setWidget(w) scrollArea.setFixedHeight(10 + w.height()) ll = QHBoxLayout() ll.setContentsMargins(0, 0, 0, 0) ll.addWidget(scrollArea) self.setLayout(ll) def _buttonSelected(self, btn): self._selectedButtonId = self._bGroup.id(btn) self.buttonClicked.emit(btn.text(), self._bGroup.id(btn)) def getSelectedButtonId(self): return self._selectedButtonId def selectNextButton(self): id = self._selectedButtonId + 1 if id >= len(self._bGroup.buttons()): id = 0 self.setButtonSelected(id) def setButtonSelected(self, ID: int): btn = self._bGroup.button(ID) btn.click()
class RadiobuttonItemsView(QDialog): def __init__(self, dbs, selected_db): super().__init__() self.layout = QGridLayout() self.selected_db = selected_db self.dbs = dbs btn_ok = QPushButton('OK', self) btn_ok.clicked.connect(self.ok_pressed) btn_cancel = QPushButton('Cancel', self) btn_cancel.clicked.connect(self.cancel_pressed) scroll = QScrollArea(self) scroll.setWidgetResizable(True) self.content = QWidget() scroll.setWidget(self.content) rb_vbox = QVBoxLayout(self.content) rb_vbox.addStretch(1) self.button_group = QButtonGroup() # btn_vbox = QVBoxLayout() # btn_vbox.addStretch(1) # btn_vbox.addWidget(btn_ok) # btn_vbox.addWidget(btn_cancel) for db in self.dbs: self.button_name = QRadioButton(f"{db}") self.button_name.setObjectName(f"radiobtn_{db}") rb_vbox.addWidget(self.button_name) self.button_group.addButton(self.button_name) self.layout.addWidget(scroll, 0, 0) self.layout.addWidget(btn_ok, 0, 1) self.layout.addWidget(btn_cancel, 0, 2) self.setStyleSheet("QScrollArea{min-width:300 px; min-height: 400px}") self.setLayout(self.layout) self.setModal(True) self.show() def ok_pressed(self): self.selected_db = '' for x in range(len(self.button_group.buttons())): if self.button_group.buttons()[x].isChecked(): self.selected_db = self.button_group.buttons()[x].text() self.close() def cancel_pressed(self): self.close()
def initUI(self): # create menus menu.GuiMenu() menu.WidgetMenu() menu.SettingsMenu() menu.LoggingMenu() # main layout mainVLayout = QVBoxLayout() elementHLayouts = [] # top element: toolbar, status t = QLabel("Toolbar") s = QLabel("Status") toolbarStatusHLayout = QHBoxLayout() toolbarStatusHLayout.addWidget(t) toolbarStatusHLayout.addWidget(s) elementHLayouts.append(toolbarStatusHLayout) # mid element: menu buttons menubuttonsHLayout = QHBoxLayout() stackedButtonsWidget = QStackedWidget() buttonGroup = QButtonGroup(self) buttonGroup.setExclusive(True) for m in menu.Menu.menus: btn = QPushButton(m.name) btn.setCheckable(True) btn.pressed.connect(lambda m=m: stackedButtonsWidget.setCurrentWidget(m)) menubuttonsHLayout.addWidget(btn) buttonGroup.addButton(btn) stackedButtonsWidget.addWidget(m) elementHLayouts.append(menubuttonsHLayout) # bot element: menu specific widgets menuwidgetsHLayout = QHBoxLayout() menuwidgetsHLayout.addWidget(stackedButtonsWidget) elementHLayouts.append(menuwidgetsHLayout) # click first button for defined initial state if len(buttonGroup.buttons()) > 0: buttonGroup.buttons()[0].click() for l in elementHLayouts: mainVLayout.addLayout(l) self.setLayout(mainVLayout)
def set_btn_group_data(button_group: QtWidgets.QButtonGroup, values: Iterable[Any]): """Adds a data_item attribute for all buttons in the button group. The value of the data_item is taken from the given values. No buttons are added or removed. button_group has to contain the same number of buttons as there are values. """ btns = button_group.buttons() if len(btns) != len(values): raise ValueError( "Button group and data must have the same number of items") for btn, value in zip(button_group.buttons(), values): btn.setText(str(value)) btn.data_item = value
def create_button_group(label_name, names): hbox = QHBoxLayout() label = QLabel(label_name) hbox.addWidget(label) group = QButtonGroup() for name in names: btn = QRadioButton(name) group.addButton(btn) hbox.addWidget(btn) group.buttons()[0].setChecked(True) return group, hbox
def set_btn_group_value(button_group: QtWidgets.QButtonGroup, value: Any): """Checks the button whose data_item matches the value. """ for btn in button_group.buttons(): if btn.data_item == value: btn.setChecked(True) break
class RadioButtons(WidgetBridge, Choices): _qttype = QGroupBox def customize(self, widget): assert self.choices, "RadioButtons: Cannot build widget bridge without choices" # We give the GroupBox a container so we can add stretch at the end. self.container = QWidget(self.parent) hbox = QHBoxLayout(self.container) self.buttongroup = QButtonGroup(self.parent) if "direction" in self.config and \ self.config["direction"].lower() == "vertical": box = QVBoxLayout() else: box = QHBoxLayout() ix = 1 for text in self.choicesdict().values(): rb = QRadioButton(text, self.parent) box.addWidget(rb) self.buttongroup.addButton(rb, ix) ix += 1 widget.setLayout(box) hbox.addWidget(widget) hbox.addStretch(1) hbox.setContentsMargins(QMargins(0, 0, 0, 0)) def apply(self, value): for b in self.buttongroup.buttons(): b.setChecked(False) b = self.buttongroup.button(self.index(value) + 1) if b: b.setChecked(True) def retrieve(self): ix = self.buttongroup.checkedId() return self.at(ix - 1) if ix > 0 else None
class Window(QWidget): def __init__(self): super().__init__() self.title = "PyQt5 QButton Group" self.top = 200 self.left = 500 self.width = 400 self.height = 300 self.setWindowTitle(self.title) self.setWindowIcon(QtGui.QIcon("icon.png")) self.setGeometry(self.left, self.top, self.width, self.height) hbox = QHBoxLayout() self.label = QLabel(self) self.label.setFont(QtGui.QFont("Sanserif", 15)) hbox.addWidget(self.label) self.buttongroup = QButtonGroup() #self.buttongroup.setExclusive(False) self.buttongroup.buttonClicked[int].connect(self.on_button_clicked) button = QPushButton("Python") self.buttongroup.addButton(button, 0) button.setFont(QtGui.QFont("Sanserif", 15)) button.setIcon(QtGui.QIcon("pythonicon.png")) button.setIconSize(QtCore.QSize(40, 40)) hbox.addWidget(button) button = QPushButton("Java") self.buttongroup.addButton(button, 1) button.setFont(QtGui.QFont("Sanserif", 15)) button.setIcon(QtGui.QIcon("java.png")) button.setIconSize(QtCore.QSize(40, 40)) hbox.addWidget(button) button = QPushButton("C++") self.buttongroup.addButton(button, 2) button.setFont(QtGui.QFont("Sanserif", 15)) button.setIcon(QtGui.QIcon("cpp.png")) button.setIconSize(QtCore.QSize(40, 40)) hbox.addWidget(button) self.setLayout(hbox) self.show() def on_button_clicked(self, id): print(id) for button in self.buttongroup.buttons(): print(type(button)) if button is self.buttongroup.button(id): self.label.setText(button.text() + " Was Clicked ") self.setWindowTitle("andy") button.setIconSize(QtCore.QSize(60, 60)) print(button.text()) button.setText("andy")
class LocalButtonsConf(OptionsDialogGroupBox): def __init__(self, name, main): self.main = main OptionsDialogGroupBox.__init__(self, name, main) self.buttonBox = QGroupBox("Pins") self.buttonBoxLayout = QVBoxLayout() self.buttonBox.setLayout(self.buttonBoxLayout) def initUI(self): vbox = QVBoxLayout() self.polBox = QCheckBox("Invert") vbox.addWidget(self.polBox) self.buttongroup = QButtonGroup() self.buttongroup.setExclusive(False) vbox.addWidget(self.buttonBox) self.setLayout(vbox) def initButtons(self, num): #delete buttons self.num = num # Remove buttons for i in range(self.buttonBoxLayout.count()): b = self.buttonBoxLayout.takeAt(0) self.buttonBoxLayout.removeItem(b) b.widget().deleteLater() for b in self.buttongroup.buttons(): self.buttongroup.removeButton(b) self.buttonBox.update() for i in range(self.num): cb = QCheckBox(str(i + 1)) self.buttongroup.addButton(cb, i) self.buttonBoxLayout.addWidget(cb) def localcb(mask): for i in range(self.num): self.buttongroup.button(i).setChecked(mask & (1 << i)) self.main.comms.serialGetAsync("local_btnmask?", localcb, int) def apply(self): mask = 0 for i in range(self.num): if (self.buttongroup.button(i).isChecked()): mask |= 1 << i self.main.comms.serialWrite("local_btnmask=" + str(mask)) self.main.comms.serialWrite("local_btnpol=" + ("1" if self.polBox.isChecked() else "0")) def readValues(self): self.main.comms.serialGetAsync("local_btnpins?", self.initButtons, int) self.main.comms.serialGetAsync("local_btnpol?", self.polBox.setChecked, int)
class Window(QWidget): def __init__(self): super().__init__() self.title = 'Button Group' self.top = 200 self.left = 400 self.width = 400 self.height = 200 self.initWindow() def initWindow(self): self.setWindowTitle(self.title) self.setWindowIcon(QtGui.QIcon('avatar.png')) self.setGeometry(self.left, self.top, self.width, self.height) vbox = QVBoxLayout() hbox = QHBoxLayout() self.label = QLabel('This is label', self) self.label.setFont(QtGui.QFont('Sanserif', 13)) vbox.addWidget(self.label) self.buttongroup = QButtonGroup() self.buttongroup.buttonClicked[int].connect(self.on_button_clicked) button = QPushButton('Python') self.buttongroup.addButton(button, 1) self.buttongroup.addButton(button, 1) button.setFont(QtGui.QFont("Sanserif", 13)) button.setIcon(QtGui.QIcon("avatar.png")) button.setIconSize(QtCore.QSize(15, 15)) hbox.addWidget(button) button = QPushButton("Java") self.buttongroup.addButton(button, 2) button.setFont(QtGui.QFont("Sanserif", 13)) button.setIcon(QtGui.QIcon("avatar.png")) button.setIconSize(QtCore.QSize(15, 15)) hbox.addWidget(button) button = QPushButton("C++") self.buttongroup.addButton(button, 3) button.setFont(QtGui.QFont("Sanserif", 13)) button.setIcon(QtGui.QIcon("avatar.png")) button.setIconSize(QtCore.QSize(15, 15)) hbox.addWidget(button) vbox.addLayout(hbox) self.setLayout(vbox) self.show() def on_button_clicked(self, id): for button in self.buttongroup.buttons(): if button is self.buttongroup.button(id): self.label.setText(button.text() + ' Was Clicked')
class ButtonListWidget(QGroupBox): selectionChanged = pyqtSignal(object) def __init__(self, name, parent=None): QGroupBox.__init__(self, name, parent) self.setLayout(FloatingLayout()) self.name = name self.button_group = QButtonGroup() self.button_group.setExclusive(False) self.buttons = {} def create_button(self, button_name): button = QPushButton(button_name) button.setFlat(True) button.setCheckable(True) button.clicked.connect(self.clickedButton) return button def add_button(self, button_name): button = self.create_button(button_name) self.buttons[button_name] = button self.layout().addWidget(button) self.button_group.addButton(button) return button def get_button(self, button_name): return self.buttons[button_name] def toggleChecked(self, button_name, apply=True): selection = None for button in self.button_group.buttons(): if button.text() != button_name: button.setChecked(False) else: if apply: button.setChecked(not button.isChecked()) if button.isChecked(): selection = button_name self.selectionChanged.emit(selection) def clickedButton(self): button_name = str(self.sender().text()) self.toggleChecked(button_name, False) #for button in self.button_group.buttons(): #if button is not self.sender(): #button.setChecked(False) #print "sender:", label_name def get_checked_button(self): return self.button_group.checkedButton()
class Window(QWidget): def __init__(self): super().__init__() self.title = "PyQt5 QButton Group" self.left = 500 self.top = 200 self.width = 300 self.height = 250 self.iconName = "icon.png" self.InitWindow() def InitWindow(self): self.setWindowIcon(QtGui.QIcon(self.iconName)) self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) hqbox = QHBoxLayout() self.buttongroup = QButtonGroup() self.buttongroup.buttonClicked[int].connect(self.on_button_clicked) self.label = QLabel(self) self.label.setFont(QtGui.QFont("Sanserif", 14)) hqbox.addWidget(self.label) button = QPushButton("Python") button.setFont(QtGui.QFont("Sanserif", 14)) button.setIcon(QtGui.QIcon("python.png")) button.setIconSize(QtCore.QSize(40, 40)) self.buttongroup.addButton(button, 1) hqbox.addWidget(button) button2 = QPushButton("Java") button2.setFont(QtGui.QFont("Sanserif", 14)) button2.setIcon(QtGui.QIcon("java.png")) button2.setIconSize(QtCore.QSize(40, 40)) self.buttongroup.addButton(button2, 2) hqbox.addWidget(button2) button3 = QPushButton("PHP") button3.setFont(QtGui.QFont("Sanserif", 14)) button3.setIcon(QtGui.QIcon("php.png")) button3.setIconSize(QtCore.QSize(40, 40)) self.buttongroup.addButton(button3, 3) hqbox.addWidget(button3) self.setLayout(hqbox) self.show() def on_button_clicked(self, id): # 原始範例 for button in self.buttongroup.buttons(): if button is self.buttongroup.button(id): self.label.setText(button.text() + " Was clicked.")
class MainWidow(QWidget): def __init__(self): super().__init__() self.Window_Properties() self.Window_Properties_Apply() self.Interface() def Window_Properties(self): self.title = "PyQt5 Button Group" self.top = 200 self.left = 500 self.width = 500 self.height = 500 self.iconName = "icon.png" def Window_Properties_Apply(self): self.setWindowTitle(self.title) self.setWindowIcon(QtGui.QIcon(self.iconName)) self.setGeometry(self.top , self.left ,self.width ,self.height) def Interface(self): self.label = QLabel() button_twelfth = QPushButton("Twelfth") button_twelfth.setFont(QtGui.QFont("Sanserif" ,15)) button_twelfth.setIcon(QtGui.QIcon("icon.png")) button_twelfth.setIconSize(QtCore.QSize(40 ,40)) button_thirteenth = QPushButton("Thirteenth") button_fourteenth = QPushButton("Fourteeth") self.buttonGroup = QButtonGroup() self.buttonGroup.addButton(button_twelfth ,1) self.buttonGroup.addButton(button_thirteenth ,2) self.buttonGroup.addButton(button_fourteenth , 3) h_box = QHBoxLayout() h_box.addWidget(self.label) h_box.addWidget(button_twelfth) h_box.addWidget(button_thirteenth) h_box.addWidget(button_fourteenth) self.buttonGroup.buttonClicked[int].connect(self.On_Button_Clicked) self.setLayout(h_box) def On_Button_Clicked(self ,id): for button in self.buttonGroup.buttons(): if button is self.buttonGroup.button(id): self.label.setText(button.text() + " Was Clicked")
class PopupFleets(QMainWindow): def __init__(self, fleet_id: str): super().__init__() self.fleet = wgv_utils.get_exp_fleets()[fleet_id] self.user_ships = get_processed_userShipVo() self.setStyleSheet(wgv_utils.get_color_scheme()) self.setWindowTitle('WGViewer - Expedition Fleet Selection') self.width = 200 self.height = 500 self.resize(self.width, self.height) self.curr_tab = QTableWidget() self.next_buttons = QButtonGroup() self.set_curr_table(0) content_layout_widget = QWidget(self) content_layout = QVBoxLayout(content_layout_widget) content_layout.addWidget(QLabel(f'Current Fleet {fleet_id}')) content_layout.addWidget(self.curr_tab) content_layout.addWidget(QLabel(f'Expedition Fleet for Next Map')) for b in self.next_buttons.buttons(): content_layout.addWidget(b) self.setCentralWidget(content_layout_widget) self.show() def set_curr_table(self, row: int) -> None: self.curr_tab.setRowCount(6) self.curr_tab.setColumnCount(3) for ship_id in self.fleet: info = self.user_ships[str(ship_id)] self.curr_tab.setItem(row, 0, QTableWidgetItem(info['Class'])) self.curr_tab.setItem(row, 1, QTableWidgetItem(info['Lv.'])) self.curr_tab.setItem(row, 2, QTableWidgetItem(info['Name'])) row += 1 self.curr_tab.resizeColumnsToContents() self.curr_tab.resizeRowsToContents() self.curr_tab.setShowGrid(False) self.curr_tab.horizontalHeader().setSectionResizeMode( QHeaderView.ResizeToContents) self.curr_tab.horizontalHeader().hide() self.curr_tab.verticalHeader().hide() self.curr_tab.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.curr_tab.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.curr_tab.setEditTriggers(QTableView.NoEditTriggers) self.curr_tab.setFocusPolicy(Qt.NoFocus) self.curr_tab.setSelectionMode(QTableView.NoSelection) self.curr_tab.setSizeAdjustPolicy(QAbstractScrollArea.AdjustToContents) def set_next_table(self) -> None: # TODO: like ship_window.py pass
class Window(QDialog): def __init__(self): super().__init__() self.title = "Line Edit" self.left = 300 self.top = 100 self.width = 500 self.height = 500 self.IconName = "Icon/python.png" self.InitWindow() def InitWindow(self): self.setWindowIcon(QtGui.QIcon(self.IconName)) self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) hbox = QHBoxLayout() self.buttonGroup = QButtonGroup() buttonOne = QPushButton("Python") buttonTwo = QPushButton("Java") buttonOne.setIcon(QtGui.QIcon(self.IconName)) buttonOne.setIconSize(QtCore.QSize(40, 40)) buttonTwo.setIcon(QtGui.QIcon(self.IconName)) buttonTwo.setIconSize(QtCore.QSize(40, 40)) self.buttonGroup.addButton(buttonOne) self.buttonGroup.addButton(buttonTwo) self.buttonGroup.buttonClicked[int].connect(self.OnButtonClick) self.label = QLabel(self) hbox.addWidget(buttonOne) hbox.addWidget(buttonTwo) hbox.addWidget(self.label) self.setLayout(hbox) self.show() def OnButtonClick(self, id): for button in self.buttonGroup.buttons(): if button is self.buttonGroup.button(id): self.label.setText(button.text() + " is clicked!")
class Window(QWidget): def __init__(self): super().__init__() self.title = "PyQt5 QButton Group @ stu_dados" self.top = 500 self.left = 500 self.width = 500 self.height = 500 self.iconName = "_imagens/stuart.ico" self.setWindowIcon(QtGui.QIcon(self.iconName)) self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) hbox = QHBoxLayout() self.label = QLabel(self) self.label.setFont(QtGui.QFont("Sanserif", 15)) hbox.addWidget(self.label) self.buttongroup = QButtonGroup() self.buttongroup.buttonClicked[int].connect(self.on_button_clicked) button = QPushButton("Python") self.buttongroup.addButton(button, 1) button.setFont(QtGui.QFont("Sanserif", 13)) hbox.addWidget(button) button = QPushButton("Java") self.buttongroup.addButton(button, 2) button.setFont(QtGui.QFont("Sanserif", 13)) hbox.addWidget(button) button = QPushButton("C++") self.buttongroup.addButton(button, 3) button.setFont(QtGui.QFont("Sanserif", 13)) hbox.addWidget(button) self.setLayout(hbox) self.show() def on_button_clicked(self, id): for button in self.buttongroup.buttons(): if button is self.buttongroup.button(id): self.label.setText(button.text() + " foi clicado.")
class window(QWidget): def __init__(self): super().__init__() self.title = "Pyqt5 Qbutton group" self.top = 500 self.left = 500 self.width = 100 self.height = 200 self.iconName = "transistor.jpg" self.setWindowIcon(QtGui.QIcon(self.iconName)) self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) hbox = QVBoxLayout() self.label = QLabel("Hello") self.label.setFont(QtGui.QFont("Sanserif", 10)) hbox.addWidget(self.label) self.buttongroup = QButtonGroup() self.buttongroup.buttonClicked[int].connect(self.onButton_clicked) button = QPushButton("Python") self.buttongroup.addButton(button, 1) button.setMinimumHeight(70) hbox.addWidget(button) button1 = QPushButton("Java") self.buttongroup.addButton(button1, 2) button1.setMinimumHeight(70) button1.setIcon(QtGui.QIcon(self.iconName)) button1.setIconSize(QtCore.QSize(60, 60)) button1.setFont(QtGui.QFont("Sanserif", 15)) hbox.addWidget(button1) button2 = QPushButton("JOSE") self.buttongroup.addButton(button2, 3) button2.setMinimumHeight(70) hbox.addWidget(button2) self.setLayout(hbox) self.show() def onButton_clicked(self, id): for button in self.buttongroup.buttons(): if button is self.buttongroup.button(id): self.label.setText(button.text() + " was Clicked")
class Window(QWidget): def __init__(self): super().__init__() self.title = "QLine Edit" self.top = 100 self.left = 100 self.width = 400 self.height = 120 self.iconName = "logo.png" self.setWindowTitle(self.title) self.setWindowIcon(QtGui.QIcon(self.iconName)) self.setGeometry(self.left, self.top, self.width, self.height) hbox = QHBoxLayout() self.label = QLabel("Hello") hbox.addWidget(self.label) self.label.setFont(QtGui.QFont("Algerian", 14)) self.buttongroup = QButtonGroup() self.buttongroup.buttonClicked[int].connect(self.onButtonClicked) btn1 = QPushButton("Python") btn1.setIcon(QtGui.QIcon("python.png")) self.buttongroup.addButton(btn1, 1) hbox.addWidget(btn1) btn2 = QPushButton("Java") btn2.setIcon(QtGui.QIcon("java.png")) self.buttongroup.addButton(btn2, 2) hbox.addWidget(btn2) btn3 = QPushButton("C++") btn3.setIcon(QtGui.QIcon("Cpp.png")) self.buttongroup.addButton(btn3, 3) hbox.addWidget(btn3) self.setLayout(hbox) self.show() def onButtonClicked(self, id): for button in self.buttongroup.buttons(): if button is self.buttongroup.button(id): self.label.setText(button.text() + " Clicked!")
class GetMwdRepTate(QDialog): """ Dialog to get the MWD from RepTate """ def __init__(self, parent=None, th_dict={}, title="title"): super().__init__(parent) self.setWindowTitle(title) layout = QVBoxLayout(self) validator = QDoubleValidator() hlayout = QHBoxLayout() hlayout.addWidget(QLabel("Me")) self.Me_text = QLineEdit("%.3g" % parent.parameters["Me"].value) self.Me_text.setValidator(validator) hlayout.addWidget(self.Me_text) hlayout.addWidget(QLabel("taue")) self.taue_text = QLineEdit("%.3g" % parent.parameters["tau_e"].value) self.taue_text.setValidator(validator) hlayout.addWidget(self.taue_text) layout.addLayout(hlayout) self.btngrp = QButtonGroup() for item in th_dict.keys(): rb = QRadioButton(item, self) layout.addWidget(rb) self.btngrp.addButton(rb) # default button selection rb = self.btngrp.buttons()[0] rb.setChecked(True) # OK and Cancel buttons buttons = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) buttons.accepted.connect(self.accept) buttons.rejected.connect(self.reject) layout.addWidget(buttons)
class GetModesDialog(QDialog): def __init__(self, parent=None, th_dict={}): super(GetModesDialog, self).__init__(parent) self.setWindowTitle("Get Maxwell modes") layout = QVBoxLayout(self) self.btngrp = QButtonGroup() for item in th_dict.keys(): rb = QRadioButton(item, self) layout.addWidget(rb) self.btngrp.addButton(rb) #select first button by default rb = self.btngrp.buttons()[0] rb.setChecked(True) # OK and Cancel buttons buttons = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) buttons.accepted.connect(self.accept) buttons.rejected.connect(self.reject) layout.addWidget(buttons)
class bugReport(QDialog): def __init__(self): super(bugReport, self).__init__() self.translate = QCoreApplication.translate self.readedHowReportBug = False self.timerAutoSave = QTimer() self.timerAutoSave.timeout.connect(self.onautoSave) self.timerAutoSave.start(1000 * 60 * 3) def createPanel(self): labelReportTitle = QLabel( self.translate("bugReport", "Bug Report Title: ")) self.lineEditReportTitle = QLineEdit() labelTestedEnvironment = QLabel( self.translate("bugReport", "Tested Environment: ")) self.lineEditTestedEnvironment = QLineEdit( self.translate( "bugReport", """System Platform:{}_{} Python Version:{}.{}.{}-{} PyQt Version:{} QT Version:{}""" ).format( QSysInfo.prettyProductName() if QSysInfo.prettyProductName() == "unknown" else "{}-{}".format(QSysInfo.kernelType(), QSysInfo.kernelVersion()), QSysInfo.currentCpuArchitecture(), sys.version_info.major, sys.version_info.minor, sys.version_info.micro, sys.version_info.releaselevel, PYQT_VERSION_STR, QT_VERSION_STR)) radioBtnQuickReport = QRadioButton( self.translate("bugReport", "Quick Report")) radioBtnKnowHowFix = QRadioButton( self.translate("bugReport", "Know How Fix")) radioBtnKnowHowFix.setChecked(True) radioBtnFeatureRequest = QRadioButton( self.translate("bugReport", "Feature Request")) buttonOpenHowReportBugURL = QPushButton( self.translate( "bugReport", """Click Me! Read "HOW REPORT A BUG" before report a bug.""")) self.buttonGroupBugReport = QButtonGroup() self.buttonGroupBugReport.addButton(radioBtnQuickReport) self.buttonGroupBugReport.addButton(radioBtnKnowHowFix) self.buttonGroupBugReport.addButton(radioBtnFeatureRequest) self.buttonGroupBugReport.addButton(buttonOpenHowReportBugURL) hboxRadiobutton = QHBoxLayout() hboxRadiobutton.addWidget(radioBtnKnowHowFix) hboxRadiobutton.addWidget(radioBtnQuickReport) hboxRadiobutton.addWidget(radioBtnFeatureRequest) hboxRadiobutton.addWidget(buttonOpenHowReportBugURL) hboxRadiobutton.addStretch() labelStepsToReproduce = QLabel( self.translate("bugReport", "Steps To Reproduce: ")) self.textEditStepsToReproduce = QTextEdit() labelActualresults = QLabel( self.translate("bugReport", "Actual results: ")) self.textEditActualresults = QTextEdit() self.textEditActualresults.insertPlainText( self.translate( "bugReport", "if have Python's Traceback, Please Paste.\nif is V2Ray-core JSON Editor issue, please Paste the JSON File without server information." )) self.textEditActualresults.setAcceptDrops(True) labelExpectedresults = QLabel( self.translate("bugReport", "Expected results: ")) self.textEditExpectedresults = QTextEdit() labelFeatureRequest = QLabel( self.translate("bugReport", "Feature Request: ")) self.textEditFeatureRequest = QTextEdit() labelQuickReport = QLabel(self.translate("bugReport", "Quick Report: ")) self.textEditQuickReport = QTextEdit() labelHowFix = QLabel(self.translate("bugReport", "How Fix: ")) self.textEditHowFix = QTextEdit() gridBoxReport = QGridLayout() gridBoxReport.addWidget(labelReportTitle, 0, 0) gridBoxReport.addWidget(self.lineEditReportTitle, 0, 1) gridBoxReport.addWidget(labelTestedEnvironment, 1, 0) gridBoxReport.addWidget(self.lineEditTestedEnvironment, 1, 1) gridBoxReport.addLayout(hboxRadiobutton, 2, 0, 1, 2) gridBoxQuickReport = QGridLayout() gridBoxQuickReport.addWidget(labelQuickReport, 0, 0) gridBoxQuickReport.addWidget(self.textEditQuickReport, 0, 1) self.groupBoxQuickReport = QGroupBox("", self) self.groupBoxQuickReport.setLayout(gridBoxQuickReport) self.groupBoxQuickReport.hide() gridBoxKnowHowFix = QGridLayout() gridBoxKnowHowFix.addWidget(labelStepsToReproduce, 0, 0) gridBoxKnowHowFix.addWidget(self.textEditStepsToReproduce, 0, 1) gridBoxKnowHowFix.addWidget(labelActualresults, 1, 0) gridBoxKnowHowFix.addWidget(self.textEditActualresults, 1, 1) self.buttonInsertPiture = QPushButton( self.translate("bugReport", "Insert Picture From URL:")) self.lineEditInserPiture = QLineEdit() gridBoxKnowHowFix.addWidget(self.lineEditInserPiture, 2, 1) gridBoxKnowHowFix.addWidget(self.buttonInsertPiture, 2, 0) gridBoxKnowHowFix.addItem(QSpacerItem(50, 50), 3, 0, 1, 4) gridBoxKnowHowFix.addWidget(labelExpectedresults, 4, 0) gridBoxKnowHowFix.addWidget(self.textEditExpectedresults, 4, 1) gridBoxKnowHowFix.addWidget(labelHowFix, 5, 0) gridBoxKnowHowFix.addWidget(self.textEditHowFix, 5, 1) self.groupBoxKnowHowFix = QGroupBox() self.groupBoxKnowHowFix.setLayout(gridBoxKnowHowFix) gridBoxFeatureRequest = QGridLayout() gridBoxFeatureRequest.addWidget(labelFeatureRequest, 0, 0) gridBoxFeatureRequest.addWidget(self.textEditFeatureRequest, 0, 1) self.groupBoxFeatureRequest = QGroupBox("", self) self.groupBoxFeatureRequest.setLayout(gridBoxFeatureRequest) self.groupBoxFeatureRequest.hide() hboxButton = QHBoxLayout() self.buttonExportBugReportText = QPushButton( self.translate("bugReport", "Export Bug Report Text")) self.buttonExitButReport = QPushButton( self.translate("bugReport", "Exit")) hboxButton.addStretch() hboxButton.addWidget(self.buttonExportBugReportText) hboxButton.addWidget(self.buttonExitButReport) vboxBugReport = QVBoxLayout(self) vboxBugReport.addLayout(gridBoxReport) vboxBugReport.addWidget(self.groupBoxQuickReport) vboxBugReport.addWidget(self.groupBoxKnowHowFix) vboxBugReport.addWidget(self.groupBoxFeatureRequest) vboxBugReport.addLayout(hboxButton) vboxBugReport.addStretch() self.settextEidtReadonly(result=True) self.createSignals() def createSignals(self): self.buttonGroupBugReport.buttonClicked.connect( self.onbuttonGroupBugReport) self.buttonExitButReport.clicked.connect(self.close) self.buttonExportBugReportText.clicked.connect(self.onautoSave) self.buttonInsertPiture.clicked.connect(self.onbuttonInsertPiture) def onbuttonInsertPiture(self): url = self.lineEditInserPiture.text() if url != "": url = QUrl(url) self.textEditActualresults.moveCursor(QTextCursor.End) self.textEditActualresults.insertPlainText( """\n<img src="{}"/>""".format(url.path())) self.textEditActualresults.moveCursor(QTextCursor.End) self.lineEditInserPiture.clear() def settextEidtReadonly(self, result=True): self.lineEditInserPiture.setReadOnly(result) self.textEditActualresults.setReadOnly(result) self.textEditExpectedresults.setReadOnly(result) self.textEditFeatureRequest.setReadOnly(result) self.textEditHowFix.setReadOnly(result) self.textEditQuickReport.setReadOnly(result) self.textEditStepsToReproduce.setReadOnly(result) def onautoSave(self): currentButton = self.buttonGroupBugReport.buttons() for i in currentButton: if i.isChecked(): button = i.text() if button == self.translate("bugReport", "Quick Report"): self.savebugReportText( save=copy.deepcopy(self.saveQuickReport())) if button == self.translate("bugReport", "Know How Fix"): self.savebugReportText( save=copy.deepcopy(self.saveKnowHowFix())) if button == self.translate("bugReport", "Feature Request"): self.savebugReportText( save=copy.deepcopy(self.saveFeatureRequest())) def savebugReportText(self, save=False): if save: outFile = QFileInfo(self.translate("bugReport", "bugReport.txt")) fileName = outFile.fileName() if QFile.exists(fileName): QFile.remove(fileName) outFile = QFile(fileName) outFile.open(QIODevice.WriteOnly | QIODevice.Text) outFile.write(codecs.encode(save, "utf-8")) def saveQuickReport(self): bugReportText = self.translate( "bugReport", "Bug Report Title: \n{}\nTested Environment: \n{}\n\nQuick Report:\n{}\n" ).format(self.lineEditReportTitle.text(), self.lineEditTestedEnvironment.text(), self.textEditQuickReport.toPlainText()) return bugReportText def saveKnowHowFix(self): bugReportText = self.translate( "bugReport", """Bug Report Title: {} \nTested Environment: \n{} \nSteps To Reproduce: \n{} \nActual Results: \n{} \nExpected Results: \n{} \nHow Fix: \n{}\n""").format(self.lineEditReportTitle.text(), self.lineEditTestedEnvironment.text(), self.textEditStepsToReproduce.toPlainText(), self.textEditActualresults.toPlainText(), self.textEditExpectedresults.toPlainText(), self.textEditHowFix.toPlainText()) return bugReportText def saveFeatureRequest(self): bugReportText = self.translate( "bugReport", """Feature Request Title: \n{} Tested Environment: \n{} Feature Request Details:\n{}\n""").format( self.lineEditReportTitle.text(), self.lineEditTestedEnvironment.text(), self.textEditFeatureRequest.toPlainText()) return bugReportText def onbuttonGroupBugReport(self, button): def hideAllWidget(): self.groupBoxFeatureRequest.hide() self.groupBoxKnowHowFix.hide() self.groupBoxQuickReport.hide() buttonText = button.text() if buttonText == self.translate("bugReport", "Quick Report"): hideAllWidget() self.groupBoxQuickReport.show() elif buttonText == self.translate("bugReport", "Know How Fix"): hideAllWidget() self.groupBoxKnowHowFix.show() elif buttonText == self.translate("bugReport", "Feature Request"): hideAllWidget() self.groupBoxFeatureRequest.show() elif buttonText == self.translate( "bugReport", """Click Me! Read "HOW REPORT A BUG" before report a bug."""): QDesktopServices.openUrl( QUrl("https://www.chiark.greenend.org.uk/~sgtatham/bugs.html")) self.settextEidtReadonly(result=False)
class IADToolWidget(ToolWidgetBase): toolClass = IADTool columnLabels = [ 'Name', 'IAD X', 'IAD Y', 'X offset', 'Weight center', 'Peak x', 'Peak y' ] def __init__(self, graphWidget): super().__init__(graphWidget) self.selectBaseGroup = None vbox = VBoxLayout() vbox.setContentsMargins(4, 4, 4, 4) self.setLayout(vbox) self.linesTable = TableWidget() self.linesTable.cellChanged.connect(self.linesTableCellChanged) vbox.addWidget(self.linesTable) self.copyResultButton = QPushButton('Copy') self.copyResultButton.clicked.connect(lambda c: self.copyResult()) hbox = HBoxLayout() hbox.addWidget(self.copyResultButton) hbox.addStretch(1) vbox.addLayout(hbox) vbox.addStretch(1) vbox.addWidget(HSeparator()) for name in 'Smooth', 'BGSub', 'Interp': cls = globals()['MethodSelector%s' % name] sel = cls(self.tool.interpdx) if name == 'Interp' else cls() setattr(self, name.lower(), sel) sel.selectionChanged.connect(self.replot) self.addMethodSelector(sel) vbox.addWidget(sel) hbox = HBoxLayout() hbox.addWidget(QLabel('Weight center threshold')) hbox.addWidget(self.tool.threshold.getWidget()) vbox.addLayout(hbox) vbox.addWidget(HSeparator()) buttons = [('Plot original', lambda: self.plot('orig')), ('Plot normalized', lambda: self.plot('norm')), ('Plot with X offset', lambda: self.plot('xoff')), ('Plot differences', lambda: self.plot('diff')), ('Plot IAD', lambda: self.plot('iad')), ('Export xlsx', self.exportXlsx)] grid = QGridLayout() vbox.addLayout(grid) for i, (l, f) in enumerate(buttons): c = i % 2 r = i // 2 btn = QPushButton(l) btn.clicked.connect(f) grid.addWidget(btn, r, c) self.updateToolProps() self.tool.xoffUpdated.connect(self.updateXoff) self.tool.iadYUpdated.connect(self.updateIADy) self.tool.peaksUpdated.connect(self.updatePeaks) def copyResult(self): rows = [self.columnLabels] for r in range(self.linesTable.rowCount()): row = [self.linesTable.cellWidget(r, 0).text()] for c in range(1, self.linesTable.columnCount()): row.append(self.linesTable.item(r, c).text().strip()) rows.append(row) QApplication.clipboard().setText('\n'.join( ['\t'.join(r) for r in rows])) def writeXlsx(self, wb): ws_IAD = wb.add_worksheet('IAD') ws_err = wb.add_worksheet('IAD err') ws_IAD.write(0, 0, self.xlsxRecalcMsg) errCells = self.writeXlsx_err(wb, ws_err, 0, 0) errCells = ["='%s'!%s" % (ws_err.name, c) for c in errCells] chart_spectra, chart_diff, chart_iad \ = self.writeXlsx_IAD(wb, ws_IAD, 0, 1, errCells) wb.add_chartsheet('Spectra').set_chart(chart_spectra) wb.add_chartsheet('Diff').set_chart(chart_diff) wb.add_chartsheet('IAD graph').set_chart(chart_iad) def writeXlsx_IAD(self, wb, ws, c0, r0, errCells): fmt_wc = wb.add_format() fmt_wc.set_num_format('0.000000000000') fmt_is = wb.add_format() fmt_is.set_num_format('0.00') from functions import getTableCellName as cellName lines = self.tool.getLines('xoff') base = lines.index(lines[self.tool.base]) c1, r1 = c0 + 1, r0 + 1 c2 = c1 + len(lines) + 1 for c, l in enumerate(lines): if c == 0: ws.write(r0, c0, 'x') for r, x in enumerate(l.x): ws.write(r1 + r, c0, x) ws.write(r0, c1 + c, l.name) ws.write(r0, c2 + c, l.name) for r, y in enumerate(l.y): # spectrum ws.write(r1 + r, c1 + c, y) # diff f = '=%s-%s' % (cellName( r1 + r, c1 + c), cellName(r1 + r, c1 + base, '$')) ws.write(r1 + r, c2 + c, f) chart_spectra = wb.add_chart({ 'type': 'scatter', 'subtype': 'straight' }) chart_spectra.set_title({'none': True}) chart_spectra.set_x_axis({ 'name': 'Energy (eV)', 'major_gridlines': { 'visible': False }, 'major_tick_mark': 'inside' }) chart_spectra.set_y_axis({ 'name': 'Intensity (a.u.)', 'major_gridlines': { 'visible': False }, 'major_tick_mark': 'inside' }) chart_diff = wb.add_chart({'type': 'scatter', 'subtype': 'straight'}) chart_diff.set_title({'none': True}) chart_diff.set_x_axis({ 'name': 'Energy (eV)', 'major_gridlines': { 'visible': False }, 'major_tick_mark': 'inside' }) chart_diff.set_y_axis({ 'name': 'Intensity difference (a.u.)', 'major_gridlines': { 'visible': False }, 'major_tick_mark': 'inside' }) chart_iad = wb.add_chart({ 'type': 'scatter', 'subtype': 'straight_with_markers' }) chart_iad.set_title({'none': True}) chart_iad.set_legend({'none': True}) chart_iad.set_x_axis({ 'name': 'Pressure (GPa)', 'major_gridlines': { 'visible': False }, 'major_tick_mark': 'inside' }) chart_iad.set_y_axis({ 'name': 'IAD (a.u.)', 'major_gridlines': { 'visible': False }, 'major_tick_mark': 'inside', 'min': 0 }) c3 = c2 + len(lines) + 1 c4 = c3 + 1 ws.write(r0, c4 + 0, 'IAD') ws.write(r0, c4 + 1, 'IAD err') ws.write(r0, c4 + 2, 'Weight center') ws.write(r0, c4 + 3, 'Intensity sum') lines_iad = [(l, iadX) for l, iadX in zip(lines, self.tool.iadX) if iadX is not None] for i, (l, iadX) in enumerate(lines_iad): r2 = r1 + len(l.y) - 1 f1 = '=sumproduct(abs(%s:%s))' % (cellName( r1, c2 + i), cellName(r2, c2 + i)) ry = '%s:%s' % (cellName(r1, c1 + i), cellName(r2, c1 + i)) f2 = '=sumproduct(%s:%s,%s)/sum(%s)' % (cellName( r1, c0), cellName(r2, c0), ry, ry) f3 = '=sum(%s:%s)' % (cellName(r1, c1 + i), cellName(r2, c1 + i)) ws.write(r1 + i, c3, iadX) ws.write(r1 + i, c3 + 1, f1) ws.write(r1 + i, c3 + 2, errCells[i]) ws.write(r1 + i, c3 + 3, f2, fmt_wc) ws.write(r1 + i, c3 + 4, f3, fmt_is) chart_spectra.add_series({ 'name': [ws.name, r0, c1 + i], 'categories': [ws.name, r1, c0, r2, c0], 'values': [ws.name, r1, c1 + i, r2, c1 + i], 'line': { 'width': 1 } }) chart_diff.add_series({ 'name': [ws.name, r0, c2 + i], 'categories': [ws.name, r1, c0, r2, c0], 'values': [ws.name, r1, c2 + i, r2, c2 + i], 'line': { 'width': 1 } }) err_values = "='%s'!%s:%s" % (ws.name, cellName( r1, c3 + 2), cellName(r1 + len(lines_iad) - 1, c3 + 2)) chart_iad.add_series({ 'name': [ws.name, r0, c3 + 1], 'categories': [ws.name, r1, c3, r1 + len(lines_iad) - 1, c3], 'values': [ws.name, r1, c3 + 1, r1 + len(lines_iad) - 1, c3 + 1], 'y_error_bars': { 'type': 'custom', 'plus_values': err_values, 'minus_values': err_values }, }) return chart_spectra, chart_diff, chart_iad def writeXlsx_err(self, wb, ws, c0, r0): from functions import getTableCellName as cellName lines = self.tool.getLines('orig') base = lines.index(lines[self.tool.base]) c1, r1 = c0 + 1, r0 + 1 c2 = c1 + (len(lines) * 2) + 1 c3 = c2 + 4 c4 = c3 + len(lines) + 1 ws.write(r0, c2 + 1, 'sum(I)') ws.write(r0, c2 + 2, 'sum(I) err') ws.write(r0, c4 + 1, 'IAD err') for c, l in enumerate(lines): if c == 0: ws.write(r0, c0, 'x') for r, x in enumerate(l.x): ws.write(r1 + r, c0, x) C = c1 + (c * 2) r2 = r1 + len(l.y) - 1 ws.write(r0, C, l.name) ws.write(r0, C + 1, '%s err' % l.name) ws.write(r0, c3 + c, '%s norm err' % l.name) for r, (y, y_) in enumerate(zip(l.y, l.y_)): ws.write(r1 + r, C, y) ws.write(r1 + r, C + 1, y_) ws.write( r1 + r, c3 + c, '=sqrt((1/%(sumy)s)^2*(%(y_)s^2) + (%(y)s/%(sumy)s^2)^2*(%(sumy_)s^2))' % { 'y': cellName(r1 + r, C), 'y_': cellName(r1 + r, C + 1), 'sumy': cellName(r1 + c, c2 + 1), 'sumy_': cellName(r1 + c, c2 + 2) }) ws.write(r1 + c, c2, l.name) ws.write(r1 + c, c2 + 1, '=sum(%s:%s)' % (cellName(r1, C), cellName(r2, C))) ws.write( r1 + c, c2 + 2, '=sqrt(sumsq(%s:%s))' % (cellName(r1, C + 1), cellName(r2, C + 1))) ws.write(r1 + c, c4, l.name) ws.write( r1 + c, c4 + 1, '=sqrt(sumsq(%s:%s)+sumsq(%s:%s))' % (cellName(r1, c3 + c), cellName(r2, c3 + c), cellName(r1, c3 + base), cellName(r2, c3 + base))) return [cellName(r1 + i, c4 + 1) for i, l in enumerate(lines)] def linesTableCellChanged(self, r, c): if c == 1: self.updateToolProps() def updateToolProps(self): self.tool.bgsub = self.bgsub.currentItem() self.tool.smooth = self.smooth.currentItem() self.tool.interp = self.interp.currentItem() self.tool.iadX = [] for x in self.getIADx(): try: x = float(x) except: x = None self.tool.iadX.append(x) def baseRadioClicked(self, b): self.tool.base = self.selectBaseGroup.checkedId() self.replot() def clear(self): self.linesTable.clear() self.linesTable.verticalHeader().hide() self.linesTable.horizontalHeader().setResizeMode( QHeaderView.ResizeToContents) self.linesTable.setColumnCount(len(self.columnLabels)) self.linesTable.setHorizontalHeaderLabels(self.columnLabels) self.linesTable.setSizeAdjustPolicy(self.linesTable.AdjustToContents) self.selectBaseGroup = QButtonGroup() self.selectBaseGroup.buttonClicked.connect(self.baseRadioClicked) self.lines = [] def add(self, line): r = len(self.lines) radio = QRadioButton(line.name) self.linesTable.setRowCount(r + 1) self.linesTable.setCellWidget(r, 0, radio) m = re.search(r'^([\+\-]?\d*(?:\.\d+)?)', line.name) if m: self.setIADx(r, m.group(1)) idx = len(self.selectBaseGroup.buttons()) if self.tool.base < 0 or self.tool.base == idx: radio.setChecked(True) self.selectBaseGroup.addButton(radio, idx) self.lines.append(line) def setLinesTableCell(self, r, c, v): self.linesTable.setItem(r, c, QTableWidgetItem(str(v))) def getLinesTableCol(self, c): return [ self.linesTable.item(r, c).text() for r in range(self.linesTable.rowCount()) ] def setIADx(self, i, v): self.setLinesTableCell(i, 1, v) self.updateToolProps() def setIADy(self, i, v): self.setLinesTableCell(i, 2, v) def setXoff(self, i, v): self.setLinesTableCell(i, 3, v) def setWC(self, i, v): self.setLinesTableCell(i, 4, v) def setPeak(self, i, x, y): self.setLinesTableCell(i, 5, x) self.setLinesTableCell(i, 6, y) def getIADx(self): return self.getLinesTableCol(1) def updateXoff(self): for i, (wc, xoff) in enumerate(zip(self.tool.wc, self.tool.xoff)): if i == self.tool.base: self.setWC(i, '%.10f' % wc) else: b = self.tool.wc[self.tool.base] self.setWC(i, '%.10f' % b) self.setXoff(i, '%+.10f' % xoff) def updateIADy(self): for i, iadY in enumerate(self.tool.iadY): self.setIADy(i, '%g' % iadY) def updatePeaks(self): for i, peak in enumerate(self.tool.peaks): self.setPeak(i, *peak) def replot(self): self.plot(self.tool.mode) def plot(self, mode): if not self.tool.lines: return autoRange = mode != self.tool.mode logging.info('IAD: Plot %s (auto range: %s)' % (mode, autoRange)) self.tool.mode = mode self.updateToolProps() self.plotRequested.emit(self.tool, autoRange) def restoreState(self, state): super().restoreState(state) self.updateToolProps()
class MainWindow(QMainWindow): InsertTextButton = 10 items = {-2: "source", -3: "channel", -4: "sink"} def __init__(self): import _diagramscene_rc super(MainWindow, self).__init__() self.config_manipulations = FlumeConfig(self) properties_generator.dump_props() self.create_actions() self.create_menus() self.create_tool_box() self.clicked_button_id = 0 self.scene = DiagramScene(self.item_menu) self.scene.setSceneRect(QRectF(0, 0, 5000, 5000)) self.scene.itemInserted.connect(self.item_inserted) self.scene.textInserted.connect(self.text_inserted) self.scene.itemSelected.connect(self.item_selected) self.create_tool_bars() # self.scene.enable_grid() layout = QHBoxLayout() layout.addWidget(self.tool_box) self.view = QGraphicsView(self.scene) self.view.centerOn(0, 0) layout.addWidget(self.view) self.widget = QWidget() self.widget.setLayout(layout) self.setCentralWidget(self.widget) self.setWindowTitle("The Flume Illustrator") # noinspection PyAttributeOutsideInit,PyArgumentList def create_actions(self): self.to_front_action = QAction(QIcon(':/images/bringtofront.png'), "Bring to &Front", self, shortcut="Ctrl+F", statusTip="Bring item to front", triggered=self.bring_to_front) self.send_back_action = QAction(QIcon(':/images/sendtoback.png'), "Send to &Back", self, shortcut="Ctrl+B", statusTip="Send item to back", triggered=self.send_to_back) self.bold_action = QAction(QIcon(':/images/bold.png'), "Bold", self, checkable=True, shortcut="Ctrl+B", triggered=self.handle_font_change) self.italic_action = QAction(QIcon(':/images/italic.png'), "Italic", self, checkable=True, shortcut="Ctrl+I", triggered=self.handle_font_change) self.underline_action = QAction(QIcon(':/images/underline.png'), "Underline", self, checkable=True, shortcut="Ctrl+U", triggered=self.handle_font_change) self.delete_action = QAction(QIcon(':/images/delete.png'), "Delete", self, shortcut="Delete", statusTip='Delete item from diagram', triggered=self.delete_item) self.exit_action = QAction("Exit", self, shortcut="Ctrl+X", statusTip="Quit program", triggered=self.close) self.about_action = QAction("About", self, shortcut="Ctrl+B", triggered=self.about) self.load_config_action = QAction("Load", self, shortcut="Ctrl+O", statusTip="Load config file", triggered=self.config_manipulations.load_config) self.enable_grid_action = QAction("Enable grid", self, checkable=True, triggered=self.enable_grid) # noinspection PyAttributeOutsideInit def create_menus(self): self.file_menu = self.menuBar().addMenu("File") self.file_menu.addAction(self.load_config_action) self.file_menu.addAction(self.exit_action) self.item_menu = self.menuBar().addMenu("Item") self.item_menu.addAction(self.delete_action) self.item_menu.addSeparator() self.item_menu.addAction(self.to_front_action) self.item_menu.addAction(self.send_back_action) self.about_menu = self.menuBar().addMenu("Help") self.about_menu.addAction(self.about_action) # noinspection PyAttributeOutsideInit,PyUnresolvedReferences def create_tool_box(self): self.button_group = QButtonGroup() self.button_group.setExclusive(False) self.button_group.buttonClicked[int].connect(self.button_group_clicked) layout = QGridLayout() layout.addWidget(self.create_cell_widget("Source", "source"), 0, 0) layout.addWidget(self.create_cell_widget("Channel", "channel"), 0, 1) layout.addWidget(self.create_cell_widget("Sink", "sink"), 1, 0) text_button = QToolButton() text_button.setCheckable(True) self.button_group.addButton(text_button, self.InsertTextButton) text_button.setIcon(QIcon(QPixmap(':/images/textpointer.png').scaled(30, 30))) text_button.setIconSize(QSize(50, 50)) text_layout = QGridLayout() text_layout.addWidget(text_button, 0, 0, Qt.AlignHCenter) text_layout.addWidget(QLabel("Text"), 1, 0, Qt.AlignCenter) text_widget = QWidget() text_widget.setLayout(text_layout) layout.addWidget(text_widget, 1, 1) layout.setRowStretch(3, 10) layout.setColumnStretch(2, 10) item_widget = QWidget() item_widget.setLayout(layout) self.tool_box = QToolBox() self.tool_box.setSizePolicy(QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Ignored)) self.tool_box.setMinimumWidth(item_widget.sizeHint().width()) self.tool_box.addItem(item_widget, "Basic Flume Items") # noinspection PyAttributeOutsideInit,PyUnresolvedReferences def create_tool_bars(self): self.edit_tool_bar = self.addToolBar("Edit") self.edit_tool_bar.addAction(self.delete_action) self.edit_tool_bar.addAction(self.to_front_action) self.edit_tool_bar.addAction(self.send_back_action) self.edit_tool_bar.addAction(self.enable_grid_action) self.font_combo = QFontComboBox() self.font_combo.currentFontChanged.connect(self.current_font_changed) self.font_size_combo = QComboBox() self.font_size_combo.setEditable(True) for i in range(8, 30, 2): self.font_size_combo.addItem(str(i)) validator = QIntValidator(2, 64, self) self.font_size_combo.setValidator(validator) self.font_size_combo.currentIndexChanged.connect(self.font_size_changed) self.font_color_tool_button = QToolButton() self.font_color_tool_button.setPopupMode(QToolButton.MenuButtonPopup) self.font_color_tool_button.setMenu( self.create_color_menu(self.text_color_changed, Qt.black)) self.text_action = self.font_color_tool_button.menu().defaultAction() self.font_color_tool_button.setIcon( self.create_color_tool_button_icon(':/images/textpointer.png', Qt.black)) self.font_color_tool_button.setAutoFillBackground(True) self.font_color_tool_button.clicked.connect(self.text_button_triggered) self.fill_color_tool_button = QToolButton() self.fill_color_tool_button.setPopupMode(QToolButton.MenuButtonPopup) self.fill_color_tool_button.setMenu( self.create_color_menu(self.item_color_changed, Qt.white)) self.fillAction = self.fill_color_tool_button.menu().defaultAction() self.fill_color_tool_button.setIcon( self.create_color_tool_button_icon(':/images/floodfill.png', Qt.white)) self.fill_color_tool_button.clicked.connect(self.fill_button_triggered) self.line_color_tool_button = QToolButton() self.line_color_tool_button.setPopupMode(QToolButton.MenuButtonPopup) self.line_color_tool_button.setMenu( self.create_color_menu(self.line_color_changed, Qt.black)) self.lineAction = self.line_color_tool_button.menu().defaultAction() self.line_color_tool_button.setIcon( self.create_color_tool_button_icon(':/images/linecolor.png', Qt.black)) self.line_color_tool_button.clicked.connect(self.line_button_triggered) self.text_tool_bar = self.addToolBar("Font") self.text_tool_bar.addWidget(self.font_combo) self.text_tool_bar.addWidget(self.font_size_combo) self.text_tool_bar.addAction(self.bold_action) self.text_tool_bar.addAction(self.italic_action) self.text_tool_bar.addAction(self.underline_action) self.color_tool_bar = self.addToolBar("Color") self.color_tool_bar.addWidget(self.font_color_tool_button) self.color_tool_bar.addWidget(self.fill_color_tool_button) self.color_tool_bar.addWidget(self.line_color_tool_button) self.loading_tool_bar = self.addToolBar("Load") self.loading_tool_bar.addAction(self.load_config_action) pointer_button = QToolButton() pointer_button.setCheckable(True) pointer_button.setChecked(True) pointer_button.setIcon(QIcon(":/images/pointer.png")) line_pointer_button = QToolButton() line_pointer_button.setCheckable(True) line_pointer_button.setIcon(QIcon(":/images/linepointer.png")) self.pointer_type_group = QButtonGroup() self.pointer_type_group.addButton(pointer_button, DiagramScene.MoveItem) self.pointer_type_group.addButton(line_pointer_button, DiagramScene.InsertLine) self.pointer_type_group.buttonClicked[int].connect(self.pointer_group_clicked) self.scene_scale_combo = QComboBox() self.scene_scale_combo.addItems(["50%", "75%", "100%", "125%", "150%"]) self.scene_scale_combo.setCurrentIndex(2) self.scene_scale_combo.currentIndexChanged[str].connect(self.scene_scale_changed) self.pointer_tool_bar = self.addToolBar("Pointer type") self.pointer_tool_bar.addWidget(pointer_button) self.pointer_tool_bar.addWidget(line_pointer_button) self.pointer_tool_bar.addWidget(self.scene_scale_combo) def button_group_clicked(self, button_id): buttons = self.button_group.buttons() self.clicked_button_id = button_id for button in buttons: if self.button_group.button(button_id) != button: button.setChecked(False) if button_id == self.InsertTextButton: self.scene.set_mode(DiagramScene.InsertText) else: self.scene.set_item_type(self.items[button_id]) self.scene.set_mode(DiagramScene.InsertItem) def delete_item(self): for item in self.scene.selectedItems(): if isinstance(item, FlumeDiagramItem): item.remove_arrows() self.scene.removeItem(item) # noinspection PyTypeChecker,PyCallByClass def about(self): # noinspection PyArgumentList QMessageBox.about(self, "About Flume Illustrator", "The Flume illustrator shows config-file details") def pointer_group_clicked(self): self.scene.set_mode(self.pointer_type_group.checkedId()) def bring_to_front(self): if not self.scene.selectedItems(): return selected_item = self.scene.selectedItems()[0] overlap_items = selected_item.collidingItems() z_value = 0 for item in overlap_items: if item.zValue() >= z_value and isinstance(item, FlumeDiagramItem): z_value = item.zValue() + 0.1 selected_item.setZValue(z_value) def send_to_back(self): if not self.scene.selectedItems(): return selected_item = self.scene.selectedItems()[0] overlap_items = selected_item.collidingItems() z_value = 0 for item in overlap_items: if item.zValue() <= z_value and isinstance(item, FlumeDiagramItem): z_value = item.zValue() - 0.1 selected_item.setZValue(z_value) def scene_scale_changed(self, scale): new_scale = float(scale[:scale.index("%")]) / 100 old_transform = self.view.transform() self.view.resetTransform() self.view.translate(old_transform.dx(), old_transform.dy()) self.view.scale(new_scale, new_scale) def item_inserted(self, diagram_type): self.pointer_type_group.button(DiagramScene.MoveItem).setChecked(True) self.scene.set_mode(self.scene.DefaultMode) self.button_group.button(self.clicked_button_id).setChecked(False) def text_inserted(self, item): self.button_group.button(self.InsertTextButton).setChecked(False) self.scene.set_mode(self.pointer_type_group.checkedId()) def current_font_changed(self, font): self.handle_font_change() def font_size_changed(self, font=None): self.handle_font_change() def text_color_changed(self): self.text_action = self.sender() self.font_color_tool_button.setIcon( self.create_color_tool_button_icon(':/images/textpointer.png', QColor(self.text_action.data()))) self.text_button_triggered() def item_color_changed(self): self.fillAction = self.sender() self.fill_color_tool_button.setIcon( self.create_color_tool_button_icon(':/images/floodfill.png', QColor(self.fillAction.data()))) self.fill_button_triggered() def line_color_changed(self): self.lineAction = self.sender() self.line_color_tool_button.setIcon( self.create_color_tool_button_icon(':/images/linecolor.png', QColor(self.lineAction.data()))) self.line_button_triggered() def text_button_triggered(self): self.scene.set_text_color(QColor(self.text_action.data())) def fill_button_triggered(self): self.scene.set_item_color(QColor(self.fillAction.data())) def line_button_triggered(self): self.scene.set_line_color(QColor(self.lineAction.data())) def handle_font_change(self): font = self.font_combo.currentFont() font.setPointSize(int(self.font_size_combo.currentText())) if self.bold_action.isChecked(): font.setWeight(QFont.Bold) else: font.setWeight(QFont.Normal) font.setItalic(self.italic_action.isChecked()) font.setUnderline(self.underline_action.isChecked()) self.scene.setFont(font) def item_selected(self, item): font = item.font() self.font_combo.setCurrentFont(font) self.font_size_combo.setEditText(str(font.pointSize())) self.bold_action.setChecked(font.weight() == QFont.Bold) self.italic_action.setChecked(font.italic()) self.underline_action.setChecked(font.underline()) def create_cell_widget(self, text, diagram_type): item = FlumeObject(diagram_type, "") icon = QIcon(item.pictogram.image()) button = QToolButton() button.setIcon(icon) button.setIconSize(QSize(50, 50)) button.setCheckable(True) self.button_group.addButton(button) # , diagram_type layout = QGridLayout() layout.addWidget(button, 0, 0, Qt.AlignHCenter) layout.addWidget(QLabel(text), 1, 0, Qt.AlignHCenter) widget = QWidget() widget.setLayout(layout) return widget # noinspection PyArgumentList def create_color_menu(self, slot, default_color): colors = [Qt.black, Qt.white, Qt.red, Qt.blue, Qt.yellow] names = ["black", "white", "red", "blue", "yellow"] color_menu = QMenu(self) for color, name in zip(colors, names): action = QAction(self.create_color_icon(color), name, self, triggered=slot) action.setData(QColor(color)) color_menu.addAction(action) if color == default_color: color_menu.setDefaultAction(action) return color_menu @staticmethod def create_color_tool_button_icon(image_file, color): pixmap = QPixmap(50, 80) pixmap.fill(Qt.transparent) painter = QPainter(pixmap) image = QPixmap(image_file) target = QRect(0, 0, 50, 60) source = QRect(0, 0, 42, 42) painter.fillRect(QRect(0, 60, 50, 80), color) painter.drawPixmap(target, image, source) painter.end() return QIcon(pixmap) @staticmethod def create_color_icon(color): pixmap = QPixmap(20, 20) painter = QPainter(pixmap) painter.setPen(Qt.NoPen) painter.fillRect(QRect(0, 0, 20, 20), color) painter.end() return QIcon(pixmap) def enable_grid(self): if self.enable_grid_action.isChecked(): color = Qt.black else: color = Qt.white for i in range(50): for j in range(50): self.scene.addEllipse(i * 100, j * 100, 2, 2, QPen(color))
class Ui_Widget(object): """ Klasa definiująca GUI """ def setupUi(self, Widget): # widgety rysujące kształty, instancje klasy Ksztalt self.ksztalt1 = Ksztalt(self, Ksztalty.Polygon) self.ksztalt2 = Ksztalt(self, Ksztalty.Ellipse) self.ksztaltAktywny = self.ksztalt1 # przyciski CheckBox ### uklad = QVBoxLayout() # układ pionowy self.grupaChk = QButtonGroup() for i, v in enumerate(('Kwadrat', 'Koło', 'Trójkąt', 'Linia')): self.chk = QCheckBox(v) self.grupaChk.addButton(self.chk, i) uklad.addWidget(self.chk) self.grupaChk.buttons()[self.ksztaltAktywny.ksztalt].setChecked(True) # CheckBox do wyboru aktywnego kształtu self.ksztaltChk = QCheckBox('<=') self.ksztaltChk.setChecked(True) uklad.addWidget(self.ksztaltChk) # układ poziomy dla kształtów oraz przycisków CheckBox ukladH1 = QHBoxLayout() ukladH1.addWidget(self.ksztalt1) ukladH1.addLayout(uklad) ukladH1.addWidget(self.ksztalt2) # koniec CheckBox ### # Slider i LCDNumber ### self.suwak = QSlider(Qt.Horizontal) self.suwak.setMinimum(0) self.suwak.setMaximum(255) self.lcd = QLCDNumber() self.lcd.setSegmentStyle(QLCDNumber.Flat) # układ poziomy (splitter) dla slajdera i lcd ukladH2 = QSplitter(Qt.Horizontal, self) ukladH2.addWidget(self.suwak) ukladH2.addWidget(self.lcd) ukladH2.setSizes((125, 75)) # przyciski RadioButton ### self.ukladR = QHBoxLayout() for v in ('R', 'G', 'B'): self.radio = QRadioButton(v) self.ukladR.addWidget(self.radio) self.ukladR.itemAt(0).widget().setChecked(True) # grupujemy przyciski self.grupaRBtn = QGroupBox('Opcje RGB') self.grupaRBtn.setLayout(self.ukladR) self.grupaRBtn.setObjectName('Radio') self.grupaRBtn.setCheckable(True) # układ poziomy dla grupy Radio ukladH3 = QHBoxLayout() ukladH3.addWidget(self.grupaRBtn) # koniec RadioButton ### # Lista ComboBox i SpinBox ### self.listaRGB = QComboBox(self) for v in ('R', 'G', 'B'): self.listaRGB.addItem(v) self.listaRGB.setEnabled(False) # SpinBox self.spinRGB = QSpinBox() self.spinRGB.setMinimum(0) self.spinRGB.setMaximum(255) self.spinRGB.setEnabled(False) # układ pionowy dla ComboBox i SpinBox uklad = QVBoxLayout() uklad.addWidget(self.listaRGB) uklad.addWidget(self.spinRGB) # do układu poziomego grupy Radio dodajemy układ ComboBox i SpinBox ukladH3.insertSpacing(1, 25) ukladH3.addLayout(uklad) # koniec ComboBox i SpinBox ### # przyciski PushButton ### uklad = QHBoxLayout() self.grupaP = QButtonGroup() self.grupaP.setExclusive(False) for v in ('R', 'G', 'B'): self.btn = QPushButton(v) self.btn.setCheckable(True) self.grupaP.addButton(self.btn) uklad.addWidget(self.btn) # grupujemy przyciski self.grupaPBtn = QGroupBox('Przyciski RGB') self.grupaPBtn.setLayout(uklad) self.grupaPBtn.setObjectName('Push') self.grupaPBtn.setCheckable(True) self.grupaPBtn.setChecked(False) # koniec PushButton ### # główny układ okna, wertykalny ### ukladOkna = QVBoxLayout() ukladOkna.addLayout(ukladH1) ukladOkna.addWidget(ukladH2) ukladOkna.addLayout(ukladH3) ukladOkna.addWidget(self.grupaPBtn) self.setLayout(ukladOkna) # przypisanie układu do okna głównego self.setWindowTitle('Widżety')
class AlterMessage(QDialog): close_signal = pyqtSignal() def __init__(self, mess, connfd): super(AlterMessage, self).__init__() self.connfd = connfd self.mess = mess.split('#') self.timekey = False self.data = '' self.initUI() def initUI(self): # 创建固定窗口大小 self.setFixedSize(535, 600) # 窗口标题 self.setWindowTitle('注册') # 无边框 self.setWindowFlags(Qt.FramelessWindowHint) self.setWindowIcon(QIcon(':/logo.png')) window_pale = QPalette() window_pale.setBrush(self.backgroundRole(),\ QBrush(QPixmap("UI/image/altermessage.jpg"))) self.setPalette(window_pale) #设置字体颜色 pe = QPalette() pe.setColor(QPalette.WindowText, Qt.white) # 程序名 self.lbl_main = QLabel('修改货运信息', self) self.lbl_main.move(10, 10) self.lbl_main.setPalette(pe) # 创建发货地级联布局 self.centralwidget = QWidget(self) self.centralwidget.setGeometry(90, 50, 400, 40) layout = QHBoxLayout(self.centralwidget) self.province_box = QComboBox(self, minimumWidth=30) # 市级以上 self.province_box.setMaxVisibleItems(35) self.city_box = QComboBox(self, minimumWidth=73) # 市 self.city_box.setMaxVisibleItems(35) self.county_box = QComboBox(self, minimumWidth=73) # 市级以下 self.county_box.setMaxVisibleItems(35) layout.addWidget(self.province_box) province = QLabel("省", self) province.setPalette(pe) layout.addWidget(province) layout.addItem( QSpacerItem(20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)) layout.addWidget(self.city_box) city = QLabel("市", self) city.setPalette(pe) layout.addWidget(city) layout.addItem( QSpacerItem(20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)) layout.addWidget(self.county_box) county = QLabel("区/县", self) county.setPalette(pe) layout.addWidget(county) # 创建目的地级联布局 self.centralwidget2 = QWidget(self) self.centralwidget2.setGeometry(90, 96, 400, 40) layout2 = QHBoxLayout(self.centralwidget2) self.province_box2 = QComboBox(self, minimumWidth=30) # 市级以上 self.province_box2.setMaxVisibleItems(35) self.city_box2 = QComboBox(self, minimumWidth=73) # 市 self.city_box2.setMaxVisibleItems(35) self.county_box2 = QComboBox(self, minimumWidth=73) # 市级以下 self.county_box2.setMaxVisibleItems(35) layout2.addWidget(self.province_box2) province2 = QLabel("省", self) province2.setPalette(pe) layout2.addWidget(province2) layout2.addItem( QSpacerItem(20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)) layout2.addWidget(self.city_box2) city2 = QLabel("市", self) city2.setPalette(pe) layout2.addWidget(city2) layout2.addItem( QSpacerItem(20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)) layout2.addWidget(self.county_box2) county2 = QLabel("区/县", self) county2.setPalette(pe) layout2.addWidget(county2) self.initModel() self.initSignal() self.initData() for i in range(self.province_box.count()): if self.province_box.itemText(i) == self.mess[1]: self.province_box.setCurrentIndex(i) break for i in range(self.city_box.count()): if self.city_box.itemText(i) == self.mess[2]: self.city_box.setCurrentIndex(i) break for i in range(self.county_box.count()): if self.county_box.itemText(i) == self.mess[3]: self.county_box.setCurrentIndex(i) break for i in range(self.province_box2.count()): if self.province_box2.itemText(i) == self.mess[4]: self.province_box2.setCurrentIndex(i) break for i in range(self.city_box2.count()): if self.city_box2.itemText(i) == self.mess[5]: self.city_box2.setCurrentIndex(i) break for i in range(self.county_box2.count()): if self.county_box2.itemText(i) == self.mess[6]: self.county_box2.setCurrentIndex(i) break #设置字体颜色 pe = QPalette() pe.setColor(QPalette.WindowText, Qt.darkGray) self.l = ['轻卡货车', '中型货车', '大型货车', '自卸货车', '半挂货车'] x = 100 self.bg1 = QButtonGroup(self) for i in range(len(self.l)): self.bu = QRadioButton(self.l[i], self) self.bu.setGeometry(x, 150, 75, 28) self.bu.setPalette(pe) self.bg1.addButton(self.bu, i) x += 80 self.info1 = self.mess[7] self.bg1.buttonClicked.connect(self.rbclicked) self.bg1.buttons()[self.l.index(self.mess[7])].toggle() self.l2 = ['均货', '重货', '轻货', '整车', '零担'] x = 100 self.bg12 = QButtonGroup(self) for i in range(10, 10 + len(self.l2)): self.bu = QRadioButton(self.l2[i - 10], self) self.bu.setGeometry(x, 180, 75, 28) # self.bu.toggle() self.bu.setPalette(pe) self.bg12.addButton(self.bu, i) x += 80 self.info12 = self.mess[8] self.bg12.buttonClicked.connect(self.rbclicked) self.bg12.buttons()[self.l2.index(self.mess[8])].toggle() self.l3 = ['普货', '鲜货', '冻货', '大件设备'] x = 100 self.bg13 = QButtonGroup(self) for i in range(20, 20 + len(self.l3)): self.bu = QRadioButton(self.l3[i - 20], self) self.bu.setGeometry(x, 210, 75, 28) self.bu.setPalette(pe) self.bg13.addButton(self.bu, i) x += 80 self.info13 = self.mess[9] self.bg13.buttonClicked.connect(self.rbclicked) self.bg13.buttons()[self.l3.index(self.mess[9])].toggle() self.l4 = ['无要求','20-50万','50-100万',\ '100-300万','300万以上'] x = 100 self.bg14 = QButtonGroup(self) for i in range(30, 30 + len(self.l4)): self.bu = QRadioButton(self.l4[i - 30], self) self.bu.setGeometry(x, 240, 75, 28) self.bu.setPalette(pe) self.bg14.addButton(self.bu, i) x += 80 self.info14 = self.mess[10] self.bg14.buttonClicked.connect(self.rbclicked) self.bg14.buttons()[self.l4.index(self.mess[10])].toggle() conceal = "background:\ transparent;border-width:0;border-style:outset" self.Edit_bulk = QLineEdit(self) self.Edit_bulk.setGeometry(100, 290, 100, 22) self.Edit_bulk.setPlaceholderText('方量') self.Edit_bulk.setStyleSheet(conceal) self.Edit_bulk.setValidator(QRegExpValidator\ (QRegExp(r"[0-9]+.?[0-9]?"),self)) self.Edit_bulk.setMaxLength(6) self.Edit_bulk.setToolTip('方量最大长度6位') self.Edit_bulk.setText(self.mess[11]) self.weight = QLineEdit(self) self.weight.setGeometry(245, 290, 100, 22) self.weight.setPlaceholderText('总吨位') self.weight.setStyleSheet(conceal) self.weight.setValidator(QRegExpValidator\ (QRegExp(r"[0-9]+.?[0-9]?"),self)) self.weight.setMaxLength(6) self.weight.setToolTip('吨位最大长度6位') self.weight.setText(self.mess[12]) self.Edit_total = QLineEdit(self) self.Edit_total.setGeometry(400, 290, 100, 22) self.Edit_total.setPlaceholderText('运费') self.Edit_total.setStyleSheet(conceal) self.Edit_total.setValidator(QRegExpValidator\ (QRegExp(r"[0-9]+"),self)) self.Edit_total.setMaxLength(7) self.Edit_total.setToolTip('运费最大长度为6位的整数') self.Edit_total.setText(self.mess[13]) self.text_describe = QTextEdit(self) self.text_describe.setGeometry(100, 340, 370, 150) self.text_describe.setToolTip('300字以内') self.text_describe.setStyleSheet(conceal) self.text_describe.setPlaceholderText('300字以内') self.text_describe.setPlainText(self.mess[15]) self.Edit_phone = QLineEdit(self) self.Edit_phone.setGeometry(100, 518, 150, 22) self.Edit_phone.setPlaceholderText('手机号码') self.Edit_phone.setStyleSheet(conceal) self.Edit_phone.setValidator(QRegExpValidator\ (QRegExp(r"[0-9]+"),self)) self.Edit_phone.setMaxLength(11) self.Edit_phone.setToolTip('联系电话11位') self.Edit_phone.setText(self.mess[14]) l = ['请选择','12小时','24小时','3天内','5天内',\ '1周内','1月内','3月内','1年内','永久'] self.combo = QComboBox(self) self.combo.addItems(l) self.combo.setGeometry(400, 518, 70, 20) validity = int(self.mess[17]) - int(self.mess[16]) if validity == 43200: validity = '12小时' elif validity == 86400: validity = '24小时' elif validity == 259200: validity = '3天内' elif validity == 432000: validity = '5天内' elif validity == 604800: validity = '1周内' elif validity == 2592000: validity = '1月内' elif validity == 7776000: validity = '3月内' elif validity == 31536000: validity = '1年内' elif validity == 999999999: validity = '永久' for i in range(self.combo.count()): if self.combo.itemText(i) == validity: self.combo.setCurrentIndex(i) break color2 = "QPushButton{border:none;}"\ "QPushButton:hover{border-image:url(%s);border:none;}" self.button_issue = QPushButton(' ', self) self.button_issue.setGeometry(100, 562, 230, 26) self.button_issue.setStyleSheet\ (color2 % 'UI/image/altermessage1.png') self.button_issue.clicked.connect(self.onissue) self.centralwidget = QWidget(self) self.centralwidget.setGeometry(350, 555, 150, 40) self.gridLayout = QGridLayout(self.centralwidget) # 定义获取焦点事件 self.Edit_bulk.installEventFilter(self) self.Edit_total.installEventFilter(self) self.text_describe.installEventFilter(self) self.Edit_phone.installEventFilter(self) self.combo.installEventFilter(self) self.province_box.installEventFilter(self) self.city_box.installEventFilter(self) self.county_box.installEventFilter(self) self.province_box2.installEventFilter(self) self.city_box2.installEventFilter(self) self.county_box2.installEventFilter(self) self.button_little = QPushButton(' ', self) self.button_little.setGeometry(471, 0, 32, 25) self.button_little.setToolTip('最小化') self.button_little.setStyleSheet\ (color2 % 'UI/image/login3.png') self.button_close = QPushButton(' ', self) self.button_close.setGeometry(503, 0, 32, 25) self.button_close.setToolTip('关闭') self.button_close.setStyleSheet\ (color2 % 'UI/image/login2.png') self.button_little.clicked.connect(self.showMinimized) # 定义获取焦点事件 def eventFilter(self, obj, event): if obj == self.Edit_bulk: if event.type() == QEvent.FocusIn: self.issue_Error_hint() return False elif obj == self.Edit_total: if event.type() == QEvent.FocusIn: self.issue_Error_hint() return False elif obj == self.text_describe: if event.type() == QEvent.FocusIn: self.issue_Error_hint() return False elif obj == self.Edit_phone: if event.type() == QEvent.FocusIn: self.issue_Error_hint() return False elif obj == self.combo: if event.type() == QEvent.FocusIn: self.issue_Error_hint() return False elif obj == self.province_box: if event.type() == QEvent.FocusIn: self.issue_Error_hint() return False elif obj == self.city_box: if event.type() == QEvent.FocusIn: self.issue_Error_hint() return False elif obj == self.county_box: if event.type() == QEvent.FocusIn: self.issue_Error_hint() return False elif obj == self.province_box2: if event.type() == QEvent.FocusIn: self.issue_Error_hint() return False elif obj == self.city_box2: if event.type() == QEvent.FocusIn: self.issue_Error_hint() return False elif obj == self.county_box2: if event.type() == QEvent.FocusIn: self.issue_Error_hint() return False def period_of_validity(self): now_time = round(time.time()) if self.combo.currentText() == '12小时': endtime = str(now_time + 43200) return str(now_time) + '#' + endtime elif self.combo.currentText() == '24小时': endtime = str(now_time + 86400) return str(now_time) + '#' + endtime elif self.combo.currentText() == '3天内': endtime = str(now_time + 259200) return str(now_time) + '#' + endtime elif self.combo.currentText() == '5天内': endtime = str(now_time + 432000) return str(now_time) + '#' + endtime elif self.combo.currentText() == '1周内': endtime = str(now_time + 604800) return str(now_time) + '#' + endtime elif self.combo.currentText() == '1月内': endtime = str(now_time + 2592000) return str(now_time) + '#' + endtime elif self.combo.currentText() == '3月内': endtime = str(now_time + 7776000) return str(now_time) + '#' + endtime elif self.combo.currentText() == '1年内': endtime = str(now_time + 31536000) return str(now_time) + '#' + endtime elif self.combo.currentText() == '永久': endtime = str(now_time + 999999999) return str(now_time) + '#' + endtime def onissue(self): s_province = self.province_box.currentText() s_city = self.city_box.currentText() s_county = self.county_box.currentText() m_province = self.province_box2.currentText() m_city = self.city_box2.currentText() m_county = self.county_box2.currentText() if s_province == '请选择': self.issue_Error_hint('*没有选择起始位置') return elif m_province == '请选择': self.issue_Error_hint('*没有选择目的地') return elif not self.info1: self.issue_Error_hint('*没有选择要求车型') return elif not self.info12: self.issue_Error_hint('*没有选择货物类别') return elif not self.info13: self.issue_Error_hint('*没有选择货物性质') return elif not self.info14: self.issue_Error_hint('*没有选择要求保险') return elif not self.Edit_bulk.text(): self.issue_Error_hint('*没有输入方量') return elif not self.weight.text(): self.issue_Error_hint('*没有输入重量') return elif not self.Edit_total.text(): self.issue_Error_hint('*没有输入总运费') return elif not self.text_describe.toPlainText(): self.issue_Error_hint('*详细描述不能为空(没有请写无)') return elif self.combo.currentText() == '请选择': self.issue_Error_hint('*没有选择有效期') return for i in self.text_describe.toPlainText(): if i in [' ', '#']: self.issue_Error_hint('*详细描述中不能有【空格】') return elif i in [' ', '#']: self.issue_Error_hint('*详细描述中不能有【#】') return data = 'UX ' + self.mess[0] + ' ' + s_province + '#' + s_city + '#' +\ s_county + '#' + m_province + '#' + m_city + '#' + m_county\ + '#' + self.info1 + '#' + self.info12 + '#' + self.info13\ + '#' + self.info14 + '#' + self.Edit_bulk.text()\ + '#' + self.weight.text() + '#' + self.Edit_total.text()\ + '#' + self.Edit_phone.text() + '#' + \ self.text_describe.toPlainText() if self.data == data: return self.issue_Error_hint('*不能发布重复信息') self.data = data data = data + '#' + self.period_of_validity() # 让这个变量为True self.timekey = True self.threadmess = MyThread(self.connfd, data) self.threadmess.messageSignal.connect(self.handle_return_message) self.threadmess.start() # 处理返回的情况处理 def handle_return_message(self, mess): self.threadmess.deleteLater() if mess == 'UXNO NoData': self.issue_Error_hint('*修改失败') elif mess == 'UXOK ': self.issue_Error_hint('*修改成功') else: pass # 把按键检测变为False self.timekey = False def issue_Error_hint(self, show=' '): try: sip.delete(self.user_hint) except AttributeError: pass pe_red = QPalette() pe_red.setColor(QPalette.WindowText, Qt.red) self.user_hint = QLabel(show, self.centralwidget) self.user_hint.setPalette(pe_red) self.gridLayout.addWidget(self.user_hint, 0, 0, 1, 1) QApplication.processEvents() def rbclicked(self): sender = self.sender() if sender == self.bg1: if self.bg1.checkedId() == 0: self.info1 = self.l[0] elif self.bg1.checkedId() == 1: self.info1 = self.l[1] elif self.bg1.checkedId() == 2: self.info1 = self.l[2] elif self.bg1.checkedId() == 3: self.info1 = self.l[3] elif self.bg1.checkedId() == 4: self.info1 = self.l[4] else: self.info1 = '' self.issue_Error_hint() elif sender == self.bg12: if self.bg12.checkedId() == 10: self.info12 = self.l2[0] elif self.bg12.checkedId() == 11: self.info12 = self.l2[1] elif self.bg12.checkedId() == 12: self.info12 = self.l2[2] elif self.bg12.checkedId() == 13: self.info12 = self.l2[3] elif self.bg12.checkedId() == 14: self.info12 = self.l2[4] else: self.info12 = '' self.issue_Error_hint() elif sender == self.bg13: if self.bg13.checkedId() == 20: self.info13 = self.l3[0] elif self.bg13.checkedId() == 21: self.info13 = self.l3[1] elif self.bg13.checkedId() == 22: self.info13 = self.l3[2] elif self.bg13.checkedId() == 23: self.info13 = self.l3[3] else: self.info13 = '' self.issue_Error_hint() elif sender == self.bg14: if self.bg14.checkedId() == 30: self.info14 = self.l4[0] elif self.bg14.checkedId() == 31: self.info14 = self.l4[1] elif self.bg14.checkedId() == 32: self.info14 = self.l4[2] elif self.bg14.checkedId() == 33: self.info14 = self.l4[3] elif self.bg14.checkedId() == 34: self.info14 = self.l4[4] else: self.info14 = '' self.issue_Error_hint() def initSignal(self): # 初始化信号槽 self.province_box.currentIndexChanged.connect\ (self.city_model.setFilter) self.city_box.currentIndexChanged.connect\ (self.county_model.setFilter) self.province_box2.currentIndexChanged.connect\ (self.city_model2.setFilter) self.city_box2.currentIndexChanged.connect\ (self.county_model2.setFilter) def initModel(self): # 初始化模型 self.province_model = SortFilterProxyModel(self) self.city_model = SortFilterProxyModel(self) self.county_model = SortFilterProxyModel(self) # 设置模型 self.province_box.setModel(self.province_model) self.city_box.setModel(self.city_model) self.county_box.setModel(self.county_model) # 初始化模型 self.province_model2 = SortFilterProxyModel(self) self.city_model2 = SortFilterProxyModel(self) self.county_model2 = SortFilterProxyModel(self) # 设置模型 self.province_box2.setModel(self.province_model2) self.city_box2.setModel(self.city_model2) self.county_box2.setModel(self.county_model2) def initData(self): # 初始化数据 datas = open("UI/data.json", "rb").read() encoding = chardet.detect(datas) or {} datas = datas.decode(encoding.get("encoding", "utf-8")) datas = json.loads(datas) # 开始解析数据 for data in datas: item_code = data.get("item_code") # 编码 item_name = data.get("item_name") # 名字 item = QStandardItem(item_name) item.setData(item_code, Qt.ToolTipRole) if item_code.endswith("0000"): # 4个0结尾的是市级以上的 self.province_model.appendRow(item) elif item_code.endswith("00"): # 2个0结尾的是市 self.city_model.appendRow(item) else: # 市以下 self.county_model.appendRow(item) # 开始解析数据 for data in datas: item_code = data.get("item_code") # 编码 item_name = data.get("item_name") # 名字 item = QStandardItem(item_name) item.setData(item_code, Qt.ToolTipRole) if item_code.endswith("0000"): # 4个0结尾的是市级以上的 self.province_model2.appendRow(item) elif item_code.endswith("00"): # 2个0结尾的是市 self.city_model2.appendRow(item) else: # 市以下 self.county_model2.appendRow(item) def handle_size(self, left, top): screen = self.frameGeometry() # 窗口显示位置 wall = QDesktopWidget().availableGeometry().center() screen.moveCenter(wall) if left < 0: left = 0 if top < 0: top = 0 if left > screen.left() * 2: left = screen.left() * 2 if top > screen.top() * 2: top = screen.top() * 2 self.move(left, top) QApplication.processEvents() # 把隐藏的窗口显示出来 def handle_click(self): if not self.isVisible(): self.show() # 对ESC进行的重载 按ESC也有退出的功能 def keyPressEvent(self, event): if event.key() == Qt.Key_Escape: self.close() self.close_signal.emit() # 重写无边框拖动方法 def mouseMoveEvent(self, e: QMouseEvent): try: self._endPos = e.pos() - self._startPos self.move(self.pos() + self._endPos) except TypeError: pass def mousePressEvent(self, e: QMouseEvent): if e.button() == Qt.LeftButton: self._isTracking = True self._startPos = QPoint(e.x(), e.y()) def mouseReleaseEvent(self, e: QMouseEvent): if e.button() == Qt.LeftButton: self._isTracking = False self._startPos = None self._endPos = None
class TabThermopylae(QWidget): """ Thermopylae, JueZhan Mode, first introduced in Game v5.0.0 (CN server). This tab is meant for automatically farming Thermopylae Ex-6 (the last chapter of the mode), which was the primary reason that brings WGViewer into real world. """ sig_fuel = pyqtSignal(int) sig_ammo = pyqtSignal(int) sig_steel = pyqtSignal(int) sig_baux = pyqtSignal(int) sig_repair = pyqtSignal(int) sig_exp = pyqtSignal(dict) def __init__(self, tab_name: str, side_dock: SideDock, is_realrun: bool): super().__init__() self.setObjectName(tab_name) self.side_dock = side_dock self.resource_info: ResourceTableModel = self.side_dock.table_model self.is_realrun = is_realrun # Signals self.sig_fuel.connect(self.resource_info.update_fuel) self.sig_ammo.connect(self.resource_info.update_ammo) self.sig_steel.connect(self.resource_info.update_steel) self.sig_baux.connect(self.resource_info.update_bauxite) self.sig_repair.connect(self.resource_info.update_repair) self.sig_exp.connect(self.side_dock.update_lvl_label) # Members self.api = API_SIX(wgv_data.load_cookies()) self.qsettings = QSettings(wgv_data.get_qsettings_file(), QSettings.IniFormat) self.user_ships = wgv_data.get_processed_userShipVo() self.battle_fleet: list = [None] * 6 self.escort_DD: list = [None] * 2 self.escort_CV: list = [None] self.user_chosen_cid: list = [None] * 9 self.ship_select_window = None self.sortie = None # Threads self.bee_pre_battle = None self.bee_fresh_sortie = None self.bee_resume_sortie = None # UI members self.main_layout = QHBoxLayout(self) self.left_layout = QGridLayout() self.right_layout = QVBoxLayout() self.ticket_label = QLabel("?") self.button_purchase = QPushButton("?") self.adjutant_label = QLabel("?") self.adjutant_exp_label = QLabel("?/?") self.points_label = QLabel("?") self._label = None self._is_first_timer: bool = True self._is_speed_mode: bool = False self._clicks: int = 0 self._is_timer_start: bool = False self._timer = QTimer(self) self._timer.timeout.connect(self._check_label) self.set_ticket_display() self.set_adjutant_display() self.ship_button_group = QButtonGroup() self.boat_pool_label = QLabel() self.fleet_label = QLabel() self.ui_buttons = QButtonGroup() self.button_set_ships = QPushButton('&Set fleet') self.button_pre_battle = QPushButton('&Pre-Battle Check') self.button_fresh_sortie = QPushButton('Fresh &Combat') self.button_resume_sortie = QPushButton('&Resume Combat') self.button_stop_sortie = QPushButton('Stop Task') self.multi_runs = QSpinBox() self.init_left_layout() self.right_text_box = QTextEdit() # after right_text_box creation self.logger = get_new_logger(name=QLOGS.TAB_THER, level=QLOGS.LVL_INFO, signal=self.right_text_box.append) self.init_right_layout() self.init_ui() def init_ui(self) -> None: self.main_layout.setContentsMargins(0, 0, 0, 0) self.main_layout.addLayout(self.left_layout) self.main_layout.addLayout(self.right_layout) self.main_layout.setStretch(0, 1) self.main_layout.setStretch(1, 1) self.setLayout(self.main_layout) def init_left_layout(self) -> None: self.button_purchase.setEnabled(False) t = QTextEdit() msg = "Notes\n" msg += "1. As of now, this auto sortie function is ONLY for players who passed E6 manually;\n" msg += "2. Adjutant 紫貂 (default) and Habakkuk (purchased in shop) are required;\n" msg += "3. Ships under Lv. 80 cannot be selected.\n" msg += "\nHow to Use\n" msg += "1. Select ships (rest non-battle ships are selected from old settings), then press 'Set fleet'\n" msg += "2. Press 'Pre-Battle Check'\n" msg += "3. Adjust your desired sortie times\n" msg += "4. Press 'Fresh Combat' or 'Resume Combat'\n" msg += "?. Now just wait or find an easter egg to boost sortie speed" t.setFontPointSize(10) t.setText(msg) t.setReadOnly(True) self.boat_pool_label.setFont(QFont('Consolas')) self.boat_pool_label.setWordWrap(True) self.boat_pool_label.setText('BOAT POOL |') self.fleet_label.setFont(QFont('Consolas')) self.fleet_label.setWordWrap(True) self.fleet_label.setText('ON BATTLE |') self.button_set_ships.clicked.connect(self.check_selections) self.ui_buttons.addButton(self.button_set_ships) self.button_pre_battle.clicked.connect(self.on_pre_battle) self.ui_buttons.addButton(self.button_pre_battle) self.button_fresh_sortie.clicked.connect(self.on_fresh_sortie) self.ui_buttons.addButton(self.button_fresh_sortie) self.button_resume_sortie.clicked.connect(self.on_resume_sortie) self.ui_buttons.addButton(self.button_resume_sortie) self.multi_runs.setEnabled(False) self.multi_runs.setSuffix(" times") self.button_stop_sortie.clicked.connect(self.disable_sortie) self.ui_buttons.addButton(self.button_stop_sortie) for b in self.ui_buttons.buttons(): b.setEnabled(False) self.button_set_ships.setEnabled(True) self.left_layout.addWidget(t, 3, 0, 1, 4) if self.qsettings.contains(QKEYS.THER_DD) and self.qsettings.contains( QKEYS.THER_CV) and self.qsettings.contains(QKEYS.THER_SS): self.escort_DD: list = list( map(int, self.qsettings.value(QKEYS.THER_DD))) self.escort_CV: list = list( map(int, self.qsettings.value(QKEYS.THER_CV))) self.battle_fleet: list = list( map(int, self.qsettings.value(QKEYS.THER_SS))) ssb = self.set_ship_selection_buttons(dd=self.escort_DD, cv=self.escort_CV, ss=self.battle_fleet) else: ssb = self.set_ship_selection_buttons() self.left_layout.addWidget(ssb, 4, 0, 2, 4) self.left_layout.addWidget(self.button_set_ships, 6, 0, 1, 2) self.left_layout.addWidget(self.button_pre_battle, 6, 2, 1, 2) self.left_layout.addWidget(self.fleet_label, 7, 0, 1, 4) self.left_layout.addWidget(self.boat_pool_label, 8, 0, 1, 4) self.left_layout.addWidget(self.button_fresh_sortie, 9, 0) self.left_layout.addWidget(self.button_resume_sortie, 9, 1) self.left_layout.addWidget(self.multi_runs, 9, 2) self.left_layout.addWidget(self.button_stop_sortie, 9, 3) self.left_layout.setRowStretch(3, 5) self.left_layout.setRowStretch(4, 1) def init_right_layout(self) -> None: self.right_text_box.document().setMaximumBlockCount(100) self.right_text_box.setFont(QFont('Consolas')) self.right_text_box.setFontPointSize(10) self.right_text_box.setReadOnly(True) self.right_layout.addWidget(self.right_text_box) def set_ticket_display(self) -> None: w = QWidget() layout = QHBoxLayout(w) layout.setContentsMargins(0, 0, 0, 0) self.button_purchase.clicked.connect(self.on_purchase_clicked) layout.addWidget(QLabel("Remaining Sortie Tickets")) layout.addWidget(self.ticket_label) layout.addWidget(QLabel("Purchasable Tickets")) layout.addWidget(self.button_purchase) w.setLayout(layout) for i in range(4): layout.setStretch(i, 0) self.left_layout.addWidget(w, 0, 0, 1, 4) def set_adjutant_display(self) -> None: w = QWidget() layout = QHBoxLayout(w) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(QLabel("Adjutant")) layout.addWidget(self.adjutant_label) layout.addWidget(self.adjutant_exp_label) # secret switch for disable sleep event self._label = ClickableLabel() self._label.setText("Point") self._label.clicked.connect(self._label_clicked) layout.addWidget(self._label) layout.addWidget(self.points_label) w.setLayout(layout) self.left_layout.addWidget(w, 1, 0, 1, 4) def disable_sortie_widgets(self): for b in self.ship_button_group.buttons(): b.setEnabled(False) for b in self.ui_buttons.buttons(): b.setEnabled(False) self.multi_runs.setEnabled(False) def enable_sortie_widgets(self): for b in self.ship_button_group.buttons(): b.setEnabled(True) for b in self.ui_buttons.buttons(): b.setEnabled(True) self.multi_runs.setEnabled(True) # ================================ # Signals # ================================ def _label_clicked(self) -> None: if self._is_speed_mode: return if self._is_timer_start: self._clicks += 1 else: if self._is_first_timer: self._timer.start(2000) self._is_timer_start = True self._is_first_timer = False else: pass def _check_label(self) -> None: self._timer.stop() if self._clicks > 10: self._is_speed_mode = True self.logger.warning("WGViewer boost is ON!") stop_sleep_event() else: self._is_speed_mode = False self._is_timer_start = False self._is_first_timer = True self._clicks = 0 def disable_sortie(self) -> None: stop_sleep_event() self.button_stop_sortie.setEnabled(False) if self.bee_fresh_sortie.isRunning(): self.logger.debug('fresh-sortie thread is running...') self.sortie.stop() elif self.bee_resume_sortie.isRunning(): self.logger.debug('resume-sortie thread is running...') self.sortie.stop() # elif self.bee_pre_battle.isRunning(): # self.logger.debug('pre-battle checking thread is running...') # self.sortie.stop() else: self.logger.debug('No thread to disable') def on_purchase_clicked(self) -> None: self.sortie.buy_ticket() def on_pre_battle(self) -> None: self.disable_sortie_widgets() self.qsettings.setValue(QKEYS.THER_DD, self.escort_DD) self.qsettings.setValue(QKEYS.THER_CV, self.escort_CV) self.qsettings.setValue(QKEYS.THER_SS, self.battle_fleet) self.sortie = Sortie(self, self.api, self.escort_DD, self.escort_CV, self.battle_fleet, self.is_realrun) self.bee_pre_battle = CallbackWorker(self.sortie.pre_battle, (), self.pre_battle_finished) self.bee_pre_battle.terminate() self.bee_fresh_sortie = CallbackWorker(self.sortie.start_fresh_sortie, (), self.sortie_finished) self.bee_fresh_sortie.terminate() self.bee_resume_sortie = CallbackWorker(self.sortie.resume_sortie, (), self.sortie_finished) self.bee_resume_sortie.terminate() self.bee_pre_battle.start() def on_fresh_sortie(self) -> None: reset_sleep_event() self._is_speed_mode = False self._is_timer_start = False self._is_first_timer = True self.disable_sortie_widgets() self.button_stop_sortie.setEnabled(True) self.bee_fresh_sortie.start() def on_resume_sortie(self) -> None: reset_sleep_event() self._is_speed_mode = False self._is_timer_start = False self._is_first_timer = True self.disable_sortie_widgets() self.button_stop_sortie.setEnabled(True) self.bee_resume_sortie.start() def sortie_finished(self, result: bool) -> None: self.logger.info('==== Sortie is done! ====') self.enable_sortie_widgets() self.button_stop_sortie.setEnabled(False) if result is True: self.logger.debug('sortie success!') self.multi_runs.stepDown() if self.multi_runs.value() > 0: set_sleep() self.logger.info('Starting a new run') self.bee_fresh_sortie.start() else: self.logger.info("Completed sortie plan!") else: self.logger.debug('sortie failed') if int(self.ticket_label.text()) == 0: self.button_fresh_sortie.setEnabled(False) self.button_resume_sortie.setEnabled(False) def pre_battle_finished(self, result: bool) -> None: if result is True: self.logger.info('==== Pre battle checking is done! ====') else: self.logger.warning('==== Cannot start sortie ====') # ================================ # Update Side Dock # ================================ def update_resources(self, f: int, a: int, s: int, b: int) -> None: # signals has to be emitted from a QObject self.sig_fuel.emit(f) self.sig_ammo.emit(a) self.sig_steel.emit(s) self.sig_baux.emit(b) def update_repair_bucket(self, b): self.sig_repair.emit(b) def update_user_exp_label(self, x: dict) -> None: self.sig_exp.emit(x) # ================================ # Update left-layout display # ================================ def update_ticket(self, data: int) -> None: self.ticket_label.setText(str(data)) def update_purchasable(self, data: int) -> None: self.button_purchase.setText(str(data)) def update_adjutant_name(self, data: str) -> None: self.adjutant_label.setText(data) def update_adjutant_exp(self, data: str) -> None: self.adjutant_exp_label.setText(data) def update_points(self, data: str) -> None: self.points_label.setText(str(data)) def update_boat_pool_label(self, data: str) -> None: self.boat_pool_label.setText(data) def update_fleet_label(self, data: str) -> None: self.fleet_label.setText(data) # ================================ # Left Panel - Ship Selection # ================================ def set_ship_selection_buttons(self, dd: list = None, cv: list = None, ss: list = None) -> QWidget: def _create_button(t, l, idx, lay, lim=None, cid=None) -> QPushButton: b = QPushButton() b.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) if cid is None: b.setText(f'+\n{t}') else: ship = self.user_ships[str(cid)] b.setText(f"{ship['Class']}\n{ship['Name']}\nLv.{ship['Lv.']}") b.clicked.connect( lambda _, _i=idx: self.popup_select_window(_i, l, lim)) lay.addWidget(b) self.ship_button_group.addButton(b) return b w = QWidget() v_layout = QVBoxLayout(w) row_1 = QHBoxLayout() row_1.setContentsMargins(0, 0, 0, 0) if dd is not None: _create_button(t='LOW COST DD', l=['DD'], idx=0, lay=row_1, lim=[1, 2], cid=dd[0]) _create_button(t='LOW COST DD', l=['DD'], idx=1, lay=row_1, lim=[1, 2, 3], cid=dd[1]) else: _create_button(t='LOW COST DD', l=['DD'], idx=0, lay=row_1, lim=[1, 2]) _create_button(t='LOW COST DD', l=['DD'], idx=1, lay=row_1, lim=[1, 2, 3]) if cv is not None: _create_button(t='LOW COST CV/AV', l=['CV', 'AV'], idx=2, lay=row_1, lim=[1, 2, 3], cid=cv[0]) else: _create_button(t='LOW COST CV/AV', l=['CV', 'AV'], idx=2, lay=row_1, lim=[1, 2, 3]) row_2 = QHBoxLayout() row_2.setContentsMargins(0, 0, 0, 0) for i in range(3, 9): if ss is not None: _create_button(t='SS', l=['SS'], idx=i, lay=row_2, cid=ss[i - 3]) else: _create_button(t='SS', l=['SS'], idx=i, lay=row_2) v_layout.addLayout(row_1) v_layout.addLayout(row_2) return w def handle_selection(self, ship_info: list, button_id: int) -> None: b = self.ship_button_group.buttons()[button_id] ship_id = ship_info[1] if ship_info[-1] in self.user_chosen_cid: b.setText("SHIP EXISTS\nPLEASE CHANGE") else: self.ship_select_window.close() self.ship_select_window.deleteLater() self.ship_select_window = None self.user_chosen_cid[button_id] = ship_info[-1] if button_id in [0, 1]: self.escort_DD[button_id] = int(ship_id) elif button_id == 2: self.escort_CV[0] = int(ship_id) else: self.battle_fleet[button_id - 3] = int(ship_id) s = f'{ship_info[0]}\n{ship_info[2]}\n{ship_info[3]}' b.setText(s) def popup_select_window(self, btn_id: int, ship_class: list, cost_lim: list = None) -> None: self.ship_select_window = ShipSelectWindow(self, btn_id, ship_class, cost_lim) self.ship_select_window.show() def check_selections(self) -> None: try: assert (None not in self.escort_DD) except AssertionError: self.logger.warning('DD are not set') return try: assert (None not in self.escort_CV) except AssertionError: self.logger.warning('CV are not set') return try: assert (None not in self.battle_fleet) except AssertionError: self.logger.warning('SS are not set') return self.button_pre_battle.setEnabled(True)
class FoodOrder(QWidget): def __init__(self): super().__init__() self.initialize_ui() def initialize_ui(self): self.setMinimumSize(600, 700) self.setWindowTitle('Food Order GUI') self.setupTabsAndLayout() self.show() def setupTabsAndLayout(self): """ Set up tab bar and different tab widgets. Also, create the side widget to display items selected. """ self.tab_bar = QTabWidget() self.pizza_tab = QWidget() self.pizza_tab.setObjectName("Tabs") self.wings_tab = QWidget() self.wings_tab.setObjectName("Tabs") self.tab_bar.addTab(self.pizza_tab, "Pizza") self.tab_bar.addTab(self.wings_tab, "Wings") self.pizzaTab() self.wingsTab() # Set up side widget which is not part of the tab widget self.side_widget = QWidget() self.side_widget.setObjectName("Tabs") order_label = QLabel("YOUR ORDER") order_label.setObjectName("Header") items_box = QWidget() items_box.setObjectName("Side") pizza_label = QLabel("Pizza Type: ") self.display_pizza_label = QLabel("") toppings_label = QLabel("Toppings: ") self.display_toppings_label = QLabel("") extra_label = QLabel("Extra: ") self.display_wings_label = QLabel("") # Set grid layout for objects in side widget items_grid = QGridLayout() items_grid.addWidget(pizza_label, 0, 0, Qt.AlignRight) items_grid.addWidget(self.display_pizza_label, 0, 1) items_grid.addWidget(toppings_label, 1, 0, Qt.AlignRight) items_grid.addWidget(self.display_toppings_label, 1, 1) items_grid.addWidget(extra_label, 2, 0, Qt.AlignRight) items_grid.addWidget(self.display_wings_label, 2, 1) items_box.setLayout(items_grid) # Set main layout for side widget side_v_box = QVBoxLayout() side_v_box.addWidget(order_label) side_v_box.addWidget(items_box) side_v_box.addStretch() self.side_widget.setLayout(side_v_box) # Add widgets to main window and set layout main_h_box = QHBoxLayout() main_h_box.addWidget(self.tab_bar) main_h_box.addWidget(self.side_widget) self.setLayout(main_h_box) def pizzaTab(self): """ Create the pizza tab. Allows the user to select the type of pizza and topping using radio buttons. """ tab_pizza_label = QLabel("BUILD YOUR OWN PIZZA") tab_pizza_label.setObjectName("Header") description_box = QWidget() description_box.setObjectName("ImageBorder") pizza_image_path = "images/pizza.png" pizza_image = self.loadImage(pizza_image_path) pizza_desc = QLabel() pizza_desc.setObjectName("ImageInfo") pizza_desc.setText( "Build a custom pizza for you. Start with your favorite crust and add any toppings, " "plus the perfect amount of cheese and sauce.") pizza_desc.setWordWrap(True) h_box = QHBoxLayout() h_box.addWidget(pizza_image) h_box.addWidget(pizza_desc) description_box.setLayout(h_box) crust_gbox = QGroupBox() crust_gbox.setTitle("CHOOSE YOUR CRUST") self.crust_group = QButtonGroup() gb_v_box = QVBoxLayout() crust_list = ["Hand-Tossed", "Flat", "Stuffed"] for cr in crust_list: crust_rb = QRadioButton(cr) gb_v_box.addWidget(crust_rb) self.crust_group.addButton(crust_rb) crust_gbox.setLayout(gb_v_box) # Create group box that will contain toppings choices toppings_gbox = QGroupBox() toppings_gbox.setTitle("CHOOSE YOUR TOPPINGS") # Set up button group for toppings radio buttons self.toppings_group = QButtonGroup() gb_v_box = QVBoxLayout() toppings_list = [ "Pepperoni", "Sausage", "Bacon", "Canadian Bacon", "Beef", "Pineapple", "Mushroom", "Onion", "Olive", "Green Pepper", "Tomato", "Spinach", "Cheese" ] # Create radio buttons for the different toppings and # add to layout for top in toppings_list: toppings_rb = QRadioButton(top) gb_v_box.addWidget(toppings_rb) self.toppings_group.addButton(toppings_rb) self.toppings_group.setExclusive(False) toppings_gbox.setLayout(gb_v_box) # Create button to add information to side widget # when clicked add_to_order_button1 = QPushButton("Add To Order") add_to_order_button1.clicked.connect(self.displayPizzaInOrder) # create layout for pizza tab (page 1) page1_v_box = QVBoxLayout() page1_v_box.addWidget(tab_pizza_label) page1_v_box.addWidget(description_box) page1_v_box.addWidget(crust_gbox) page1_v_box.addWidget(toppings_gbox) page1_v_box.addStretch() page1_v_box.addWidget(add_to_order_button1, alignment=Qt.AlignRight) self.pizza_tab.setLayout(page1_v_box) def wingsTab(self): """ Set up widgets and layouts to display information to the user about the page """ tab_wings_label = QLabel("TRY OUR AMAZING WINGS") tab_wings_label.setObjectName("Header") description_box = QWidget() description_box.setObjectName("ImageBorder") wings_image_path = "images/wings.png" wings_image = self.loadImage(wings_image_path) wings_desc = QLabel() wings_desc.setObjectName("ImageInfo") wings_desc.setText( "6 pieces of rich-tasting, white meat chicken that will have you coming back for more." ) wings_desc.setWordWrap(True) h_box = QHBoxLayout() h_box.addWidget(wings_image) h_box.addWidget(wings_desc) description_box.setLayout(h_box) wings_gbox = QGroupBox() wings_gbox.setTitle("CHOOSE YOUR FLAVOR") self.wings_group = QButtonGroup() gb_v_box = QVBoxLayout() wings_list = ["Buffalo", "Sweet-Sour", "Teriyaki", "Barbecue"] for fl in wings_list: flavor_rb = QRadioButton(fl) gb_v_box.addWidget(flavor_rb) self.wings_group.addButton(flavor_rb) wings_gbox.setLayout(gb_v_box) add_to_order_button2 = QPushButton("Add To Order") add_to_order_button2.clicked.connect(self.displayWingsInOrder) page2_v_box = QVBoxLayout() page2_v_box.addWidget(tab_wings_label) page2_v_box.addWidget(description_box) page2_v_box.addWidget(wings_gbox) page2_v_box.addWidget(add_to_order_button2, alignment=Qt.AlignRight) page2_v_box.addStretch() self.wings_tab.setLayout(page2_v_box) def collectTopingfInList(self): """ Create list of all checked toppings radio buttons. """ return [ button.text() for i, button in enumerate(self.toppings_group.buttons()) if button.isChecked() ] def displayPizzaInOrder(self): """ Collect the text from the radio buttons that are checked on pizza page. Display text in side widget. """ try: pizza_text = self.crust_group.checkedButton().text() self.display_pizza_label.setText(pizza_text) toppings = self.collectTopingfInList() toppings_str = '\n'.join(toppings) self.display_toppings_label.setText(toppings_str) self.repaint() except AttributeError: print("No value selected.") QMessageBox.warning(self, "Error", "No value selected", QMessageBox.Ok) pass def displayWingsInOrder(self): """ Collect the text from the radio buttons that are checked on wings page. Display text in side widget. """ try: text = self.wings_group.checkedButton().text() + " Wings" self.display_wings_label.setText(text) self.repaint() except AttributeError: # print("No value selected.") QMessageBox.warning(self, "Error", "No value selected", QMessageBox.Ok) pass def loadImage(self, path): """ Load and scale images. :param path: path to the file """ try: with open(path): image = QLabel(self) image.setObjectName("ImageInfo") pixmap = QPixmap(path) image.setPixmap( pixmap.scaled(image.size(), Qt.KeepAspectRatioByExpanding, Qt.SmoothTransformation)) return image except FileNotFoundError: print("Image not found.")
class SendConfigDialog(QDialog): def __init__(self): super().__init__() self.setMinimumWidth(640) self.setWindowTitle("Send configuration to device") self.settings = QSettings("tasmotizer.cfg", QSettings.IniFormat) self.commands = None self.module_mode = 0 self.createUI() self.loadSettings() def createUI(self): vl = VLayout() self.setLayout(vl) # Wifi groupbox self.gbWifi = QGroupBox("WiFi") self.gbWifi.setCheckable(True) self.gbWifi.setChecked(False) flWifi = QFormLayout() self.leAP = QLineEdit() self.leAPPwd = QLineEdit() self.leAPPwd.setEchoMode(QLineEdit.Password) flWifi.addRow("SSID", self.leAP) flWifi.addRow("Password", self.leAPPwd) self.gbWifi.setLayout(flWifi) # Recovery Wifi groupbox self.gbRecWifi = QGroupBox("Recovery WiFi") self.gbRecWifi.setCheckable(True) self.gbRecWifi.setChecked(False) flRecWifi = QFormLayout() lbRecAP = QLabel("Recovery") lbRecAP.setAlignment(Qt.AlignVCenter | Qt.AlignRight) lbRecAPPwd = QLabel("a1b2c3d4") lbRecAPPwd.setAlignment(Qt.AlignVCenter | Qt.AlignRight) flRecWifi.addRow("SSID", lbRecAP) flRecWifi.addRow("Password", lbRecAPPwd) self.gbRecWifi.setLayout(flRecWifi) vl_wifis = VLayout(0) vl_wifis.addWidgets([self.gbWifi, self.gbRecWifi]) # MQTT groupbox self.gbMQTT = QGroupBox("MQTT") self.gbMQTT.setCheckable(True) self.gbMQTT.setChecked(False) flMQTT = QFormLayout() self.leBroker = QLineEdit() self.sbPort = SpinBox() self.sbPort.setValue(1883) self.leTopic = QLineEdit() self.leTopic.setText("tasmota") self.leFullTopic = QLineEdit() self.leFullTopic.setText("%prefix%/%topic%/") self.leFriendlyName = QLineEdit() self.leMQTTUser = QLineEdit() self.leMQTTPass = QLineEdit() self.leMQTTPass.setEchoMode(QLineEdit.Password) flMQTT.addRow("Host", self.leBroker) flMQTT.addRow("Port", self.sbPort) flMQTT.addRow("Topic", self.leTopic) flMQTT.addRow("FullTopic", self.leFullTopic) flMQTT.addRow("FriendlyName", self.leFriendlyName) flMQTT.addRow("User [optional]", self.leMQTTUser) flMQTT.addRow("Password [optional]", self.leMQTTPass) self.gbMQTT.setLayout(flMQTT) # Module/template groupbox self.gbModule = GroupBoxV("Module/template") self.gbModule.setCheckable(True) self.gbModule.setChecked(False) hl_m_rb = HLayout() self.rbModule = QRadioButton("Module") self.rbModule.setChecked(True) self.rbTemplate = QRadioButton("Template") hl_m_rb.addWidgets([self.rbModule, self.rbTemplate]) self.rbgModule = QButtonGroup(self.gbModule) self.rbgModule.addButton(self.rbModule, 0) self.rbgModule.addButton(self.rbTemplate, 1) self.cbModule = QComboBox() for mod_id, mod_name in modules.items(): self.cbModule.addItem(mod_name, mod_id) self.leTemplate = QLineEdit() self.leTemplate.setPlaceholderText("Paste template string here") self.leTemplate.setVisible(False) self.gbModule.addLayout(hl_m_rb) self.gbModule.addWidgets([self.cbModule, self.leTemplate]) self.rbgModule.buttonClicked[int].connect(self.setModuleMode) # layout all widgets hl_wifis_mqtt = HLayout(0) hl_wifis_mqtt.addLayout(vl_wifis) hl_wifis_mqtt.addWidget(self.gbMQTT) vl.addLayout(hl_wifis_mqtt) vl.addWidget(self.gbModule) btns = QDialogButtonBox(QDialogButtonBox.Save | QDialogButtonBox.Close) btns.accepted.connect(self.accept) btns.rejected.connect(self.reject) vl.addWidget(btns) def loadSettings(self): self.gbWifi.setChecked(self.settings.value("gbWifi", False, bool)) self.leAP.setText(self.settings.value("AP")) self.gbRecWifi.setChecked(self.settings.value("gbRecWifi", False, bool)) self.gbMQTT.setChecked(self.settings.value("gbMQTT", False, bool)) self.leBroker.setText(self.settings.value("Broker")) self.sbPort.setValue(self.settings.value("Port", 1883, int)) self.leTopic.setText(self.settings.value("Topic", "tasmota")) self.leFullTopic.setText( self.settings.value("FullTopic", "%prefix%/%topic%/")) self.leFriendlyName.setText(self.settings.value("FriendlyName")) self.leMQTTUser.setText(self.settings.value("MQTTUser")) self.gbModule.setChecked(self.settings.value("gbModule", False, bool)) module_mode = self.settings.value("ModuleMode", 0, int) for b in self.rbgModule.buttons(): if self.rbgModule.id(b) == module_mode: b.setChecked(True) self.setModuleMode(module_mode) self.cbModule.setCurrentText(self.settings.value("Module", "Generic")) self.leTemplate.setText(self.settings.value("Template")) def setModuleMode(self, radio): self.module_mode = radio self.cbModule.setVisible(not radio) self.leTemplate.setVisible(radio) def accept(self): ok = True if self.gbWifi.isChecked() and (len(self.leAP.text()) == 0 or len(self.leAPPwd.text()) == 0): ok = False QMessageBox.warning(self, "WiFi details incomplete", "Input WiFi AP and Password") if self.gbMQTT.isChecked() and not self.leBroker.text(): ok = False QMessageBox.warning(self, "MQTT details incomplete", "Input broker hostname") if self.module_mode == 1 and len(self.leTemplate.text()) == 0: ok = False QMessageBox.warning(self, "Template string missing", "Input template string") if ok: backlog = [] if self.gbWifi.isChecked(): backlog.extend([ "ssid1 {}".format(self.leAP.text()), "password1 {}".format(self.leAPPwd.text()) ]) if self.gbRecWifi.isChecked(): backlog.extend(["ssid2 Recovery", "password2 a1b2c3d4"]) if self.gbMQTT.isChecked(): backlog.extend([ "mqtthost {}".format(self.leBroker.text()), "mqttport {}".format(self.sbPort.value()) ]) topic = self.leTopic.text() if topic and topic != "tasmota": backlog.append("topic {}".format(topic)) fulltopic = self.leFullTopic.text() if fulltopic and fulltopic != "%prefix%/%topic%/": backlog.append("fulltopic {}".format(fulltopic)) fname = self.leFriendlyName.text() if fname: backlog.append("friendlyname {}".format(fname)) mqttuser = self.leMQTTUser.text() if mqttuser: backlog.append("mqttuser {}".format(mqttuser)) mqttpassword = self.leMQTTPass.text() if mqttpassword: backlog.append("mqttpassword {}".format(mqttpassword)) if self.gbModule.isChecked(): if self.module_mode == 0: backlog.append("module {}".format( self.cbModule.currentData())) elif self.module_mode == 1: backlog.extend([ "template {}".format(self.leTemplate.text()), "module 0" ]) self.commands = "backlog {}\n".format(";".join(backlog)) self.done(QDialog.Accepted)
class bridgePanel(QMainWindow, QObject): start = pyqtSignal() stop = pyqtSignal() def __init__(self, app): super().__init__() self.__v2rayshellConfigFile = { "preferences": { "v2ray-core": "", "v2ray-coreFilePath": "", "connection": { "connect": "switch", "interval": 45, "timeout": 3, "enable": True, "trytimes": 3 } }, "configFiles": [{ "enable": True, "hostName": "", "configFileName": "" }] } self.bridgetreasureChest = bridgetreasureChest.bridgetreasureChest() self.app = app self.translate = QCoreApplication.translate self.__v2rayshellVersion = "20180204" self.__windowTitile = "V2Ray-shell" + " " + self.__v2rayshellVersion self.runv2raycore = False self.iconStart = QIcon() self.iconStop = QIcon() self.__iconSize = QSize(32, 32) self.iconStart.addPixmap(QPixmap(filePath + "/icons/start.png"), QIcon.Normal, QIcon.On) self.iconStop.addPixmap(QPixmap(filePath + "/icons/stop.png"), QIcon.Disabled, QIcon.On) self.currentRowRightClicked = False self.v2rayshellTrayIcon = QSystemTrayIcon() self.v2rayshellTrayIcon.setIcon(self.iconStart) self.v2rayshellTrayIcon.show() self.radioButtonGroup = QButtonGroup() self.setV2RayshellLanguage() self.trytimes = self.bridgetreasureChest.getConnectiontrytimes() self.interval = self.bridgetreasureChest.getConnectioninterval() self.proxyTryConnect = proxyTryconnect() if v2rayshellDebug: self.proxyTryConnect.setresetTime(6, 3) else: self.proxyTryConnect.setresetTime(self.interval, self.trytimes) self.labelBridge = (self.translate("bridgePanel", "Start/Stop"), self.translate("bridgePanel", "Host Name"), self.translate("bridgePanel", "Config Name"), self.translate("bridgePanel", "Proxy"), self.translate("bridgePanel", "Time Lag")) self.createBridgePanel() def createBridgePanel(self): self.setWindowTitle(self.__windowTitile) self.setWindowIcon(self.iconStart) menubar = self.menuBar() self.statusBar() self.actionNewV2rayConfigFile = QAction( self.translate("bridgePanel", "Add V2Ray-core Config File"), self) self.actionNewV2rayConfigFile.setShortcut(QKeySequence.New) self.actionNewV2rayConfigFile.setStatusTip( self.translate("bridgePanel", "Add V2Ray-core Config File")) self.actionSaveV2rayshellConfigFile = QAction( self.translate("bridgePanel", "Save V2Ray-shell Config File"), self) self.actionSaveV2rayshellConfigFile.setShortcut(QKeySequence.Save) self.actionSaveV2rayshellConfigFile.setStatusTip( self.translate("bridgePanel", "Save V2Ray-shell Config File")) self.actionReloadV2rayshellConfigFile = QAction( self.translate("bridgePanel", "Open V2Ray-shell Config File"), self) self.actionReloadV2rayshellConfigFile.setShortcut(QKeySequence.Open) self.actionReloadV2rayshellConfigFile.setStatusTip( self.translate("bridgePanel", "Open V2Ray-shell Config File")) self.actionQuitV2rayshellPanel = QAction( self.translate("bridgePanel", "Quit"), self) if sys.platform.startswith('win'): self.actionQuitV2rayshellPanel.setShortcut("Ctrl+Q") else: self.actionQuitV2rayshellPanel.setShortcut(QKeySequence.Quit) self.actionQuitV2rayshellPanel.setStatusTip( self.translate("bridgePanel", "Quit V2Ray-shell")) fileMenu = menubar.addMenu(self.translate("bridgePanel", "&File")) fileMenu.addAction(self.actionNewV2rayConfigFile) fileMenu.addSeparator() fileMenu.addAction(self.actionReloadV2rayshellConfigFile) fileMenu.addAction(self.actionSaveV2rayshellConfigFile) fileMenu.addSeparator() fileMenu.addAction(self.actionQuitV2rayshellPanel) self.texteditBridge = QTextEdit(self) self.texteditBridge.setReadOnly(True) self.tableWidgetBridge = QTableWidget() self.tableWidgetBridge.setRowCount(0) self.tableWidgetBridge.setColumnCount(5) self.tableWidgetBridge.setHorizontalHeaderLabels(self.labelBridge) self.tableWidgetBridge.setSelectionMode( QAbstractItemView.SingleSelection) self.tableWidgetBridge.setSelectionBehavior( QAbstractItemView.SelectRows) self.tableWidgetBridge.setEditTriggers( QAbstractItemView.NoEditTriggers) #self.tableWidgetBridge.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) self.tableWidgetBridge.setContextMenuPolicy(Qt.CustomContextMenu) self.popMenu = popMenu = QMenu(self.tableWidgetBridge) self.actionpopMenuAddV2rayConfigFile = QAction( self.translate("bridgePanel", "Add V2Ray Config File"), self) self.actionpopMenuAddV2rayConfigFile.setShortcut("Ctrl+n") self.actionpopMenuEditV2rayConfigFile = QAction( self.translate("bridgePanel", "Edit V2Ray Config File"), self) self.actionpopMenuProxyCheckTimeLag = QAction( self.translate("bridgePanel", "Proxy Time Lag Check..."), self) self.actionpopMenuDeleteRow = QAction( self.translate("bridgePanel", "Delete"), self) popMenu.addAction(self.actionpopMenuAddV2rayConfigFile) popMenu.addAction(self.actionpopMenuEditV2rayConfigFile) popMenu.addAction(self.actionpopMenuProxyCheckTimeLag) popMenu.addAction(self.actionpopMenuDeleteRow) self.actionopenV2rayshellPreferencesPanel = QAction( self.translate("bridgePanel", "preferences"), self) self.actionopenV2rayshellPreferencesPanel.setStatusTip( self.translate("bridgePanel", "Setting V2Ray-shell")) optionMenu = menubar.addMenu(self.translate("bridgePanel", "&options")) optionMenu.addAction(self.actionpopMenuProxyCheckTimeLag) optionMenu.addAction(self.actionopenV2rayshellPreferencesPanel) helpMenu = menubar.addMenu(self.translate("bridgePanel", "&help")) self.actioncheckv2raycoreupdate = QAction( self.translate("bridgePanel", "check V2Ray-core update"), self) self.actionv2rayshellBugreport = QAction( self.translate("bridgePanel", "Bug Report"), self) self.actionaboutv2rayshell = QAction( self.translate("bridgePanel", "About"), self) helpMenu.addAction(self.actioncheckv2raycoreupdate) helpMenu.addAction(self.actionv2rayshellBugreport) helpMenu.addAction(self.actionaboutv2rayshell) toolBar = QToolBar() self.actionV2rayStart = QAction(self.translate("bridgePanel", "Start")) self.actionV2rayStart.setIcon(self.style().standardIcon( getattr(QStyle, "SP_MediaPlay"))) self.actionV2rayStop = QAction(self.translate("bridgePanel", "Stop")) self.actionV2rayStop.setIcon(self.style().standardIcon( getattr(QStyle, "SP_MediaStop"))) toolBar.addAction(self.actionV2rayStart) toolBar.addAction(self.actionV2rayStop) self.addToolBar(toolBar) self.trayIconMenu = QMenu() self.v2rayshellTrayIcon.setContextMenu(self.trayIconMenu) self.trayIconMenushowhidePanel = QAction( self.translate("bridgePanel", "Show/Hide")) self.trayIconMenuclosePanel = QAction( self.translate("bridgePanel", "Quit")) self.trayIconMenu.addAction(self.trayIconMenushowhidePanel) self.trayIconMenu.addSeparator() self.trayIconMenu.addAction(self.trayIconMenuclosePanel) self.splitterBridge = QSplitter(Qt.Vertical) self.splitterBridge.addWidget(self.tableWidgetBridge) self.splitterBridge.addWidget(self.texteditBridge) self.setCentralWidget(self.splitterBridge) self.createBridgePanelSignals() self.onloadV2rayshellConfigFile(init=True) self.onv2raycoreStart() self.autocheckv2raycoreUpdate() def createBridgePanelSignals(self): self.actionNewV2rayConfigFile.triggered.connect( self.tableWidgetBridgeAddNewV2rayConfigFile) self.actionReloadV2rayshellConfigFile.triggered.connect( self.onloadV2rayshellConfigFile) self.actionSaveV2rayshellConfigFile.triggered.connect( self.onsaveV2rayshellConfigFile) self.actionopenV2rayshellPreferencesPanel.triggered.connect( self.createBridgepreferencesPanel) self.actionpopMenuAddV2rayConfigFile.triggered.connect( self.tableWidgetBridgeAddNewV2rayConfigFile) self.actionpopMenuEditV2rayConfigFile.triggered.connect( self.oncreatenauticalChartPanel) self.actionpopMenuDeleteRow.triggered.connect( self.tableWidgetBridgeDelete) self.actionpopMenuProxyCheckTimeLag.triggered.connect( self.onproxyserverTimeLagTest) self.actioncheckv2raycoreupdate.triggered.connect( self.onopenv2rayupdatePanel) self.actionv2rayshellBugreport.triggered.connect(self.bugReportPanel) self.actionQuitV2rayshellPanel.triggered.connect(self.close) self.actionV2rayStart.triggered.connect(self.onv2raycoreStart) self.actionV2rayStop.triggered.connect(self.onv2raycoreStop) self.actionaboutv2rayshell.triggered.connect(self.about) self.radioButtonGroup.buttonClicked.connect(self.onradioButtonClicked) self.tableWidgetBridge.cellDoubleClicked.connect( self.ontableWidgetBridgecellDoubleClicked) self.tableWidgetBridge.customContextMenuRequested.connect( self.ontableWidgetBridgeRightClicked) self.v2rayshellTrayIcon.activated.connect(self.restorebridgePanel) self.trayIconMenushowhidePanel.triggered.connect( self.onsystemTrayIconMenushowhidebridgePanel) self.trayIconMenuclosePanel.triggered.connect(self.close) self.proxyTryConnect.reconnectproxy.connect(self.swapNextConfigFile) self.start.connect(self.onupdateinstallFinishedstartNewV2raycore) self.stop.connect(self.onv2raycoreStop) def setV2RayshellLanguage(self): self.trans = QTranslator() language = self.bridgetreasureChest.getLanguage() allLanguages = self.bridgetreasureChest.getAllLanguage() if language and allLanguages: if language in allLanguages: self.trans.load(allLanguages[language]) self.app.installTranslator(self.trans) def autocheckv2raycoreUpdate(self): self.v2rayshellautoUpdate = updatePanel.updateV2ray() self.bridgeSingal = (self.start, self.stop) self.trycheckUpdate = QTimer() self.trycheckUpdate.timeout.connect( lambda: self.v2rayshellautoUpdate.enableUpdateSchedule( self.bridgetreasureChest, self.bridgeSingal)) self.trycheckUpdate.start(1000 * 60 * 60 * 4) ### Check every four hours self.trycheckUpdate.singleShot( ### Check when the script is started 1000 * 15, ### fifty seconds lambda: self.v2rayshellautoUpdate.enableUpdateSchedule( self.bridgetreasureChest, self.bridgeSingal)) def event(self, event): if (event.type() == QEvent.WindowStateChange and self.isMinimized()): self.setWindowFlags(self.windowFlags() & ~Qt.Tool) self.v2rayshellTrayIcon.show() return True else: return super(bridgePanel, self).event(event) def onsystemTrayIconMenushowhidebridgePanel(self): if self.isHidden(): self.showNormal() elif self.isVisible(): self.hide() def restorebridgePanel(self, reason): if reason == QSystemTrayIcon.Trigger: if self.isVisible(): self.hide() elif self.isHidden(): self.showNormal() def close(self): super(bridgePanel, self).close() self.v2rayshellTrayIcon.hide() self.onv2raycoreStop() def closeEvent(self, event): self.close() event.accept() sys.exit(self.app.exec_()) def onv2raycoreStop(self): if (self.runv2raycore): self.runv2raycore.stop.emit() try: ### force stop checking proxy time lag del self.autoCheckTimer except Exception: pass def onupdateinstallFinishedstartNewV2raycore(self): self.onloadV2rayshellConfigFile(init=True) self.onv2raycoreStart() def onv2raycoreStart(self): currentActiveRow = False rowCount = self.tableWidgetBridge.rowCount() for i in range(rowCount): currentActiveRow = self.tableWidgetBridge.cellWidget(i, 0) if currentActiveRow.isChecked(): self.texteditBridge.clear() option = self.tableWidgetBridge.item(i, 2) if option: option = '-config="{}" -format=json'.format(option.text()) else: option = "" filePath = self.bridgetreasureChest.getV2raycoreFilePath() if (filePath == False or filePath == ""): filePath = "v2ray" self.runv2raycore = runV2raycore.runV2raycore( outputTextEdit=self.texteditBridge, v2rayPath=filePath, v2rayOption=option, bridgetreasureChest=self.bridgetreasureChest) self.runv2raycore.start.emit() self.autocheckProxy(i) break else: del currentActiveRow def autocheckProxy(self, row): ### TODO """ Frequent access to the server may cause suspicion of DDOS attacks, which may put the VPS server at risk. """ enableAutoCheck = self.bridgetreasureChest.getConnectionEnable() if (enableAutoCheck): self.proxyStatus = proxyTest.proxyStatus() self.autoCheckTimer = QTimer() invervalTime = self.bridgetreasureChest.getConnectioninterval() timeout = self.bridgetreasureChest.getConnectiontimeout() proxyAddress = self.getProxyAddressFromTableWidget(row) if proxyAddress: self.autoCheckTimer.timeout.connect( lambda: self.startCheckProxy(timeout=timeout, proxyAddress=proxyAddress, row=row, proxyStatus=self.proxyStatus)) self.bridgetreasureChest.setProxy(proxyAddress) if v2rayshellDebug: self.autoCheckTimer.start(6000) else: self.autoCheckTimer.start(1000 * invervalTime) self.autoCheckTimer.singleShot( 100, lambda: self.startCheckProxy(timeout=timeout, proxyAddress=proxyAddress, row=row, proxyStatus=self.proxyStatus)) def setTableWidgetTimelag(self, row, proxyStatus): newlabelTimelag = self.setlabelTimeLagColor(proxyStatus) oldlabelTimelag = self.tableWidgetBridge.cellWidget(row, 4) del oldlabelTimelag self.tableWidgetBridge.setCellWidget(row, 4, newlabelTimelag) self.tableWidgetBridge.resizeColumnsToContents() def startCheckProxy(self, timeout, proxyAddress, row, proxyStatus): if (proxyAddress): proxyStatus.clear() proxyStatus.signal.connect( lambda: self.setTableWidgetTimelag(row, proxyStatus)) self.proxy = proxyTest.proxyTest(proxyprotocol=proxyAddress[0], proxyhostname=proxyAddress[1], proxyhostport=int( proxyAddress[2]), getproxyStatus=proxyStatus, timeout=int(timeout)) def setlabelTimeLagColor(self, proxyStatus=False): labelTimeLag = QLabel() if (proxyStatus and proxyStatus.getProxyError() == False): labelFont = QFont() labelFont.setPointSize(12) labelFont.setBold(True) labelTimeLag.setFont(labelFont) forestGreen = "QLabel {color: rgb(34, 139, 34)}" darkOrange = "QLabel {color: rgb(255, 140, 0)}" red = "QLabel {color: rgb(194,24,7)}" if (proxyStatus.getElapsedTime() < 260): labelTimeLag.setStyleSheet(forestGreen) elif (proxyStatus.getElapsedTime() > 420): labelTimeLag.setStyleSheet(red) else: labelTimeLag.setStyleSheet(darkOrange) labelTimeLag.setText("{} ms".format( str(proxyStatus.getElapsedTime()))) return labelTimeLag elif (proxyStatus and proxyStatus.getProxyError()): labelTimeLag.setText("{}:{}".format( proxyStatus.getProxyErrorString(), proxyStatus.getProxyErrorCode())) self.proxyTryConnect.trytimesDecrease() return labelTimeLag def swapNextConfigFile(self): self.onv2raycoreStop() try: self.trytimes = self.bridgetreasureChest.getConnectiontrytimes() self.interval = self.bridgetreasureChest.getConnectioninterval() self.proxyTryConnect.stopperiodicCheckProxyStatus() if v2rayshellDebug: self.proxyTryConnect.setresetTime(6, 3) else: self.proxyTryConnect.setresetTime(self.interval, self.trytimes) except Exception: self.proxyTryConnect.setresetTime(60, 3) if (self.bridgetreasureChest.connectionisSwitch()): ### swap next row's configFile buttons = self.radioButtonGroup.buttons() buttonsNumber = len(buttons) activeRow = False for i in range(buttonsNumber): if buttons[i].isChecked(): buttons[i].setChecked(False) if i == buttonsNumber - 1: buttons[0].setChecked(True) activeRow = 0 break else: buttons[i + 1].setChecked(True) activeRow = i + 1 break ### change the row icons for i in range(buttonsNumber): widget = self.tableWidgetBridge.cellWidget(i, 0) if (widget): widget.setIcon(self.iconStop) widget.setIconSize(self.__iconSize) if (widget.isChecked()): pass widget = self.tableWidgetBridge.cellWidget(activeRow, 0) if widget: widget.setIcon(self.iconStart) widget.setIconSize(self.__iconSize) self.onv2raycoreStart() def onopenv2rayupdatePanel(self): currentActiveRow = False rowCount = self.tableWidgetBridge.rowCount() currentRow = False for i in range(rowCount): currentActiveRow = self.tableWidgetBridge.cellWidget(i, 0) if currentActiveRow.isChecked(): currentRow = i break if (currentActiveRow and currentActiveRow.isChecked()): proxy = self.tableWidgetBridge.item(currentRow, 3) proxy = proxy.text().split(":") protocol = QNetworkProxy.Socks5Proxy if (proxy[0] == "socks"): protocol = QNetworkProxy.Socks5Proxy elif (proxy[0] == "http"): protocol = QNetworkProxy.HttpProxy hostName = proxy[1] hostPort = int(proxy[2]) v2rayAPI = updatePanel.v2rayAPI() self.createupdatePanel = updatePanel.v2rayUpdatePanel( v2rayapi=v2rayAPI, protocol=protocol, proxyhostName=hostName, port=hostPort, bridgetreasureChest=self.bridgetreasureChest) self.createupdatePanel.createPanel() self.createupdatePanel.setAttribute(Qt.WA_DeleteOnClose) self.createupdatePanel.setWindowIcon(self.iconStart) self.createupdatePanel.setWindowTitle( self.translate("bridgePanel", "Check V2Ray-core update")) self.createupdatePanel.resize(QSize(1024, 320)) self.createupdatePanel.move( QApplication.desktop().screen().rect().center() - self.createupdatePanel.rect().center()) self.createupdatePanel.show() self.createupdatePanel.exec_() else: self.noPoxyServerRunning() def ontableWidgetBridgeRightClicked(self, pos): index = self.tableWidgetBridge.indexAt(pos) clickedRow.rightClickedRow = index.row() clickedRow.mousePos = QCursor().pos() self.popMenu.move(QCursor().pos()) self.popMenu.show() def ontableWidgetBridgecellDoubleClicked(self, row, column): if (column == 1): hostName, ok = QInputDialog.getText( self, self.translate("bridgePanel", 'Host Name'), self.translate("bridgePanel", 'Enter Host Name:')) if (ok): self.tableWidgetBridge.setItem(row, column, QTableWidgetItem(str(hostName))) self.tableWidgetBridge.resizeColumnsToContents() elif (column == 2): fileNames = self.onopenV2rayConfigJSONFile() if (fileNames): for fileName in fileNames: self.tableWidgetBridge.setItem( row, column, QTableWidgetItem(str(fileName))) self.tableWidgetBridge.resizeColumnsToContents() elif (column == 3): self.onproxyserverTimeLagTest() elif (column == 4): self.onproxyserverTimeLagTest() def getProxyAddressFromTableWidget(self, row): proxy = self.tableWidgetBridge.item(row, 3) try: proxy = proxy.text().split(":") except Exception: return False if (proxy[0] == "socks"): proxy[0] = QNetworkProxy.Socks5Proxy elif (proxy[0] == "http"): proxy[0] = QNetworkProxy.HttpProxy if len(proxy) < 3: return False else: return proxy def onproxyserverTimeLagTest(self): proxyStatus = proxyTest.proxyStatus() """ right clicked mouse button pop a menu check proxy """ currentActiveRow = False rowCount = self.tableWidgetBridge.rowCount() currentRow = False for i in range(rowCount): currentActiveRow = self.tableWidgetBridge.cellWidget(i, 0) if currentActiveRow.isChecked(): currentRow = i break if (currentActiveRow and currentActiveRow.isChecked()): proxy = self.getProxyAddressFromTableWidget(currentRow) protocol = proxy[0] hostName = proxy[1] hostPort = int(proxy[2]) proxy = proxyTest.proxyTestPanel(proxyhostname=hostName, proxyhostport=hostPort, proxyprotocol=protocol, getproxyStatus=proxyStatus) proxy.createproxyTestPanel() proxy.setAttribute(Qt.WA_DeleteOnClose) proxy.setWindowTitle( self.translate("bridgePanel", "Proxy Time Lag Check")) proxy.setWindowIcon(self.iconStart) proxy.resize(QSize(600, 480)) proxy.move(QApplication.desktop().screen().rect().center() - proxy.rect().center()) proxy.show() proxy.exec_() else: self.noPoxyServerRunning() def noPoxyServerRunning(self): warningPanel = QDialog() warningPanel.setAttribute(Qt.WA_DeleteOnClose) warningPanel.setWindowTitle(self.translate("bridgePanel", "Warnnig...")) warningPanel.setWindowIcon(self.iconStop) labelMsg = QLabel( self.translate( "bridgePanel", "There no any server is running, \n[File]->[Add V2Ray-core Config File] (Ctrl+n) add a config.json." )) vbox = QVBoxLayout() vbox.addWidget(labelMsg) warningPanel.setLayout(vbox) warningPanel.move(QApplication.desktop().screen().rect().center() - warningPanel.rect().center()) warningPanel.open() warningPanel.exec_() def getProxyAddressFromJSONFile(self, filePath): from bridgehouse.editMap.port import treasureChest, openV2rayJSONFile tempTreasureChest = treasureChest.treasureChest() openV2rayJSONFile.openV2rayJSONFile( filePath, tempTreasureChest, disableLog=True).initboundJSONData() inbound = tempTreasureChest.getInbound() if (inbound): protocol = inbound["protocol"] ipAddress = inbound["listen"] port = inbound["port"] if (protocol == "socks" or protocol == "http"): return "{}:{}:{}".format(protocol, ipAddress, port) else: return False else: return False def onradioButtonClicked(self, e): rowCount = self.tableWidgetBridge.rowCount() #radioButtonClickedRow = 0 for i in range(rowCount): widget = self.tableWidgetBridge.cellWidget(i, 0) if (widget): widget.setIcon(self.iconStop) widget.setIconSize(self.__iconSize) if (widget.isChecked()): #radioButtonClickedRow = i pass e.setIcon(self.iconStart) e.setIconSize(self.__iconSize) def onloadV2rayshellConfigFile(self, init=False): """ when the script first start, and auto load v2ray-shell config file. """ if init: self.settingv2rayshelltableWidget() else: def openV2rayshellConfigFile(): options = QFileDialog.Options() filePath, _ = QFileDialog.getOpenFileName( self, self.translate("bridgePanel", "Open V2Ray-sehll Config File"), "", "V2Ray-shell config file (*.v2rayshell)", options=options) if (filePath): self.bridgetreasureChest.clear() self.tableWidgetBridge.setRowCount(0) self.bridgetreasureChest.inibridgeJSONData( v2rayshellConfigFileName=filePath) self.settingv2rayshelltableWidget() openV2rayshellConfigFile() def onopenV2rayConfigJSONFile(self): """ open a new v2ray config file to tabelWidget """ options = QFileDialog.Options() filePaths, _ = QFileDialog.getOpenFileNames( self, self.translate("bridgePanel", "Open V2Ray-core Config File"), "", """ V2Ray config file (*.json);; All File (*);; """, options=options) if (filePaths): return filePaths else: return False def createBridgepreferencesPanel(self): self.createpreferencesPanel = bridgePreference.bridgepreferencesPanel( self.bridgetreasureChest) self.createpreferencesPanel.setAttribute(Qt.WA_DeleteOnClose) self.createpreferencesPanel.createpreferencesPanel() self.createpreferencesPanel.setWindowIcon(self.iconStart) self.createpreferencesPanel.move( QApplication.desktop().screen().rect().center() - self.createpreferencesPanel.rect().center()) self.createpreferencesPanel.open() self.createpreferencesPanel.exec_() def settingv2rayshelltableWidget(self): v2rayConfigFiles = self.bridgetreasureChest.getV2raycoreconfigFiles() if v2rayConfigFiles == False: return v2rayConfigFilesNumber = len(v2rayConfigFiles) if (v2rayConfigFilesNumber > 0): self.tableWidgetBridge.setRowCount(0) for i in range(v2rayConfigFilesNumber): try: enable = bool(v2rayConfigFiles[i]["enable"]) hostName = str(v2rayConfigFiles[i]["hostName"]) configFileName = str(v2rayConfigFiles[i]["configFileName"]) except Exception: pass radioButtonStopStart = QRadioButton(self) radioButtonStopStart.setIcon( self.iconStop if not enable else self.iconStart) radioButtonStopStart.setChecked(True if enable else False) radioButtonStopStart.setIconSize(self.__iconSize) self.radioButtonGroup.addButton(radioButtonStopStart) self.tableWidgetBridge.setRowCount(i + 1) self.tableWidgetBridge.setCellWidget(i, 0, radioButtonStopStart) self.tableWidgetBridge.setItem(i, 1, QTableWidgetItem(hostName)) self.tableWidgetBridge.setItem( i, 2, QTableWidgetItem(configFileName)) self.tableWidgetBridge.setItem( i, 3, QTableWidgetItem( self.getProxyAddressFromJSONFile(configFileName))) self.tableWidgetBridge.resizeColumnsToContents() #self.tableWidgetBridge.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) def onsaveV2rayshellConfigFile(self): self.bridgetreasureChest.clearconfigFiles() rowCount = self.tableWidgetBridge.rowCount() for i in range(rowCount): enable = self.tableWidgetBridge.cellWidget(i, 0) if enable and enable.isChecked(): enable = True else: enable = False hostName = self.tableWidgetBridge.item(i, 1) if hostName: hostName = hostName.text() else: hostName = "" config = self.tableWidgetBridge.item(i, 2) if config: config = config.text() else: config = "" self.bridgetreasureChest.setV2raycoreconfigFiles( enable, hostName, configFileName=config) self.bridgetreasureChest.save.emit() def oncreatenauticalChartPanel(self): v2rayConfigFileName = self.tableWidgetBridge.item( clickedRow.rightClickedRow, 2) if (v2rayConfigFileName): nc = nauticalChartPanel.nauticalChartPanel( v2rayConfigFileName.text()) nc.setAttribute(Qt.WA_DeleteOnClose) nc.createPanel() nc.setWindowTitle( self.translate("bridgePanel", "V2Ray config file edit")) nc.setWindowIcon(self.iconStart) nc.setGeometry(0, 0, 1024, 768) ### move widget to center nc.move(QApplication.desktop().screen().rect().center() - nc.rect().center()) nc.show() nc.exec_() def tableWidgetBridgeAddNewV2rayConfigFile(self): configFileNames = self.onopenV2rayConfigJSONFile() if (configFileNames): for configFileName in configFileNames: rowCount = self.tableWidgetBridge.rowCount() radioButtonStopStart = QRadioButton(self) radioButtonStopStart.setIcon(self.iconStop) radioButtonStopStart.setIconSize(self.__iconSize) self.radioButtonGroup.addButton(radioButtonStopStart) self.tableWidgetBridge.setRowCount(rowCount + 1) self.tableWidgetBridge.setCellWidget(rowCount, 0, radioButtonStopStart) self.tableWidgetBridge.setItem(rowCount, 1, QTableWidgetItem("")) self.tableWidgetBridge.setItem( rowCount, 2, QTableWidgetItem(configFileName)) self.tableWidgetBridge.setItem( rowCount, 3, QTableWidgetItem( self.getProxyAddressFromJSONFile(configFileName))) self.tableWidgetBridge.resizeColumnsToContents() else: pass def tableWidgetBridgeDelete(self): self.tableWidgetBridge.removeRow(clickedRow.rightClickedRow) def validateV2rayJSONFile(self, JSONData): """ simply validate a V2Ray json file. """ try: JSONData["inbound"] JSONData["outbound"] except KeyError: return False else: return True def about(self): NineteenEightySeven = QLabel( self.translate( "bridgePanel", """Across the Great Wall, we can reach every corner in the world.""" )) ### Crossing the Great Wall to Join the World Timeless = QLabel( self.translate( "bridgePanel", """You weren't thinking about that when you were creating it.\nBecause if you did? You never would have gone through with it.""" )) DwayneRichardHipp = QLabel( self.translate( "bridgePanel", """May you do good and not evil.\nMay you find forgiveness for yourself and forgive others.\nMay you share freely, never taking more than you give.""" )) vbox = QVBoxLayout() vbox.addWidget(NineteenEightySeven) vbox.addWidget(Timeless) vbox.addWidget(DwayneRichardHipp) dialogAbout = QDialog() dialogAbout.setAttribute(Qt.WA_DeleteOnClose) dialogAbout.setWindowTitle( self.translate("bridgePanel", "About V2Ray-shell")) dialogAbout.setWindowIcon(self.iconStart) dialogAbout.move(QApplication.desktop().screen().rect().center() - dialogAbout.rect().center()) dialogAbout.setLayout(vbox) dialogAbout.open() dialogAbout.exec_() def bugReportPanel(self): self.bugReport = bugReport.bugReport() self.bugReport.setAttribute(Qt.WA_DeleteOnClose) self.bugReport.setWindowTitle( self.translate("bridgePanel", "Bug Report")) self.bugReport.setWindowIcon(self.iconStart) self.bugReport.createPanel() self.bugReport.show() self.bugReport.setGeometry(250, 150, 1024, 768)
class DMSUnitWgt(QWidget): unitTabDataWdg = None decorateTypeWgt: DMSDecorateTypeWgt = None decorateDataWgt: DMSDecorateDataWgt = None currentBuilding: DB_Building = None unitDict: dict = {} def __init__(self, parent=None): super(DMSUnitWgt, self).__init__(parent) self.initUI() self.initTrigger() def initUI(self): self.ui = Ui_UnitWgt() self.ui.setupUi(self) self.ui.verticalLayout.setContentsMargins(0, 0, 0, 0) self.setContentsMargins(0, 0, 0, 0) self.decorateTypeWgt = DMSDecorateTypeWgt(self) self.decorateDataWgt = DMSDecorateDataWgt(self) count = self.ui.verticalLayout.count() self.ui.verticalLayout.addWidget(self.decorateDataWgt) self.groupButton = QButtonGroup(self) def unitChanged(self): # self.decorateDataWgt. pass def initTrigger(self): self.ui.pBtnAddUnit.clicked.connect(self.addUnit) self.ui.pBtnDleleteUnit.clicked.connect(self.deleteUnit) self.groupButton.buttonClicked.connect(self.unitChanged) def setCurrentBuilding(self, building_id): if self.currentBuilding and self.currentBuilding.id == building_id: return self.currentBuilding = None building: DB_Building = dmsDatabase().getRecordById( DB_Building, building_id) if building is None: self.updateUiEnabled() return self.currentBuilding = building self.clearUnit() self.loadUnit() self.updateUiEnabled() def getCurrentUnit(self): pass def addUnit(self): unit = newUnit(self.currentBuilding) unit_tool_btn = self.createToolButton(unit) unit_tool_btn.setChecked(True) def deleteUnit(self): _id = self.groupButton.checkedId() _button = self.groupButton.checkedButton() self.groupButton.removeButton(_button) delete(_button) customDeleteRecord(DB_Building_Unit, _id) self.updateUiEnabled() def createToolButton(self, business_unit) -> QToolButton: if business_unit is None: return unit_tool_btn = QToolButton() unit_tool_btn.setText(business_unit.name) unit_tool_btn.setCheckable(True) count = self.ui.horizontalLayout.count() self.ui.horizontalLayout.insertWidget(count - 3, unit_tool_btn) self.unitDict[business_unit.id] = unit_tool_btn self.groupButton.addButton(unit_tool_btn, business_unit.id) return unit_tool_btn def loadUnit(self): if self.currentBuilding is None: return unit_list = dmsDatabase().getTableList( DB_Building_Unit, "building_id = " + str(self.currentBuilding.id)) if len(unit_list) == 0: return first_item: QToolButton = None for item in unit_list: unit_tool_btn = self.createToolButton(item) if first_item is None: first_item = unit_tool_btn first_item.setChecked(True) def clearUnit(self): if len(self.unitDict) == 0: return tool_btn_list = self.unitDict.values() for var in self.groupButton.buttons(): self.groupButton.removeButton(var) for item in tool_btn_list: self.ui.horizontalLayout.removeWidget(item) delete(item) self.unitDict.clear() def updateUnitDate(self, currentBuildingID, previousBuildingID=None): """ 槽函数 :param currentBuildingID: :param previousBuildingID: :return: """ pass # # Todo 待梳理嵌套关系 # print(currentBuildingID, previousBuildingID) # dateTableWidget = self.unitTabWdg.currentWidget() # dateTableWidget = DMSDecorateDataWgt() # # decorateTaskList: List[DB_Decorate_Type] = dmsProject().getTableList(DB_Decorate_Type, filter_str=currentBuildingID).orderBy( # # DB_Decorate_Type.order) # decorateTaskList: List[DB_Decorate_Type] = dmsDatabase().getTableList(DB_Decorate_Type) # tableHeaderList = [task.name for task in decorateTaskList] # dateTableWidget.setHorizontalHeaderLabels(tableHeaderList) def updateUiEnabled(self): enabled = False if len(self.unitDict) == 0: enabled = False else: enabled = True self.ui.pBtnDleleteUnit.setEnabled(enabled)
class ApplicationPage(QWidget): """ The GUI for the application page of a project. """ # The page's label. label = "Application Source" # Emitted when the user changes the PyQt version. pyqt_version_changed = pyqtSignal(bool) @property def project(self): """ The project property getter. """ return self._project @project.setter def project(self, value): """ The project property setter. """ if self._project != value: self._project = value self._script_edit.set_project(value) self._package_edit.set_project(value) self._update_page() def __init__(self): """ Initialise the page. """ super().__init__() self._project = None # Create the page's GUI. layout = QGridLayout() form = BetterForm() self._name_edit = QLineEdit( placeholderText="Application name", whatsThis="The name of the application. It will default to " "the base name of the application script without any " "extension.", textEdited=self._name_changed) form.addRow("Name", self._name_edit) self._script_edit = FilenameEditor("Application Script", placeholderText="Application script", whatsThis="The name of the application's optional main script " "file.", textEdited=self._script_changed) form.addRow("Main script file", self._script_edit) self._entry_point_edit = QLineEdit( placeholderText="Entry point in application package", whatsThis="The name of the optional entry point in the " "application's package.", textEdited=self._entry_point_changed) form.addRow("Entry point", self._entry_point_edit) self._sys_path_edit = QLineEdit( placeholderText="Additional sys.path directories", whatsThis="A space separated list of additional directories, " "ZIP files and eggs to add to <tt>sys.path</tt>. Only " "set this if you want to allow external packages to " "be imported.", textEdited=self._sys_path_changed) form.addRow("sys.path", self._sys_path_edit) layout.addLayout(form, 0, 0) options_layout = QVBoxLayout() pyqt_versions_layout = QHBoxLayout() self._pyqt_versions_bg = QButtonGroup() for version in ('PyQt5', 'PyQt4'): rb = QRadioButton(version, whatsThis="Click here if it is a {0} application.".format( version)) pyqt_versions_layout.addWidget(rb) self._pyqt_versions_bg.addButton(rb) options_layout.addLayout(pyqt_versions_layout) self._pyqt_versions_bg.buttonToggled.connect( self._pyqt_version_changed) self._console_edit = QCheckBox("Use console (Windows)", whatsThis="Enable console output for Windows applications. " "Console output will be enabled automatically if no " "graphical PyQt modules are used.", stateChanged=self._console_changed) options_layout.addWidget(self._console_edit) self._bundle_edit = QCheckBox("Application bundle (OS X)", whatsThis="Build an application bundle on OS X. If it is not " "checked then the application will be built as a " "simple executable.", stateChanged=self._bundle_changed) options_layout.addWidget(self._bundle_edit) options_layout.addStretch() layout.addLayout(options_layout, 0, 1) self._package_edit = _ApplicationPackageEditor() self._package_edit.package_changed.connect(self._package_changed) package_edit_gb = QGroupBox(self._package_edit.title) package_edit_gb.setLayout(self._package_edit) layout.addWidget(package_edit_gb, 1, 0, 1, 2) layout.setRowStretch(1, 1) self.setLayout(layout) def _update_page(self): """ Update the page using the current project. """ project = self.project self._name_edit.setText(project.application_name) self._script_edit.setText(project.application_script) self._entry_point_edit.setText(project.application_entry_point) self._sys_path_edit.setText(project.sys_path) self._package_edit.configure(project.application_package, project) blocked = self._pyqt_versions_bg.blockSignals(True) for rb in self._pyqt_versions_bg.buttons(): if rb.text() == 'PyQt5': rb.setChecked(project.application_is_pyqt5) else: rb.setChecked(not project.application_is_pyqt5) self._pyqt_versions_bg.blockSignals(blocked) blocked = self._console_edit.blockSignals(True) self._console_edit.setCheckState( Qt.Checked if project.application_is_console else Qt.Unchecked) self._console_edit.blockSignals(blocked) blocked = self._bundle_edit.blockSignals(True) self._bundle_edit.setCheckState( Qt.Checked if project.application_is_bundle else Qt.Unchecked) self._bundle_edit.blockSignals(blocked) def _pyqt_version_changed(self, button, checked): """ Invoked when the user changes the PyQt version number. """ if button.text() == 'PyQt5': self.project.application_is_pyqt5 = checked self.project.modified = True self.pyqt_version_changed.emit(checked) def _console_changed(self, state): """ Invoked when the user changes the console state. """ self.project.application_is_console = (state == Qt.Checked) self.project.modified = True def _bundle_changed(self, state): """ Invoked when the user changes the bundle state. """ self.project.application_is_bundle = (state == Qt.Checked) self.project.modified = True def _name_changed(self, value): """ Invoked when the user edits the application name. """ self.project.application_name = value self.project.modified = True def _script_changed(self, value): """ Invoked when the user edits the application script name. """ self.project.application_script = value self.project.modified = True def _entry_point_changed(self, value): """ Invoked when the user edits the entry point. """ self.project.application_entry_point = value self.project.modified = True def _sys_path_changed(self, value): """ Invoked when the user edits the sys.path directories. """ self.project.sys_path = value.strip() self.project.modified = True def _package_changed(self): """ Invoked when the user edits the application package. """ self.project.modified = True