def __init__(self, display, parent=None): super(uiSearch, self).__init__(parent) self.openResults = tfmlib.openResults() self.mkShortcut = tfmlib.shortcutFunc() self.escPath = tfmlib.escapeFunc() # self.mkresdir() # Screen object then used to read monitor size self.screen = display self.txtSearch = QLineEdit(self) self.txtSearch.setToolTip('Seperate your tags by spaces or commas.') btnSearch = QPushButton('Search',self) btnSearch.setToolTip('Search by tags.') layout = QVBoxLayout() layout.addWidget(self.txtSearch) layout.addWidget(btnSearch) self.setLayout(layout) self.setWindowTitle('Search') self.setGeom(300, 75) btnSearch.clicked.connect(self.search)
def __init__(self): super(TransformationHistoryWidget, self).__init__() self.actionContainer = ButtonContainer() self.transformationModel = TransformationModel() self.transformationView = TransformationListView() self.transformationView.setRootIsDecorated(False) self.transformationView.setModel(self.transformationModel) self.transformationView.setAttribute(Qt.WA_MacShowFocusRect, False) self.transformationView.clicked.connect(self.clickedTransformation) self._transformCount = 0 layout = QVBoxLayout() layout.setSpacing(0) layout.setAlignment(Qt.AlignTop) layout.addWidget(self.transformationView) layout.addWidget(self.actionContainer) self.setLayout(layout) removeButton = QPushButton() removeButton.setIcon(QIcon(AppVars.imagePath() + "RemoveButton.png")) removeButton.clicked.connect(self.removeButtonClicked) removeButton.setToolTip("Remove the last transformation") self.actionContainer.addButton(removeButton)
def __init__(self): generic.GenericGui.__init__(self) window = QWidget() window.setWindowTitle('quichem-pyside') self.compiler_view = QListWidget() self.compiler_view.currentRowChanged.connect(self.show_source) self.stacked_widget = QStackedWidget() self.stacked_widget.setFrameStyle(QFrame.StyledPanel | QFrame.Raised) self.edit = QLineEdit() self.edit.setPlaceholderText('Type quichem input...') self.edit.textChanged.connect(self.change_value) self.view = QWebView() self.view.page().mainFrame().setScrollBarPolicy(Qt.Vertical, Qt.ScrollBarAlwaysOff) self.view.page().action(QWebPage.Reload).setVisible(False) self.view.setMaximumHeight(0) self.view.setUrl('qrc:/web/page.html') self.view.setZoomFactor(2) self.view.page().mainFrame().contentsSizeChanged.connect( self._resize_view) # For debugging JS: ## from PySide.QtWebKit import QWebSettings ## QWebSettings.globalSettings().setAttribute( ## QWebSettings.DeveloperExtrasEnabled, True) button_image = QPushButton('Copy as Image') button_image.clicked.connect(self.set_clipboard_image) button_image.setToolTip('Then paste into any graphics program') button_word = QPushButton('Copy as MS Word Equation') button_word.clicked.connect(self.set_clipboard_word) button_html = QPushButton('Copy as Formatted Text') button_html.clicked.connect(self.set_clipboard_html) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) button_layout = QHBoxLayout() button_layout.addStretch() button_layout.addWidget(button_image) button_layout.addWidget(button_word) button_layout.addWidget(button_html) source_layout = QHBoxLayout() source_layout.addWidget(self.compiler_view) source_layout.addWidget(self.stacked_widget, 1) QVBoxLayout(window) window.layout().addWidget(self.edit) window.layout().addWidget(self.view) window.layout().addLayout(button_layout) window.layout().addWidget(line) window.layout().addLayout(source_layout, 1) window.show() window.resize(window.minimumWidth(), window.height()) # To prevent garbage collection of internal Qt object. self._window = window
def __add_button(self, object_name, icon_path, func, tooltip): """ Add simple button to UI """ button = QPushButton() button.setObjectName(object_name) button.setIcon(QIcon(QPixmap(icon_path))) button.setFixedSize(QSize(self.BUTTON_SIZE, self.BUTTON_SIZE)) button.setIconSize(QSize(self.BUTTON_SIZE, self.BUTTON_SIZE)) button.clicked.connect(func) button.setToolTip(tooltip) self.layout.addWidget(button) self.buttons[object_name] = button
class ExampleDialog( QDialog ): def __init__( self, parent ): QDialog.__init__( self, parent ) self.setGeometry( 100, 100, 200, 100 ) self.setWindowTitle( "Hello World" ) self.setToolTip( "This is a <b>QWidget</b> widget" ) self.btn = QPushButton( "Log Text", self ) self.btn.setToolTip( "This is a <b>QPushButton</b> widget" ) self.btn.resize( self.btn.sizeHint() ) self.btn.clicked.connect( self.logText ) self.lineedit = QLineEdit( "Hello World", self ) self.lineedit.setToolTip( "Type Something" ) layout = QVBoxLayout( self ) layout.addWidget( self.lineedit ) layout.addWidget( self.btn ) def logText( self ): Application.LogMessage( self.lineedit.text() )
def initUI(self): grp = QGroupBox('Anim Munge') grplay = QGridLayout() self.bf1mode = QCheckBox() grplay.addWidget(QLabel('<b>SWBF1</b>'), 0, 1) grplay.addWidget(self.bf1mode, 0, 2) grplay.addWidget(QLabel('<b>Input</b>'), 1, 1) grplay.addWidget(QLabel('<b>Output</b>'), 1, 3) self.infiles = QListWidget() self.infiles.setMinimumWidth(150) self.infiles.addItems([os.path.basename(item) for item in self.files]) grplay.addWidget(self.infiles, 2, 1, 1, 2) self.outfiles = QListWidget() self.outfiles.setMinimumWidth(150) grplay.addWidget(self.outfiles, 2, 3, 1, 2) self.add_params = QLineEdit() self.add_params.setText('Additional Params') self.add_params.setToolTip('<b>Additional Munge Parameters.</b> Like scale 1.5') grplay.addWidget(self.add_params, 0, 3, 1, 2) self.statlabel = QLabel('<b>AnimMunger</b>') grplay.addWidget(self.statlabel, 4, 1, 1, 1) self.animname = QLineEdit() self.animname.setText('AnimName') self.animname.setToolTip('<b>Animation Name.</b> Name of the final animation files. IE: name.zafbin, name.zaabin, name.anims.') grplay.addWidget(self.animname, 3, 1) self.type_box = QComboBox() self.type_box.addItems(self.types) self.type_box.setToolTip('<b>Munge Mode.</b> This switches munge parameters.') grplay.addWidget(QLabel('<b>Munge Mode:</b>'), 3, 2) grplay.addWidget(self.type_box, 3, 3, 1, 2) munge_btn = QPushButton('Munge') munge_btn.clicked.connect(self.munge) munge_btn.setToolTip('<b>Munge.</b> Munges the input files with the selected mode.') grplay.addWidget(munge_btn, 4, 2) save_out = QPushButton('Save') save_out.clicked.connect(self.save) save_out.setToolTip('<b>Save.</b> Saves the output files.') grplay.addWidget(save_out, 4, 3) cancel_btn = QPushButton('Cancel') cancel_btn.clicked.connect(self.cancel) cancel_btn.setToolTip('<b>Cancel.</b> Closes the dialog and removes all temporary files.') grplay.addWidget(cancel_btn, 4, 4) grp.setLayout(grplay) mainlay = QVBoxLayout() mainlay.addWidget(grp) self.setLayout(mainlay) self.setGeometry(340, 340, 320, 300) self.setWindowTitle('MSH Suite - Animation Munge') self.show()
def initUI(self): open_msh_btn = QPushButton('Open .MSH...') open_msh_btn.clicked.connect(self.load_msh) open_msh_btn.setToolTip('<b>Loads a .MSH file</b> for editing.') dump_msh_btn = QPushButton('Dump .MSH...') dump_msh_btn.clicked.connect(self.dump_msh) dump_msh_btn.setToolTip('<b>Dumps .MSH file information</b> into a text file.') munge_anim_btn = QPushButton('Munge Animation') munge_anim_btn.clicked.connect(self.munge_anim) munge_anim_btn.setToolTip('<b>Launches the AnimMunger.</b>') buttonslay = QGridLayout() buttonslay.addWidget(open_msh_btn, 1, 1) buttonslay.addWidget(dump_msh_btn, 1, 3) buttonslay.addWidget(munge_anim_btn, 3, 1) frame = QFrame() frame.setLayout(buttonslay) self.setCentralWidget(frame) self.setGeometry(200, 100, WIDTH_LAUNCH, HEIGHT_LAUNCH) self.setWindowTitle('MSH Suite') self.show()
class CC_window(QWidget): def __init__(self): super(CC_window, self).__init__() self.version = '0.2' glo = QVBoxLayout(self) self.Runningo = None self.Looping = None self.P = CC_thread() if name == 'nt': ficon = r_path('images\\favicon.png') licon = r_path('images\\logo.png') else: ficon = r_path('images/favicon.png') licon = r_path('images/logo.png') self.tf = QFont("", 13, QFont.Bold) self.sf = QFont("", 10, QFont.Bold) self.SelfIinit(QIcon(ficon)) self.center() self.a_btn(licon, glo) self.ss_btns(glo) self.i_list(glo) self.cl_btn(glo) self.l_btns(glo) self.f_btns(glo) self.ds_bar(glo) self.setLayout(glo) self.activateWindow() self.show() def SelfIinit(self, icon): self.setWindowTitle('chrome-cut ' + self.version) self.setGeometry(300, 300, 200, 150) self.setMinimumWidth(600) self.setMaximumWidth(600) self.setMinimumHeight(500) self.setMaximumHeight(500) # Setting Icon self.setWindowIcon(icon) QToolTip.setFont(self.sf) def msgApp(self, title, msg): uinfo = QMessageBox.question(self, title, msg, QMessageBox.Yes | QMessageBox.No) if uinfo == QMessageBox.Yes: return 'y' if uinfo == QMessageBox.No: return 'n' def closeEvent(self, event=None): if self.P.isRunning(): response = self.msgApp("Making sure", "Sure, you want to exit while looping ?") if response == 'y': if event is not None: event.accept() self.P.stop() exit(0) else: if event is not None: event.ignore() else: if event is not None: event.accept() exit(0) def center(self): qrect = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qrect.moveCenter(cp) self.move(qrect.topLeft()) def a_btn(self, icon, glo): def show_about(): Amsg = "<center>All credit reserved to the author of chrome-cut " Amsg += " version " + self.version Amsg += ", This work is a free, open-source project licensed " Amsg += " under Mozilla Public License version 2.0 . <br><br>" Amsg += " visit us for more infos and how-tos :<br> " Amsg += "<b><a href='https://github.io/mrf345/chrome-cut'> " Amsg += "https://github.io/mrf345/chrome-cut </a> </b></center>" Amsgb = "About chrome-cut" return QMessageBox.about(self, Amsgb, Amsg) self.abutton = QPushButton('', self) self.abutton.setIcon(QPixmap(icon)) self.abutton.setIconSize(QSize(500, 100)) self.abutton.setToolTip('About chrome-cut') self.abutton.clicked.connect(show_about) glo.addWidget(self.abutton) def ss_btns(self, glo): self.lebutton = QPushButton('Scan IP address', self) self.lebutton.setToolTip( 'Insert and check if a specific IP is a valid chrome cast') self.lebutton.setFont(self.tf) self.lebutton.clicked.connect(self.sip_input) glo.addWidget(self.lebutton) def sip_input(self): self.lebutton.setEnabled(False) self.s_bar.setStyleSheet(self.s_norm) self.s_bar.showMessage('> Checking out the IP ..') msg = "<center>Enter suspected IP to check : <br><i><u>Usually it is " msg += "on 192.168.what_have_you.188</i></center>" text, okPressed = QInputDialog.getText(self, "Scan IP", msg) if okPressed and text != '': self.setCursor(Qt.BusyCursor) ch = is_ccast(text) if ch: self.il_add([text]) self.unsetCursor() self.lebutton.setEnabled(True) return True else: self.s_bar.setStyleSheet(self.s_error) self.s_bar.showMessage( '! Error: inserted IP is not chrome cast device') self.unsetCursor() self.lebutton.setEnabled(True) return True self.s_bar.clearMessage() self.lebutton.setEnabled(True) return True def i_list(self, glo): self.ci_list = QListWidget() self.ci_list.setToolTip("List of discovered devices") self.ci_list.setEnabled(False) self.setFont(self.sf) glo.addWidget(self.ci_list) def cl_btn(self, glo): self.cle_btn = QPushButton('Clear devices list') self.cle_btn.setToolTip("Remove all devices from the list") self.cle_btn.setFont(self.sf) self.cle_btn.setEnabled(False) self.cle_btn.clicked.connect(self.il_add) glo.addWidget(self.cle_btn) def l_btns(self, glo): hlayout = QHBoxLayout() self.llo = QCheckBox("Looping") self.llo.setToolTip( 'Automate repeating the smae command on the smae device selected ') self.llo.setEnabled(False) self.nlo = QLineEdit() self.nlo.setPlaceholderText("duration in seconds. Default is 10") self.nlo.setEnabled(False) self.nlo.setToolTip("Duration of sleep after each loop") self.lbtn = QPushButton('Stop') self.lbtn.setEnabled(False) self.lbtn.setFont(self.tf) self.llo.setFont(self.sf) self.lbtn.setToolTip("stop on-going command or loop") self.llo.toggled.connect(self.loped) self.lbtn.clicked.connect(partial(self.inloop_state, out=True)) hlayout.addWidget(self.llo) hlayout.addWidget(self.nlo) hlayout.addWidget(self.lbtn) glo.addLayout(hlayout) def loped(self): if self.Looping: self.Looping = None self.llo.setChecked(False) self.nlo.setEnabled(False) else: self.Looping = True self.llo.setChecked(True) self.nlo.setEnabled(True) return True def f_btns(self, glo): hlayout = QHBoxLayout() self.ksbutton = QPushButton('Kill stream', self) self.ksbutton.setToolTip('Kill whetever been streamed') self.ksbutton.setFont(self.tf) self.ksbutton.clicked.connect(self.k_act) self.sbutton = QPushButton('Stream', self) self.sbutton.setFont(self.tf) self.sbutton.setToolTip('Stream a youtube video') self.fbutton = QPushButton('Factory reset', self) self.fbutton.setFont(self.tf) self.fbutton.setToolTip('Factory reset the device') self.fbutton.clicked.connect(self.fr_act) self.sbutton.clicked.connect(self.yv_input) self.ksbutton.setEnabled(False) self.sbutton.setEnabled(False) self.fbutton.setEnabled(False) hlayout.addWidget(self.ksbutton) hlayout.addWidget(self.sbutton) hlayout.addWidget(self.fbutton) glo.addLayout(hlayout) def ch_dur(th=None, dur=10): if len(dur) >= 1: try: dur = int(dur) except: dur = None if dur is None or not isinstance(dur, int): self.s_bar.setStyleSheet(self.s_error) self.s_bar.showMessage( '! Error: wrong duration entery, only integers') return None else: dur = 10 return dur def k_act(self): if self.ci_list.count() >= 1: cr = self.ci_list.currentRow() if cr is None or cr <= 0: cr = 0 ip = self.ci_list.item(cr).text() if self.Looping is not None: dur = self.ch_dur(self.nlo.text()) if dur is None: return True self.P = CC_thread(cancel_app, dur, ip) self.P.start() self.P.somesignal.connect(self.handleStatusMessage) self.P.setTerminationEnabled(True) self.inloop_state() return True else: ch = cancel_app(ip) if ch is None: self.s_bar.setStyleSheet(self.s_error) self.s_bar.showMessage('! Error: failed to kill stream ..') else: self.s_bar.setStyleSheet(self.s_norm) self.s_bar.showMessage('# Stream got killed ') else: self.s_bar.setStyleSheet(self.s_error) self.s_bar.showMessage('! Error: No items selected from the list') self.eout() return True def fr_act(self): if self.ci_list.count() >= 1: cr = self.ci_list.currentRow() if cr is None or cr <= 0: cr = 0 ip = self.ci_list.item(cr).text() if self.Looping is not None: dur = self.ch_dur(self.nlo.text()) if dur is None: return True self.P = CC_thread(reset_cc, dur, ip) self.P.start() self.P.somesignal.connect(self.handleStatusMessage) self.P.setTerminationEnabled(True) self.inloop_state() return True else: ch = reset_cc(ip) if ch is None: self.s_bar.setStyleSheet(self.s_error) self.s_bar.showMessage( '! Error: failed to factory reset ..') else: self.s_bar.setStyleSheet(self.s_norm) self.s_bar.showMessage('# Got factory reseted ') else: self.s_bar.setStyleSheet(self.s_error) self.s_bar.showMessage('! Error: No items selected from the list') self.eout() return True def y_act(self, link=None): if self.ci_list.count() >= 1: cr = self.ci_list.currentRow() if cr is None or cr <= 0: cr = 0 ip = self.ci_list.item(cr).text() if self.Looping is not None: dur = self.ch_dur(self.nlo.text()) if dur is None: return True self.P = CC_thread(send_app, dur, ip, link) self.P.start() self.P.somesignal.connect(self.handleStatusMessage) self.P.setTerminationEnabled(True) self.inloop_state() return True else: ch = reset_cc(ip) if ch is None: self.s_bar.setStyleSheet(self.s_error) self.s_bar.showMessage('! Error: failed to stream link ..') else: self.s_bar.setStyleSheet(self.s_norm) self.s_bar.showMessage('# Streamed the link ') else: self.s_bar.setStyleSheet(self.s_error) self.s_bar.showMessage('! Error: No items selected from the list') self.eout() return True def yv_input(self): text, okPressed = QInputDialog.getText( self, "Stream youtube", "Enter youtube video link to be streamed :") if okPressed and text != '': ntext = text.split('?') if len(ntext) <= 1: self.s_bar.setStyleSheet(self.s_error) self.s_bar.showMessage('! Error: Invalid youtube linkd ') return False ntext = ntext[1] if ntext != '' and len(ntext) > 1 and "youtube" in text: self.y_act(ntext) return True else: self.s_bar.setStyleSheet(self.s_error) self.s_bar.showMessage('! Error: Invalid youtube linkd ') return False @Slot(object) def handleStatusMessage(self, message): self.s_bar.setStyleSheet(self.s_loop) self.s_bar.showMessage(message) def il_add(self, items=[]): if len(items) >= 1: self.s_bar.setStyleSheet(self.s_norm) for i in items: fitem = self.ci_list.findItems(i, Qt.MatchExactly) if len(fitem) >= 1: self.s_bar.setStyleSheet(self.s_error) self.s_bar.showMessage( '! Error: Device exists in the list') else: self.s_bar.setStyleSheet(self.s_norm) self.ci_list.addItem(i) self.s_bar.showMessage('# Device was found and added') if not self.P.isRunning(): self.cle_btn.setEnabled(True) self.ci_list.setEnabled(True) self.llo.setEnabled(True) self.nlo.setEnabled(True) self.ksbutton.setEnabled(True) self.sbutton.setEnabled(True) self.fbutton.setEnabled(True) else: self.s_bar.setStyleSheet(self.s_norm) self.s_bar.showMessage('# Cleard devices list') self.ci_list.clear() self.cle_btn.setEnabled(False) self.ci_list.setEnabled(False) self.ksbutton.setEnabled(False) self.llo.setEnabled(False) self.nlo.setEnabled(False) self.sbutton.setEnabled(False) self.fbutton.setEnabled(False) return True def inloop_state(self, out=False): if not out: self.lbtn.setEnabled(True) self.cle_btn.setEnabled(False) self.ci_list.setEnabled(False) self.ksbutton.setEnabled(False) self.llo.setEnabled(False) self.nlo.setEnabled(False) self.sbutton.setEnabled(False) self.fbutton.setEnabled(False) else: if self.P.isRunning(): self.P.stop() self.lbtn.setEnabled(False) self.cle_btn.setEnabled(True) self.ci_list.setEnabled(True) self.ksbutton.setEnabled(True) self.llo.setEnabled(True) self.nlo.setEnabled(True) self.sbutton.setEnabled(True) self.fbutton.setEnabled(True) self.s_bar.clearMessage() return True def ds_bar(self, glo): self.s_bar = QStatusBar() self.s_error = "QStatusBar{color:red;font-weight:1000;}" self.s_loop = "QStatusBar{color:black;font-weight:1000;}" self.s_norm = "QStatusBar{color:blue;font-style:italic;" self.s_norm += "font-weight:500;}" self.s_bar.setStyleSheet(self.s_norm) glo.addWidget(self.s_bar) def eout(self): msgg = "<center>" msgg += " Opps, a critical error has occurred, we will be " msgg += " grateful if you can help fixing it, by reporting to us " msgg += " at : <br><br> " msgg += "<b><a href='https://github.io/mrf345/chrome-cut'> " msgg += "https://github.io/mrf345/chrome-cut </a></b> </center>" mm = QMessageBox.critical(self, "Critical Error", msgg, QMessageBox.Ok) exit(0)
class UsbResetter(QWidget): def __init__(self): super(UsbResetter, self).__init__() self.P = UR_thread() self.thr_counter = 0 self.Looping = None self.Hidden = None self.Fhidden = None self.s_error = "QStatusBar{color:red;font-weight:1000;}" self.s_loop = "QStatusBar{color:black;font-weight:1000;}" self.s_norm = "QStatusBar{color:blue;font-style:italic;" self.s_norm += "font-weight:500;}" favicon = r_path("images/favicon.png") logo = r_path("images/logo.png") if name == 'nt': favicon = r_path("images\\favicon.png") logo = r_path("images\\logo.png") self.favicon = QIcon(favicon) self.plogo = logo self.logo = QIcon(logo) self.setStyle() mlayout = QVBoxLayout() self.setAbout(mlayout) self.setUlist(mlayout) self.setCboxs(mlayout) self.setReset(mlayout) self.setLoop(mlayout) self.setSb(mlayout) # functionalities self.set_list() self.rootWarn() # initiation self.activateWindow() self.setLayout(mlayout) self.show() def setSb(self, m): self.statusbar = QStatusBar() m.addWidget(self.statusbar) def setStyle(self): self.setMaximumWidth(350) self.setMinimumWidth(350) self.setMaximumHeight(340) self.setMinimumHeight(340) self.setWindowTitle("usb-resetter 1.0") self.setWindowIcon(self.favicon) self.show() def setAbout(self, m): self.pushButton = QPushButton() self.icon1 = QIcon() self.icon1.addPixmap(QPixmap(self.plogo), QIcon.Normal, QIcon.Off) self.pushButton.setIcon(self.icon1) self.pushButton.setIconSize(QSize(300, 100)) self.pushButton.clicked.connect(self.show_about) m.addWidget(self.pushButton) def setUlist(self, m): self.comboBox = QComboBox() m.addWidget(self.comboBox) def setCboxs(self, m): ml = QVBoxLayout() fl = QHBoxLayout() self.checkBox_2 = QCheckBox("Audio") self.checkBox_3 = QCheckBox("Mass storage") self.checkBox_2.setToolTip("Filter by audio devices") self.checkBox_3.setToolTip("Filter by mass storage devices") fl.addWidget(self.checkBox_2) fl.addWidget(self.checkBox_3) ml.addLayout(fl) sl = QHBoxLayout() self.checkBox_4 = QCheckBox("Network") self.checkBox_4.setToolTip("Filter by network devices") self.checkBox_5 = QCheckBox("Human interface") self.checkBox_5.setToolTip("Filter by Keyboard, mouse, joystick ..etc") sl.addWidget(self.checkBox_4) sl.addWidget(self.checkBox_5) ml.addLayout(sl) self.checkBox_2.clicked.connect(self.set_list) self.checkBox_3.clicked.connect(self.set_list) self.checkBox_4.clicked.connect(self.set_list) self.checkBox_5.clicked.connect(self.set_list) m.addLayout(ml) def setReset(self, m): self.pushButton_2 = QPushButton("Reset it") font = QFont() font.setPointSize(17) font.setWeight(75) font.setBold(True) self.pushButton_2.setFont(font) self.pushButton_2.clicked.connect(self.setbut_reset) m.addWidget(self.pushButton_2) def setLoop(self, m): ml = QHBoxLayout() self.checkBox = QCheckBox("Looping") self.checkBox.setToolTip("To repeat resetting for specified duration") self.lineEdit = QLineEdit() self.lineEdit.setToolTip("Duration in-which the resetting is done") self.pushButton_3 = QPushButton("Stop") self.pushButton_3.setToolTip("Stop looping") ml.addWidget(self.checkBox) ml.addWidget(self.lineEdit) ml.addWidget(self.pushButton_3) self.pushButton_3.setEnabled(False) self.lineEdit.setEnabled(False) self.lineEdit.setPlaceholderText("duration in seconds") self.checkBox.clicked.connect(self.loop_status) self.pushButton_3.clicked.connect(self.in_loop) m.addLayout(ml) # Functionalities def show_about(self): Amsg = "<center>All credit reserved to the author of " Amsg += "usb-resetter version 1.0" Amsg += ", This work is a free, open-source project licensed " Amsg += " under Mozilla Public License version 2.0 . <br><br>" Amsg += " visit us for more infos and how-tos :<br> " Amsg += "<b><a href='https://usb-resetter.github.io/'> " Amsg += "https://usb-resetter.github.io/ </a> </b></center>" Amsgb = "About usb-resetter" v = QMessageBox.about(self, Amsgb, Amsg) v = str(v) return v def closeEvent(self, event=None): if self.Hidden is None: response = QMessageBox.question( self, "Hide or close", "Do you want to hide the application ?", QMessageBox.Yes, QMessageBox.No) if response == QMessageBox.Yes: if event is not None: event.ignore() self.Hidden = True self.hide() elif response == QMessageBox.No: if event is not None: event.accept() return self.exitEvent() else: return False else: return self.exitEvent() def exitEvent(self): if self.P.isRunning(): response = QMessageBox.question( self, "Making sure", "Sure, you want to exit while looping ?", QMessageBox.Yes, QMessageBox.No) if response == QMessageBox.Yes: self.P.stop() exit(0) else: return False else: exit(0) def get_list(self): ol = [] if self.checkBox_2.isChecked(): ol.append(1) if self.checkBox_3.isChecked(): ol.append(8) if self.checkBox_4.isChecked(): ol.append(2) if self.checkBox_5.isChecked(): ol.append(3) if len(ol) >= 1: return listd(ol, True) else: return listd(None, True) def set_list(self): self.comboBox.clear() its = self.get_list() if len(its) >= 1: self.comboBox.addItems(its) self.pushButton_2.setEnabled(True) self.checkBox.setEnabled(True) else: self.pushButton_2.setEnabled(False) self.checkBox.setEnabled(False) self.lineEdit.setEnabled(False) self.pushButton_3.setEnabled(False) def setbut_reset(self): t = self.comboBox.currentText() if self.Looping is None: if resetit(t): self.statusbar.setStyleSheet(self.s_norm) self.statusbar.showMessage( "# Done: usb device got reset") return True self.statusbar.setStyleSheet(self.s_error) if name != 'nt': self.statusbar.showMessage( "# Error: maybe you need sudo permissions") else: self.statusbar.showMessage( "# Error: maybe you need to add device to libusb") return False else: tl = self.lineEdit.text() self.statusbar.setStyleSheet(self.s_error) if len(tl) == 0: self.statusbar.showMessage( "# Error: you must enter duration for looping") return False try: self.thr_counter += 1 tl = int(tl) if tl < 2: self.statusbar.showMessage( "# Error: the least allowed value is 2") return False self.P = UR_thread(t, tl, self.thr_counter) self.P.start() self.P.somesignal.connect(self.handleStatusMessage) self.P.setTerminationEnabled(True) self.in_loop(False) except: self.statusbar.showMessage( "# Error: only valid integers allowed") return False def loop_status(self): if self.Looping: self.Looping = None self.lineEdit.setEnabled(False) self.pushButton_3.setEnabled(False) else: self.Looping = True self.lineEdit.setEnabled(True) return True def in_loop(self, stop=True): if stop: if self.P.isRunning(): self.P.stop() self.pushButton_3.setEnabled(False) self.pushButton_2.setEnabled(True) self.checkBox.setEnabled(True) if self.checkBox.isChecked(): self.lineEdit.setEnabled(True) self.checkBox_2.setEnabled(True) self.checkBox_3.setEnabled(True) self.checkBox_4.setEnabled(True) self.checkBox_5.setEnabled(True) self.comboBox.setEnabled(True) else: self.pushButton_3.setEnabled(True) self.pushButton_2.setEnabled(False) self.checkBox.setEnabled(False) self.lineEdit.setEnabled(False) self.checkBox_2.setEnabled(False) self.checkBox_3.setEnabled(False) self.checkBox_4.setEnabled(False) self.checkBox_5.setEnabled(False) self.comboBox.setEnabled(False) return True def rootWarn(self): if platform[:len(platform) - 1] == "linux": from os import getuid if getuid() != 0: self.statusbar.setStyleSheet(self.s_error) self.statusbar.showMessage( "# Error: you must use sudo on Linux") @Slot(object) def handleStatusMessage(self, message): self.statusbar.setStyleSheet(self.s_loop) if message[:7] == '# Error': self.in_loop() self.statusbar.setStyleSheet(self.s_error) self.statusbar.showMessage(message)
class MainWindow(QMainWindow): '''The main window of the program''' def __init__(self): '''Initialize the main window and it's parents''' super(MainWindow, self).__init__() self._createtWidgets() self._initUI() self._makeMenu() self._makeConnections() self.fileName = None self.pdfName = None self.scriptName = None self.expName = None self.rawName = None self.rawExpName = None # Set initial number of peaks self.exchange.setNumPeaks(2) # Set matrix to symmetric by default self.exchange.setMatrixSymmetry(True) # Set the initial window. self.scale.setValue(1900, 2100, False) # Default to rate in units of THz self.rate.setUnit('THz') # Clear button starts off inactive self.clear.setEnabled(False) def _createtWidgets(self): '''Creates all the widgets''' # Make the views self.plot = Plot(self) self.rate = RateView(parent=self) self.exchange = ExchangeView(parent=self) self.peak = PeakView(parent=self) self.scale = ScaleView(parent=self) # Create the model controller self.control = Controller(self) # Attach models to the views self.rate.setModel(self.control.rate) self.exchange.setModel(self.control.exchange, self.control.numpeaks) self.peak.setModel(self.control.peak) self.scale.setModel(self.control.scale) # Init the UI of all the views self.rate.initUI() self.exchange.initUI() self.peak.initUI() self.scale.initUI() # Last, make inter-view connections self.rate.makeConnections() self.exchange.makeConnections() self.peak.makeConnections() self.scale.makeConnections() self.plot.makeConnections() # The window will own a button to clear raw data self.clear = QPushButton('Clear Raw Data', self) self.clear.setToolTip(ttt('Remove raw data from the plot ' 'if there is any')) def _initUI(self): '''Sets up the layout of the window''' # Define a central widget and a layout for the window self.setCentralWidget(QWidget()) self.mainLayout = QHBoxLayout() self.setWindowTitle('Spectral Exchange') # Make a layout for all the parameter views params = QVBoxLayout() params.addWidget(self.rate) params.addWidget(self.exchange) params.addWidget(self.peak) # Add the parameter dialog self.mainLayout.addLayout(params) # Add the plot plot_lim = QVBoxLayout() plot_lim.addWidget(self.plot) lim_clear = QHBoxLayout() lim_clear.addWidget(self.scale) lim_clear.addWidget(self.clear) plot_lim.addLayout(lim_clear) self.mainLayout.addLayout(plot_lim) # Add the widgets to the central widget self.centralWidget().setLayout(self.mainLayout) def _makeConnections(self): '''Connect the widgets to each other''' # When the controller says plot, plot self.control.plotSpectrum.connect(self.plot.plotCalculatedData) # When the controller says resize x limits, do so self.control.newXLimits.connect(self.plot.changeScale) # Clear raw data if pushed self.clear.clicked.connect(self.clearRawData) # If the plot is clicked, send info to the scale widget self.plot.pointPicked.connect(self.scale.setSelection) def _makeMenu(self): '''Makes the menu bar for this widget''' # Get the menu bar object self.menu = self.menuBar() self.fileMenu = self.menu.addMenu('&File') # Open action open = QAction('&Open', self) open.setShortcuts(QKeySequence.Open) open.triggered.connect(self.openFromInput) open.setToolTip('Open an already made input file') self.fileMenu.addAction(open) # Save action save = QAction('&Save', self) save.setShortcuts(QKeySequence.Save) save.triggered.connect(self.saveToInput) save.setToolTip('Save settings to an input file') self.fileMenu.addAction(save) # Save action saveas = QAction('Save As', self) saveas.triggered.connect(self.saveToInputAs) save.setToolTip('Save settings to an input file of a new name') self.fileMenu.addAction(saveas) # Save action savepdf = QAction('Save as PDF', self) savepdf.triggered.connect(self.saveAsPDF) save.setToolTip('Save image to a PDF') self.fileMenu.addAction(savepdf) # Menu separator self.fileMenu.addSeparator() # Import action imp = QAction('&Import raw XY data', self) imp.setShortcut(QKeySequence('Ctrl+I')) imp.triggered.connect(self.importRawData) imp.setToolTip('Import raw data an plot alongside calculated data') self.fileMenu.addAction(imp) # Export action raw = QAction('Export raw XY data', self) raw.triggered.connect(self.exportRawData) raw.setToolTip('Export raw data to a file for use elsewhere') self.fileMenu.addAction(raw) # Export action exp = QAction('&Export calculated XY data', self) exp.setShortcut(QKeySequence('Ctrl+E')) exp.triggered.connect(self.exportXYData) exp.setToolTip('Export calculated data to a file for use elsewhere') self.fileMenu.addAction(exp) # Make script action scr = QAction('Make Sc&ript', self) scr.setShortcut(QKeySequence('Ctrl+R')) scr.triggered.connect(self.makeScript) scr.setToolTip('Create a python script that directly recreates this ' 'spectrum') self.fileMenu.addAction(scr) # Menu separator self.fileMenu.addSeparator() # Quit action quit = QAction('&Quit', self) quit.setShortcuts(QKeySequence.Quit) quit.triggered.connect(QApplication.instance().quit) self.fileMenu.addAction(quit) ####### # SLOTS ####### def clearRawData(self): '''Clear the raw data from the plot''' self.plot.clearRawData() self.clear.setEnabled(False) def openFromInput(self): '''Open parameters from an input file''' filter = 'Input Files (*.inp);;All (*)' s = QFileDialog.getOpenFileName(self, 'Input File Name', '', filter) # Continue unless the user hit cancel if not s[0]: return fileName = s[0] # Read given input file try: args = read_input(fileName) except ReaderError as r: # Error reading the input file error.showMessage(str(r)) # Set the number of peaks npeaks = len(args.num) if npeaks < 2: error.showMessage('Need at least 2 peaks for exchange') return elif npeaks > 4: error.showMessage('This GUI can only handle up to 4 peaks. ' 'Use the command-line version for an arbitrary ' 'number of peaks') return self.exchange.setNumPeaks(npeaks) # Set the exchange matrix = ZMat(npeaks, args.exchanges, args.exchange_rates, args.symmetric_exchange) self.exchange.setMatrixSymmetry(args.symmetric_exchange) self.exchange.setMatrix(matrix) # Set the rate if 'lifetime' in args: self.rate.setUnit(args.lifetime[1]) self.rate.setRate(args.lifetime[0]) else: self.rate.setUnit(args.rate[1]) self.rate.setRate(args.rate[0]) # Set the peak data self.peak.setPeaks(args.vib, args.Gamma_Lorentz, args.Gamma_Gauss, args.heights) # Plot this data self.control.setDataForPlot() # Plot raw data if it exists if args.raw is not None: self.rawName = args.rawName self.plot.setRawData(args.raw) self.plot.plotRawData() self.clear.setEnabled(True) # Set the limits self.scale.setValue(args.xlim[0], args.xlim[1], args.reverse) def saveToInput(self): '''Save current settings to current input file if available''' if not self.control.hasPlot: error.showMessage('Cannot save.. there is no data to save yet') return if self.fileName is None: self.saveToInputAs() else: self.inputGen(self.fileName) def saveToInputAs(self): '''Save current settings to an input file of specified name''' if not self.control.hasPlot: error.showMessage('Cannot save.. there is no data to save yet') return filter = 'Input Files (*.inp);;All (*)' d = '' if self.fileName is None else self.fileName s = QFileDialog.getSaveFileName(self, 'Input File Name', d, filter) # Continue unless the user hit cancel if not s[0]: return self.fileName = s[0] # Generate the input file self.inputGen(self.fileName) def saveAsPDF(self): '''Save plot as a PDF''' if not self.control.hasPlot: error.showMessage('Cannot save.. there is no data to save yet') return filter = 'PDF Documents (*.pdf);;All (*)' d = '' if self.pdfName is None else self.pdfName s = QFileDialog.getSaveFileName(self, 'PDF File Name', d, filter) # Continue unless the user hit cancel if not s[0]: return self.pdfName = s[0] # Set up the PDF printer printer = QPrinter() printer.setOutputFormat(QPrinter.PdfFormat) printer.setOrientation(QPrinter.Landscape) printer.setOutputFileName(self.pdfName) printer.setCreator('RAPID') # Send to the plot for printing p = QPainter() p.begin(printer) x, y = self.plot.calculatedData() plt = pgplot(x, y, antialias=True, connect='all', pen={'color': 'b', 'width': 0}) plt.setLabel('bottom', "Frequency (Wavenumbers, cm<sup>-1</sup>)") plt.getAxis('bottom').setPen('k') plt.setLabel('left', "Intensity (Normalized)") plt.getAxis('left').setPen('k') plt.setYRange(0, 1.1, padding=0) plt.invertX(self.plot.reversed) plt.setBackground('w') # White # The raw (experimental) data, if any if self.plot.rawData is not None: data = self.plot.getRawData() x, y = data[:,0], data[:,1] curve2 = PlotCurveItem(x, y, antialias=True, connect='all', pen={'color': 'g', 'width': 0}) plt.addItem(curve2) plt.render(p) p.end() def exportXYData(self): '''Export current spectrum to XY data''' if not self.control.hasPlot: error.showMessage('Cannot export.. there is no data to export yet') return filter = 'Data Files (*.txt *.data);;All (*)' d = '' if self.expName is None else self.expName s = QFileDialog.getSaveFileName(self, 'Calculated XY Data File Name', d, filter) # Continue unless the user hit cancel if not s[0]: return self.expName = s[0] # Grab the XY data from the plot x, y = self.plot.calculatedData() # Save in a standard format try: write_data(x, y, self.expName) except (IOError, OSError) as e: error.showMessage(str(e)) def exportRawData(self): '''Export current raw data to XY data''' if self.plot.rawData is None: error.showMessage('Cannot export.. there is no raw data to export yet') return filter = 'Data Files (*.txt *.data);;All (*)' d = '' if self.rawExpName is None else self.rawExpName s = QFileDialog.getSaveFileName(self, 'Raw XY Data File Name', d, filter) # Continue unless the user hit cancel if not s[0]: return self.rawExpName = s[0] # Grab the raw XY data from the plot data = self.plot.getRawData() # Save in a standard format try: write_data(data[:,0], data[:,1], self.rawExpName) except (IOError, OSError) as e: error.showMessage(str(e)) def importRawData(self): '''Import data from an XY file''' filter = 'Data Files (*.txt *.data);;All (*)' d = '' if self.rawName is None else self.rawName s = QFileDialog.getOpenFileName(self, 'Raw XY Data File Name', d, filter) # Continue unless the user hit cancel if not s[0]: return self.rawName = s[0] # Load raw data and plot in a second curve rawData = loadtxt(str(self.rawName)) self.plot.setRawData(rawData) self.plot.plotRawData() self.clear.setEnabled(True) def makeScript(self): '''Open parameters from an input file''' if not self.control.hasPlot: error.showMessage('Cannot save.. there is no data to save yet') return filter = 'Python Scripts (*.py)' d = '' if self.scriptName is None else self.scriptName s = QFileDialog.getSaveFileName(self, 'Python Script File Name', d, filter) # Continue unless the user hit cancel if not s[0]: return self.scriptName = s[0] # Get parameters needed xlim, rev, oldp, newp = self.control.getParametersForScript() x, y = self.plot.calculatedData() if self.clear.isEnabled(): raw = self.plot.rawData else: raw = None save_script(x, y, raw, xlim, rev, oldp, newp, self.scriptName) def inputGen(self, fileName): '''Generate an input file''' # Open file for writing try: fl = open(fileName, 'w') except (IOError, OSError) as e: error.showError(str(e)) # Generate a template string to print s = dedent('''\ # The rate or lifetime of the reaction {rate} # The exchange matrix {exchange} # The peak data {peaks} # The plot limits {limits} # Raw input file, if any {raw} ''') # Get the parameters from the underlying data xlim, rev, rate, exchange, peaks = self.control.getParametersForInput() # Create the rate string if rate[1] in ('s', 'ns', 'ps', 'fs'): lr = 'lifetime' else: lr = 'rate' ratestr = '{0} {1[0]:.3G} {1[1]}'.format(lr, rate) # Create exchange string exstr = [] if not exchange[2]: exstr.append('nosym') f = 'exchange {0:d} {1:d} {2:.3f}' for indx, r in zip(exchange[1], exchange[0]): exstr.append(f.format(indx[0]+1, indx[1]+1, r)) exstr = '\n'.join(exstr) # Create peak string peakstr = [] f = 'peak {0:.2f} {1:.3f} L={2:.3f} G={3:.3f}' for p, l, g, h in zip(peaks[0], peaks[1], peaks[2], peaks[3]): peakstr.append(f.format(p, h, l, g)) peakstr = '\n'.join(peakstr) # Create the limits string limitstr = 'xlim {0[0]:d} {0[1]:d}'.format(xlim) if rev: limitstr += '\nreverse' # Create the IO string if self.rawName is not None: rawstr = 'raw {0}'.format(self.rawName) else: rawstr = '' # Write the string to file fl.write(s.format(rate=ratestr, peaks=peakstr, limits=limitstr, exchange=exstr, raw=rawstr)) # Close file fl.close()
class NewWindow(QWidget): def __init__(self, app=None): super(NewWindow, self).__init__() self.app = app glo = QVBoxLayout(self) icp = r_path(solve_path('static/images/favicon.png')) # need to used objective message boxs instead of functions to set font self.Arial = QFont("", 12, QFont.Bold) self.Arials = QFont("", 10, QFont.Bold) # Language support variable self.Language = 'en' self.Runningo = False icon = QIcon(icp) self.SelfIinit(icon) self.center() self.langsList(glo) self.set_Abutton(icp, glo) self.Lists(glo) self.Flabel(glo) self.set_button(glo) self.setLayout(glo) mip = self.slchange() self.P = rwser(mip[1].split(',')[1], mip[0], self.app) self.activateWindow() self.show() def SelfIinit(self, icon): self.setWindowTitle('Free Queue Manager ' + version) self.setGeometry(300, 300, 200, 150) self.setMinimumWidth(500) self.setMaximumWidth(500) self.setMinimumHeight(400) self.setMaximumHeight(400) # Setting Icon self.setWindowIcon(icon) QToolTip.setFont(self.Arials) def Flabel(self, glo): fontt = self.Arial self.ic1 = QIcon(r_path(solve_path('static/images/pause.png'))) self.l = QLabel('Icond', self) self.ic1 = self.ic1.pixmap(70, 70, QIcon.Active, QIcon.On) self.l.setPixmap(self.ic1) self.l.setAlignment(Qt.AlignCenter | Qt.AlignHCenter) self.l.setFont(fontt) self.t = QLabel('Texted', self) self.t.setText(self.getTrans('11')) self.t.setOpenExternalLinks(True) self.t.setAlignment(Qt.AlignCenter | Qt.AlignHCenter) self.t.setFont(fontt) self.t.setToolTip(self.getTrans('9')) self.l.setToolTip(self.getTrans('9')) glo.addStretch() glo.addWidget(self.l) glo.addWidget(self.t) glo.addStretch() def langsList(self, glo): self.langs = { # languages to be displayed in select 'en': 'English', 'ar': 'Arabic', 'fr': 'French', 'it': 'Italian', 'es': 'Spanish' } self.langs_list = QComboBox() self.langs_list.addItems(list(self.langs.values())) self.langs_list.setCurrentIndex(1) self.langs_list.setToolTip(self.getTrans('1')) self.langs_list.currentIndexChanged.connect(self.langChange) glo.addWidget(self.langs_list) def langChange (self): self.language = list(self.langs.keys())[self.langs_list.currentIndex()] self.langs_list.setToolTip(self.getTrans('1')) self.Amsgb = self.getTrans('2') self.abutton.setToolTip( self.getTrans('2') ) self.mbutton.setText(self.getTrans('3')) self.mbutton.setToolTip(self.getTrans('4')) self.mbutton2.setText(self.getTrans('5')) self.mbutton2.setToolTip(self.getTrans('6')) self.sl.setToolTip( self.getTrans('7') ) self.sl2.setToolTip(self.getTrans('8')) self.t.setToolTip(self.getTrans('9')) self.l.setToolTip(self.getTrans('9')) if self.Runningo: pp = self.slchange() addr = self.getTrans('10') addr += u"<a href='http://" addr += pp[1].split(',')[1] + u":" + pp[0] addr += u"'> http://" + pp[1].split(',')[1] + u":" + pp[0] addr += u"</a>" self.t.setText(addr) else: self.t.setText(self.getTrans('11')) def getTrans(self, index): lang = list(self.langs.keys())[self.langs_list.currentIndex()] try: return LANGUAGES[lang][index] except Exception: return None def Lists(self, glo): ips = self.get_ips() self.sl = QComboBox() self.sl.addItems(ips) self.sl.setToolTip(self.getTrans('7')) self.sl2 = QComboBox() self.get_ports() self.sl2.setToolTip('8') self.sl.currentIndexChanged.connect(self.get_ports) glo.addWidget(self.sl) glo.addWidget(self.sl2) def get_ports(self, nauto=True): d_ports = ['5000', '8080', '3000', '80', '9931'] m_ports = [] while len(m_ports) < 10: mip = self.slchange() for p in d_ports: s = socket(AF_INET, SOCK_STREAM) try: s.bind((mip[1].split(',')[1], int(p))) s.close() m_ports.append(p) except: s.close() d_ports.remove(p) s = socket(AF_INET, SOCK_STREAM) p = randint(1000, 9999) try: s.bind((mip[1].split(',')[1], p)) s.close() m_ports.append(str(p)) except: s.close() if len(m_ports) >= 10: break self.sl2.clear() self.sl2.addItems(m_ports) def slchange(self): return [self.sl2.currentText(), self.sl.currentText()] def set_button(self, glo): hlayout = QHBoxLayout() self.mbutton = QPushButton('Start', self) self.mbutton.clicked.connect(self.s_server) self.mbutton.setFont(self.Arials) self.mbutton.setIcon(QPixmap(r_path(solve_path('static/images/play.png')))) self.mbutton2 = QPushButton('Stop', self) self.mbutton2.clicked.connect(self.st_server) self.mbutton2.setIcon(QPixmap(r_path(solve_path('static/images/pause.png')))) self.mbutton.setToolTip(self.getTrans('4')) self.mbutton2.setToolTip(self.getTrans('6')) self.mbutton2.setEnabled(False) self.mbutton2.setFont(self.Arials) hlayout.addWidget(self.mbutton) hlayout.addWidget(self.mbutton2) glo.addLayout(hlayout) def s_server(self): mip = self.slchange() self.P = rwser(mip[1].split(',')[1], mip[0], self.app) self.P.setTerminationEnabled(True) if not self.P.isRunning(): try: self.pport = mip[0] self.mbutton.setEnabled(False) self.mbutton2.setEnabled(True) self.sl.setEnabled(False) self.sl2.setEnabled(False) self.ic1 = QIcon(r_path(solve_path('static/images/play.png'))) self.ic1 = self.ic1.pixmap(70, 70, QIcon.Active, QIcon.On) self.l.setPixmap(self.ic1) pp = self.slchange() addr = self.getTrans('10') addr += "<a href='http://" addr += pp[1].split(',')[1] + ":" + pp[0] addr += "'> http://" + pp[1].split(',')[1] + ":" + pp[0] addr += "</a>" self.t.setText(addr) self.t.setFont(self.Arial) self.P.start() self.Runningo = True except: self.eout() else: self.eout() def st_server(self): if self.P.isRunning(): try: if self.P.isRunning: self.P.stop() self.mbutton.setEnabled(True) self.mbutton2.setEnabled(False) self.sl.setEnabled(True) self.sl2.setEnabled(True) self.t.setText(self.getTrans('11')) # removing the last used port to avoid termination error cind = self.sl2.currentIndex() self.sl2.removeItem(cind) self.get_ports() self.Runningo = False except: self.eout() else: self.eout() def set_Abutton(self, icon, glo): def show_about(nself): Amsg = u" <center> " Amsg += self.getTrans('12') + version + u" " Amsg += self.getTrans('13') Amsg += self.getTrans('14') Amsg += self.getTrans('15') Amsg += u"<br> <b><a href='https://fqms.github.io/'>" Amsg += u"https://fqms.github.io </a> </b></center>" Amsgb = self.getTrans('2') return QMessageBox.about( self, Amsgb, Amsg) self.abutton = QPushButton('', self) self.abutton.setIcon(QPixmap(icon)) self.abutton.setIconSize(QSize(150, 70)) self.abutton.setToolTip(self.getTrans('2')) self.abutton.clicked.connect(partial(show_about, self)) glo.addWidget(self.abutton) def closeEvent(self, event=None): if self.Runningo: response = self.msgApp( self.getTrans('16'), self.getTrans('17')) if response == 'y': if event is not None: event.accept() if self.P.isRunning(): self.P.stop() sys.exit(0) else: if event is not None: event.ignore() else: if event is not None: event.accept() if self.P.isRunning(): self.P.stop() sys.exit(0) def msgApp(self, title, msg): uinfo = QMessageBox.question(self, title, msg, QMessageBox.Yes | QMessageBox.No) if uinfo == QMessageBox.Yes: return 'y' if uinfo == QMessageBox.No: return 'n' def eout(self): if self.P.isRunning(): self.P.stop() msgg = u"<center>" msgg += self.getTrans('18') msgg += self.getTrans('19') msgg += u"<br><b><a href='https://fqms.github.io/'> " msgg += u"https://fqms.github.io </a></b> </center>" mm = QMessageBox.critical( self, self.getTrans('20'), msgg, QMessageBox.Ok) def center(self): qrect = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qrect.moveCenter(cp) self.move(qrect.topLeft()) def get_ips(self): il = [] for i in interfaces(): try: if os.name != 'nt': inf = i + " ," else: inf = ' ,' inf += ifaddresses(i)[2][0].get('addr') il.append(inf) except: pass return il
class TransformationFaceUI(QWidget): def __init__(self, oriPath, protoPath, oriPointsPath, protoPointsPath, regionsPath): super(TransformationFaceUI, self).__init__() #Initialize the data or object we need localParas, points = preprocess(oriPath, protoPath, oriPointsPath, protoPointsPath, regionsPath, 'L2') self.oriImg, self.protoImg, self.regionsPoints, self.is_in_regions_fun, self.distance_funs, self.affine_funs = localParas self.oriPlotDict, self.protoPlotDict, self.oriPoints, self.protoPoints = points self.oriPoints = np.array(self.oriPoints) self.protoPoints = np.array(self.protoPoints) self.e = 2 self.alpha = 1 self.oriPath = oriPath self.protoPath = protoPath self.oriPointsPath = oriPointsPath self.protoPointsPath = protoPointsPath self.regionsPath = regionsPath self.transform = 'Local Affine Transformation' self.newImg = None self.initUI() def initUI(self): QToolTip.setFont(QFont('SansSerif', 10)) self.setGeometry(300, 200, 810, 430) self.setWindowTitle('Transformation on Human Face') #Method choose combobox self.comboAffineLabel = QLabel(self) self.comboAffineLabel.setText('Transformation Method:') self.comboAffineLabel.setGeometry(60, 270, 230, 30) self.comboAffine = QComboBox(self) self.comboAffine.addItem("Local Affine Transformation") self.comboAffine.addItem("Moving Least Squares") self.comboAffine.addItem("Morphing") self.comboAffine.setGeometry(22, 290, 225, 30) self.comboAffine.activated[str].connect(self.affineChoiceChange) #The button to choose the original figure self.oriBtn = QPushButton('Choose Original Picture', self) self.oriBtn.setToolTip('Choose Original Picture') self.oriBtn.setGeometry(20, 330, 230, 30) self.oriBtn.clicked.connect(self.showOriDialog) #The button to choose the proto figure self.protoBtn = QPushButton('Choose Proto Picture', self) self.protoBtn.setToolTip('Choose Proto Picture') self.protoBtn.setGeometry(20, 365, 230, 30) self.protoBtn.clicked.connect(self.showProtoDialog) #The distance function choose combobox self.comboLabel = QLabel(self) self.comboLabel.setText('Distance Fun:') self.comboLabel.setGeometry(310, 280, 200, 30) self.comboDis = QComboBox(self) self.comboDis.addItem("L2") self.comboDis.addItem("L1") self.comboDis.setGeometry(410, 280, 80, 30) self.comboDis.activated[str].connect(self.distanceChoiceChange) #E choose slider self.eLabel = QLabel(self) self.eLabel.setText('E Value:0.00') self.eLabel.setGeometry(310, 320, 200, 30) self.eSld = QSlider(Qt.Horizontal, self) self.eSld.setRange(0, 10**5) self.eSld.setFocusPolicy(Qt.NoFocus) self.eSld.setGeometry(390, 320, 120, 30) self.eSld.valueChanged[int].connect(self.changeEValue) #alpha choose slider self.aLabel = QLabel(self) self.aLabel.setText('Alpha Value:0.00') self.aLabel.setGeometry(310, 360, 200, 30) self.aSld = QSlider(Qt.Horizontal, self) self.aSld.setRange(0, 10**5) self.aSld.setFocusPolicy(Qt.NoFocus) self.aSld.setGeometry(410, 360, 100, 30) self.aSld.valueChanged[int].connect(self.changeAlphaValue) # Picture show self.oriTextLabel = QLabel(self) self.protoTextLabel = QLabel(self) self.transTextLabel = QLabel(self) self.oriTextLabel.setText('The Orginal Picture') self.protoTextLabel.setText('The Proto Picture') self.transTextLabel.setText('The Picture after Transformation') self.oriTextLabel.move(70, 5) self.protoTextLabel.move(350, 5) self.transTextLabel.move(580, 5) self.oriLabel = QLabel(self) self.protoLabel = QLabel(self) self.transLabel = QLabel(self) pixmap = QPixmap(self.oriPath) pixmap2 = QPixmap(self.protoPath) self.oriLabel.setPixmap(pixmap) self.protoLabel.setPixmap(pixmap2) self.transLabel.setPixmap(pixmap) #Position setting self.oriLabel.setGeometry(20, 20, 230, 230) self.protoLabel.setGeometry(290, 20, 230, 230) self.transLabel.setGeometry(560, 20, 230, 230) self.oriLabel.setScaledContents(True) self.protoLabel.setScaledContents(True) self.transLabel.setScaledContents(True) #Load button self.loadOriBtn = QPushButton('Load Ori Points', self) self.loadOriBtn.setToolTip('Load Control Points From Txt File') self.loadOriBtn.setGeometry(550, 280, 130, 30) self.loadOriBtn.clicked.connect(self.showLoadOriDialog) self.loadProtoBtn = QPushButton('Load Proto Points', self) self.loadProtoBtn.setToolTip('Load Control Points From Txt File') self.loadProtoBtn.setGeometry(680, 280, 130, 30) self.loadProtoBtn.clicked.connect(self.showLoadProtoDialog) #Face ++ button self.faceBtn = QPushButton('Face++ Keypoint', self) self.faceBtn.setToolTip('Save the Face++ Keypoints') self.faceBtn.setGeometry(550, 315, 130, 30) self.faceBtn.clicked.connect(self.detectKeyPoints) #Load region Button self.loadRegionBtn = QPushButton('Load Regions', self) self.loadRegionBtn.setToolTip('Load Regions From Txt File') self.loadRegionBtn.setGeometry(680, 315, 130, 30) self.loadRegionBtn.clicked.connect(self.showLoadRegionDialog) #Save Button setting self.saveBtn = QPushButton('Save', self) self.saveBtn.setToolTip( 'Transform this picture to the shape of Baboon') self.saveBtn.setGeometry(560, 350, 110, 40) self.saveBtn.clicked.connect(self.saveImg) #Transform action button self.confirmBtn = QPushButton('Generate', self) self.confirmBtn.setToolTip('Generate') self.confirmBtn.setGeometry(680, 350, 110, 40) self.confirmBtn.clicked.connect(self.transformAction) self.show() #Invoke face++ and save which is connected to the facebtn def detectKeyPoints(self): print(self.oriPath) save_points('face_keypoints_ori.txt', detect((self.oriPath).encode('utf-8'))) #Save img connected to the save button def saveImg(self): if self.newImg == None: QtGui.QMessageBox.information(self, "Error", "There is not transformed figure") result = Image.fromarray(self.newImg) filenames = self.oriPath.split('/') filenames[len(filenames) - 1] = 'trans_' + filenames[len(filenames) - 1] newPath = '/'.join(filenames) result.save(newPath) #Connected to the transform button did the deformation and show it def transformAction(self): try: #For different methods have different solution if self.transform == 'Morphing': self.oriImg = np.array(Image.open(self.oriPath)) self.protoImg = np.array(Image.open(self.protoPath)) if self.oriImg.shape != self.protoImg.shape: QtGui.QMessageBox.information( self, "Error", "It is image morphing and required the same size of two images,please choose other images" ) return newImg = morphingAction((self.oriPath).encode('utf-8'), self.protoPath.encode('utf-8'), self.protoPointsPath.encode('utf-8'), self.alpha) else: localParas, points = preprocess(self.oriPath, self.protoPath, self.oriPointsPath, self.protoPointsPath, self.regionsPath, 'L2') if points == None: QtGui.QMessageBox.information(self, "Error", localParas) return self.oriImg, self.protoImg, self.regionsPoints, self.is_in_regions_fun, self.distance_funs, self.affine_funs = localParas self.oriPlotDict, self.protoPlotDict, self.oriPoints, self.protoPoints = points if self.oriImg.shape[len(self.oriImg.shape) - 1] != self.protoImg.shape[ len(self.protoImg.shape) - 1]: QtGui.QMessageBox.information( self, "Error", "The type of the figures is not the same, please choose another figure" ) return if self.transform == 'Local Affine Transformation': newImg = local_affine_transformation( self.oriImg, self.protoImg, self.e, self.regionsPoints, self.is_in_regions_fun, self.distance_funs, self.affine_funs) elif self.transform == "Moving Least Squares": newImg = affine_points_MLS(self.oriImg, self.protoImg, self.oriPoints, self.protoPoints, self.alpha) except BaseException: QtGui.QMessageBox.information( self, "Error", "There are error in the point choice or other things.") newImg = morphingAction((self.oriPath).encode('utf-8'), self.protoPath.encode('utf-8'), self.protoPointsPath.encode('utf-8'), self.alpha) self.newImg = np.uint8(newImg) newImg = rgb2bgr(np.uint8(newImg)) qimage = QImage(newImg, newImg.shape[1], newImg.shape[0], QImage.Format_ARGB32) pixmap_array = QPixmap.fromImage(qimage) self.transLabel.setPixmap(pixmap_array) ################################################################################################ ################################################################################################ ################################################################################################ ################################################################################################ ################################################################################################ ################################################################################################ ################################################################################################ ################################################################################################ #The file chooser , all of the function begin with show is the same but for different parameter. def showProtoDialog(self): fname, _ = QtGui.QFileDialog.getOpenFileName( self, 'Open file', '/home', "Image Files (*.png *.jpg *.bmp)") if fname != None and fname != '': self.protoPath = fname self.protoLabel.setPixmap(QPixmap(self.protoPath)) def showLoadOriDialog(self): fname, _ = QtGui.QFileDialog.getOpenFileName(self, 'Open file', '/home', "Text files (*.txt)") if fname != None and fname != '': self.oriPointsPath = fname def showLoadRegionDialog(self): fname, _ = QtGui.QFileDialog.getOpenFileName(self, 'Open file', '/home', "Text files (*.txt)") if fname != None and fname != '': self.regionsPath = fname def showLoadProtoDialog(self): fname, _ = QtGui.QFileDialog.getOpenFileName(self, 'Open file', '/home', "Text files (*.txt)") if fname != None and fname != '': self.protoPointsPath = fname def showOriDialog(self): fname, _ = QtGui.QFileDialog.getOpenFileName( self, 'Open file', '/home', "Image Files (*.png *.jpg *.bmp)") if fname != None and fname != '': self.oriPath = fname print(self.oriPath) self.oriLabel.setPixmap(QPixmap(self.oriPath)) #Connected with eSld change the e value in LAT method def changeEValue(self, x): self.e = 4.0 * x / 10**5 self.eLabel.setText('E Value:' + str('%.2f' % self.e)) #Connected with aSld change the alpha value in MLS and Morphing method(but the alpha range is not the same) def changeAlphaValue(self, x): if self.transform == 'Moving Least Squares': self.alpha = 2.0 * x / 10**5 elif self.transform == 'Morphing': self.alpha = 1.0 * x / 10**5 self.aLabel.setText('Alpha Value:' + str('%.2f' % self.alpha)) #Connected to the method combobox def affineChoiceChange(self, item): if self.transform in ['Moving Least Squares', 'Morphing'] and item in [ 'Moving Least Squares', 'Morphing' ] and item != self.transform: self.alpha = 0.0 self.aSld.setValue(self.alpha) self.transform = item #Connected to the distance combobox def distanceChoiceChange(self, item): self.oriImg, self.protoImg, self.protoPoints, self.affine_funs = preprocess( oriPath, protoPath, oriPointsPath, protoPointsPath, item)
class MTTFilterFileDialog(QDialog): def __init__(self, define_path='', define_type=None): super(MTTFilterFileDialog, self).__init__(get_maya_window()) self.supported_node_type = sorted([ node_type for (node_type, nice, attr) in MTTSettings.SUPPORTED_TYPE ]) self.defined_path = (define_path if os.path.isdir(define_path) or define_path == SOURCEIMAGES_TAG else None) self.defined_type = (define_type if define_type in self.supported_node_type else None) self.path_edit = None self.filter_reset_btn = None self.filter_line = None self.parent_folder_btn = None self.files_model = None self.files_list = None self.bookmark_list = None self.bookmark_list_sel_model = None self.types = None # move window to cursor position win_geo = MTTSettings.value('FilterFileDialog/windowGeometry', QRect(0, 0, 400, 300)) self.setGeometry(win_geo) mouse_pos = QCursor.pos() mouse_pos.setX(mouse_pos.x() - (win_geo.width() * 0.5)) self.move(mouse_pos) self.__create_ui() self.filter_line.setFocus() self.on_change_root_path(self.defined_path or SOURCEIMAGES_TAG) def __create_ui(self): """ Create main UI """ self.setWindowTitle(CREATE_NODE_TITLE) # remove window decoration if path and type is set if self.defined_path and self.defined_type: self.setWindowFlags(Qt.FramelessWindowHint | Qt.Popup) main_layout = QVBoxLayout(self) main_layout.setSpacing(1) main_layout.setContentsMargins(2, 2, 2, 2) # content layout content_layout = QVBoxLayout() self.files_model = QFileSystemModel() self.files_model.setNameFilterDisables(False) self.files_list = MTTFileList() self.files_list.setAlternatingRowColors(True) self.files_list.setSelectionMode(QAbstractItemView.ExtendedSelection) self.files_list.selectionValidated.connect(self.do_validate_selection) self.files_list.goToParentDirectory.connect(self.on_go_up_parent) self.files_list.doubleClicked.connect(self.on_double_click) self.files_list.setModel(self.files_model) buttons_layout = QHBoxLayout() content_layout.addLayout(self.__create_filter_ui()) content_layout.addWidget(self.files_list) content_layout.addLayout(buttons_layout) self.files_list.filter_line = self.filter_line if not self.defined_path: # path line path_layout = QHBoxLayout() # bookmark button bookmark_btn = QPushButton('') bookmark_btn.setFlat(True) bookmark_btn.setIcon(QIcon(':/addBookmark.png')) bookmark_btn.setToolTip('Bookmark this Folder') bookmark_btn.setStatusTip('Bookmark this Folder') bookmark_btn.clicked.connect(self.on_add_bookmark) # path line edit self.path_edit = QLineEdit() self.path_edit.editingFinished.connect(self.on_enter_path) # parent folder button self.parent_folder_btn = QPushButton('') self.parent_folder_btn.setFlat(True) self.parent_folder_btn.setIcon( QIcon(':/SP_FileDialogToParent.png')) self.parent_folder_btn.setToolTip('Parent Directory') self.parent_folder_btn.setStatusTip('Parent Directory') self.parent_folder_btn.clicked.connect(self.on_go_up_parent) # browse button browse_btn = QPushButton('') browse_btn.setFlat(True) browse_btn.setIcon(QIcon(':/navButtonBrowse.png')) browse_btn.setToolTip('Browse Directory') browse_btn.setStatusTip('Browse Directory') browse_btn.clicked.connect(self.on_browse) # parent widget and layout path_layout.addWidget(bookmark_btn) path_layout.addWidget(self.path_edit) path_layout.addWidget(self.parent_folder_btn) path_layout.addWidget(browse_btn) main_layout.addLayout(path_layout) # bookmark list bookmark_parent_layout = QHBoxLayout() bookmark_frame = QFrame() bookmark_frame.setFixedWidth(120) bookmark_layout = QVBoxLayout() bookmark_layout.setSpacing(1) bookmark_layout.setContentsMargins(2, 2, 2, 2) bookmark_frame.setLayout(bookmark_layout) bookmark_frame.setFrameStyle(QFrame.Sunken) bookmark_frame.setFrameShape(QFrame.StyledPanel) self.bookmark_list = MTTBookmarkList() self.bookmark_list.bookmarkDeleted.connect(self.do_delete_bookmark) self.bookmark_list.setAlternatingRowColors(True) self.bookmark_list.dragEnabled() self.bookmark_list.setAcceptDrops(True) self.bookmark_list.setDropIndicatorShown(True) self.bookmark_list.setDragDropMode(QListView.InternalMove) self.bookmark_list_sel_model = self.bookmark_list.selectionModel() self.bookmark_list_sel_model.selectionChanged.connect( self.on_select_bookmark) bookmark_layout.addWidget(self.bookmark_list) bookmark_parent_layout.addWidget(bookmark_frame) bookmark_parent_layout.addLayout(content_layout) main_layout.addLayout(bookmark_parent_layout) self.do_populate_bookmarks() else: main_layout.addLayout(content_layout) if not self.defined_type: # type layout self.types = QComboBox() self.types.addItems(self.supported_node_type) self.types.currentIndexChanged.connect(self.on_node_type_changed) if cmds.optionVar(exists='MTT_lastNodeType'): last = cmds.optionVar(query='MTT_lastNodeType') if last in self.supported_node_type: self.types.setCurrentIndex( self.supported_node_type.index(last)) buttons_layout.addWidget(self.types) if not self.defined_path or not self.defined_type: create_btn = QPushButton('C&reate') create_btn.clicked.connect(self.accept) cancel_btn = QPushButton('&Cancel') cancel_btn.clicked.connect(self.reject) buttons_layout.addStretch() buttons_layout.addWidget(create_btn) buttons_layout.addWidget(cancel_btn) def __create_filter_ui(self): """ Create filter widgets """ filter_layout = QHBoxLayout() filter_layout.setSpacing(1) filter_layout.setContentsMargins(0, 0, 0, 0) self.filter_reset_btn = QPushButton() icon = QIcon(':/filtersOff.png') self.filter_reset_btn.setIcon(icon) self.filter_reset_btn.setIconSize(QSize(22, 22)) self.filter_reset_btn.setFixedSize(24, 24) self.filter_reset_btn.setToolTip('Reset filter') self.filter_reset_btn.setFlat(True) self.filter_reset_btn.clicked.connect( partial(self.on_filter_set_text, '')) self.filter_line = QLineEdit() self.filter_line.setPlaceholderText('Enter filter string here') self.filter_line.textChanged.connect(self.on_filter_change_text) completer = QCompleter(self) completer.setCaseSensitivity(Qt.CaseInsensitive) completer.setModel(QStringListModel([], self)) self.filter_line.setCompleter(completer) filter_layout.addWidget(self.filter_reset_btn) filter_layout.addWidget(self.filter_line) return filter_layout def on_filter_set_text(self, text=''): """ Set text in filter field """ self.filter_line.setText(text) def on_filter_change_text(self, text): """ Apply filter string """ if len(text): icon = QIcon(':/filtersOn.png') self.filter_reset_btn.setIcon(icon) else: icon = QIcon(':/filtersOff.png') self.filter_reset_btn.setIcon(icon) self.files_model.setNameFilters([ '*%s*' % item.strip() for item in text.split(',') if item.strip() ]) def on_node_type_changed(self, index): cmds.optionVar( sv=['MTT_lastNodeType', self.supported_node_type[index]]) def on_double_click(self, index): current_item = self.files_model.filePath(index) if os.path.isdir(current_item): self.on_change_root_path(current_item) elif os.path.isfile(current_item): self.accept() def on_change_root_path(self, current_path): if current_path == SOURCEIMAGES_TAG: current_path = os.path.join( cmds.workspace(query=True, rootDirectory=True), cmds.workspace(fileRuleEntry='sourceImages')) self.files_model.setRootPath(current_path) self.files_list.setRootIndex(self.files_model.index(current_path)) if self.path_edit: self.path_edit.setText(current_path) if self.parent_folder_btn: current_dir = QDir(current_path) self.parent_folder_btn.setEnabled(current_dir.cdUp()) def on_go_up_parent(self): current_path = QDir(self.files_model.rootPath()) current_path.cdUp() self.on_change_root_path(current_path.absolutePath()) def on_enter_path(self): new_path = self.path_edit.text() if os.path.isdir(new_path): self.on_change_root_path(new_path) else: self.path_edit.setText(self.files_model.rootPath()) def on_browse(self): current_path = self.files_model.rootPath() file_dialog = QFileDialog(self, 'Select a Folder', current_path) file_dialog.setFileMode(QFileDialog.Directory) file_dialog.setOption(QFileDialog.ShowDirsOnly) if file_dialog.exec_(): self.on_change_root_path(file_dialog.selectedFiles()[0]) def on_select_bookmark(self, selected, deselected): current_item = selected.indexes() if current_item: self.on_change_root_path( self.bookmark_list.selectedItems()[0].root_path) def on_add_bookmark(self): current_path = self.files_model.rootPath() self.on_add_bookmark_item( '%s|%s' % (os.path.basename(current_path), current_path)) def on_add_bookmark_item(self, item): if item == '': return current_item = MTTBookmarkItem() current_item.add_raw_data(item) current_item.setSizeHint(QSize(40, 25)) current_item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsEditable | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled) self.bookmark_list.addItem(current_item) def do_delete_bookmark(self): current_item = self.bookmark_list.selectedItems() if current_item: item_row = self.bookmark_list.row(current_item[0]) self.bookmark_list.takeItem(item_row) del current_item[0] def do_save_bookmark(self): if not self.bookmark_list: return row_count = self.bookmark_list.count() ordered_list = list() for i in range(row_count): item = self.bookmark_list.item(i) name = item.text().replace(',', '_').replace('|', '_') path = item.root_path if name != 'sourceimages': ordered_list.append('%s|%s' % (name, path)) MTTSettings.set_value('FilterFileDialog/bookmarks', ','.join(ordered_list)) def do_populate_bookmarks(self): bookmarks = ['sourceimages|%s' % SOURCEIMAGES_TAG] bookmarks.extend( MTTSettings.value('FilterFileDialog/bookmarks').split(',')) for bm in bookmarks: self.on_add_bookmark_item(bm) def do_validate_selection(self): selection = self.files_list.selectedIndexes() if len(selection) == 1: current_path = self.files_model.filePath(selection[0]) if os.path.isdir(current_path): self.on_change_root_path(current_path) return self.accept() def get_selected_files(self): selected_items = list() for item_index in self.files_list.selectedIndexes(): current_path = self.files_model.filePath(item_index) if os.path.isfile(current_path): selected_items.append(current_path) return selected_items def get_node_type(self): return self.types.currentText() if self.types else self.defined_type def closeEvent(self, event): MTTSettings.set_value('FilterFileDialog/windowGeometry', self.geometry()) self.do_save_bookmark() self.deleteLater() event.accept()
def initUI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) # Select analysis file button button = QPushButton('Select analysis file', self) button.setToolTip('*.inp CalculiX analysis file.') button.move(10, 10) button.clicked.connect(self.on_click) # Text box - file path and name self.textbox_file_name = QLineEdit(self) self.textbox_file_name.move(120, 15) self.textbox_file_name.resize(420, 20) self.textbox_file_name.setText("None analysis file selected") self.textbox_file_name.setToolTip('Analysis file.') # Update button button1 = QPushButton('Update domains', self) button1.setToolTip( 'Update naming inputs and material data from FreeCAD.') button1.move(10, 50) button1.clicked.connect(self.on_click1) # Domains definition # Label above domains definition label21 = QLabel('Domain 0', self) label21.setStyleSheet("font-weight: bold") label21.move(120, 50) label21 = QLabel('Domain 1', self) label21.setStyleSheet("font-weight: bold") label21.move(260, 50) label21 = QLabel('Domain 2', self) label21.setStyleSheet("font-weight: bold") label21.move(400, 50) label24 = QLabel('Material object', self) label24.move(20, 80) label25 = QLabel('Thickness object', self) label25.move(20, 110) label26 = QLabel('As design domain', self) label26.move(20, 140) label27 = QLabel('Stress limit [MPa]', self) label27.move(20, 170) # Combo box - select domain by material object self.combo = QComboBox(self) self.combo.setToolTip('Material object to define the domain.') self.combo.move(120, 80) self.combo.resize(140, 30) self.combo.currentIndexChanged.connect(self.on_change) self.combo1 = QComboBox(self) self.combo1.setToolTip('Material object to define the domain.') self.combo1.move(260, 80) self.combo1.resize(140, 30) self.combo1.currentIndexChanged.connect(self.on_change1) self.combo2 = QComboBox(self) self.combo2.setToolTip('Material object to define the domain.') self.combo2.move(400, 80) self.combo2.resize(140, 30) self.combo2.currentIndexChanged.connect(self.on_change2) # Combo box - select thickness object self.combo0t = QComboBox(self) self.combo0t.setToolTip( 'Thickness object to specify if domain is for shells.') self.combo0t.move(120, 110) self.combo0t.resize(140, 30) self.combo1t = QComboBox(self) self.combo1t.setToolTip( 'Thickness object to specify if domain is for shells.') self.combo1t.move(260, 110) self.combo1t.resize(140, 30) self.combo2t = QComboBox(self) self.combo2t.setToolTip( 'Thickness object to specify if domain is for shells.') self.combo2t.move(400, 110) self.combo2t.resize(140, 30) self.textbox3 = QLineEdit(self) self.textbox3.move(120, 170) self.textbox3.resize(40, 20) # self.textbox3.setText("") self.textbox3.setToolTip( 'Thickness [mm] of shell elements in the domain.\n' 'This value overwrites thickness defined in FreeCAD') self.textbox4 = QLineEdit(self) self.textbox4.move(260, 170) self.textbox4.resize(40, 20) # self.textbox4.setText("") self.textbox4.setToolTip( 'Thickness [mm] of shell elements in the domain.\n' 'This value overwrites thickness defined in FreeCAD') self.textbox5 = QLineEdit(self) self.textbox5.move(400, 170) self.textbox5.resize(40, 20) # self.textbox5.setText("") self.textbox5.setToolTip( 'Thickness [mm] of shell elements in the domain.\n' 'This value overwrites thickness defined in FreeCAD') # Check box - design or nondesign self.checkbox = QCheckBox('', self) self.checkbox.setChecked(True) self.checkbox.setToolTip('Check to be the design domain.') self.checkbox.move(120, 140) self.checkbox1 = QCheckBox('', self) self.checkbox1.setChecked(True) self.checkbox1.setToolTip('Check to be the design domain.') self.checkbox1.move(260, 140) self.checkbox2 = QCheckBox('', self) self.checkbox2.setChecked(True) self.checkbox2.setToolTip('Check to be the design domain.') self.checkbox2.move(400, 140) # Text box - stress limit self.textbox = QLineEdit(self) self.textbox.move(120, 170) self.textbox.resize(40, 20) # self.textbox.setText("") self.textbox.setToolTip( 'Von Mises stress [MPa] limit, when reached, material removing will stop.' ) self.textbox1 = QLineEdit(self) self.textbox1.move(260, 170) self.textbox1.resize(40, 20) # self.textbox1.setText("") self.textbox1.setToolTip( 'Von Mises stress [MPa] limit, when reached, material removing will stop.' ) self.textbox2 = QLineEdit(self) self.textbox2.move(400, 170) self.textbox2.resize(40, 20) # self.textbox2.setText("") self.textbox2.setToolTip( 'Von Mises stress [MPa] limit, when reached, material removing will stop.' ) # Filters # Label above filter definition label31 = QLabel('Filter 0', self) label31.setStyleSheet("font-weight: bold") label31.move(120, 210) label32 = QLabel('Filter 1', self) label32.setStyleSheet("font-weight: bold") label32.move(260, 210) label33 = QLabel('Filter 2', self) label33.setStyleSheet("font-weight: bold") label33.move(400, 210) label34 = QLabel('Type', self) label34.move(20, 240) label35 = QLabel('Range [mm]', self) label35.move(20, 270) label36 = QLabel('Direction vector', self) label36.move(20, 300) label37 = QLabel('Apply to', self) label37.move(20, 330) # Combo box - select filter type self.combo6 = QComboBox(self) self.combo6.setToolTip( 'Filters:\n' '"simple" to suppress checkerboard effect,\n' '"casting" to prescribe casting direction (opposite to milling direction)\n' 'Recommendation: for casting use as first "casting" and as second "simple"' ) self.combo6.addItem("None") self.combo6.addItem("simple") self.combo6.addItem("casting") self.combo6.setCurrentIndex(1) self.combo6.move(120, 240) self.combo6.currentIndexChanged.connect(self.on_change6) self.combo7 = QComboBox(self) self.combo7.setToolTip( 'Filters:\n' '"simple" to suppress checkerboard effect,\n' '"casting" to prescribe casting direction (opposite to milling direction)\n' 'Recommendation: for casting use as first "casting" and as second "simple"' ) self.combo7.addItem("None") self.combo7.addItem("simple") self.combo7.addItem("casting") self.combo7.move(260, 240) self.combo7.currentIndexChanged.connect(self.on_change7) self.combo8 = QComboBox(self) self.combo8.setToolTip( 'Filters:\n' '"simple" to suppress checkerboard effect,\n' '"casting" to prescribe casting direction (opposite to milling direction)\n' 'Recommendation: for casting use as first "casting" and as second "simple"' ) self.combo8.addItem("None") self.combo8.addItem("simple") self.combo8.addItem("casting") self.combo8.move(400, 240) self.combo8.currentIndexChanged.connect(self.on_change8) # Text box - filter range self.textbox6 = QLineEdit(self) self.textbox6.move(120, 270) self.textbox6.resize(50, 20) # self.textbox6.setText("") self.textbox6.setToolTip( 'Filter range [mm], recommended two times mesh size.') self.textbox7 = QLineEdit(self) self.textbox7.move(260, 270) self.textbox7.resize(50, 20) # self.textbox7.setText("") self.textbox7.setToolTip( 'Filter range [mm], recommended two times mesh size.') self.textbox7.setEnabled(False) self.textbox8 = QLineEdit(self) self.textbox8.move(400, 270) self.textbox8.resize(50, 20) # self.textbox8.setText("") self.textbox8.setToolTip( 'Filter range [mm], recommended two times mesh size.') self.textbox8.setEnabled(False) # Text box - casting direction self.textbox9 = QLineEdit(self) self.textbox9.move(120, 300) self.textbox9.resize(80, 20) self.textbox9.setText("0, 0, 1") self.textbox9.setEnabled(False) self.textbox9.setToolTip( 'Casting direction vector, e.g. direction in z axis:\n' '0, 0, 1\n\n' 'solid void\n' 'XXXXXX.................\n' 'XXX........................\n' 'XX........................... --> z axis\n' 'XXXXX....................\n' 'XXXXXXXXXXX......') self.textbox10 = QLineEdit(self) self.textbox10.move(260, 300) self.textbox10.resize(80, 20) self.textbox10.resize(80, 20) self.textbox10.setText("0, 0, 1") self.textbox10.setEnabled(False) self.textbox10.setToolTip( 'Casting direction vector, e.g. direction in z axis:\n' '0, 0, 1\n\n' 'solid void\n' 'XXXXXX.................\n' 'XXX........................\n' 'XX........................... --> z axis\n' 'XXXXX....................\n' 'XXXXXXXXXXX......') self.textbox11 = QLineEdit(self) self.textbox11.move(400, 300) self.textbox11.resize(80, 20) self.textbox11.setText("0, 0, 1") self.textbox11.setEnabled(False) self.textbox11.setToolTip( 'Casting direction vector, e.g. direction in z axis:\n' '0, 0, 1\n\n' 'solid void\n' 'XXXXXX.................\n' 'XXX........................\n' 'XX........................... --> z axis\n' 'XXXXX....................\n' 'XXXXXXXXXXX......') # list widget - select domains self.widget = QListWidget(self) self.widget.setToolTip( 'Domains affected by the filter.\n' 'Select only from domains which you defined above.') self.widget.move(120, 330) self.widget.resize(140, 120) self.widget.setSelectionMode(QAbstractItemView.MultiSelection) self.widget1 = QListWidget(self) self.widget1.setToolTip( 'Domains affected by the filter.\n' 'Select only from domains which you defined above.') self.widget1.move(260, 330) self.widget1.resize(140, 120) self.widget1.setSelectionMode(QAbstractItemView.MultiSelection) self.widget1.setEnabled(False) self.widget2 = QListWidget(self) self.widget2.setToolTip( 'Domains affected by the filter.\n' 'Select only from domains which you defined above.') self.widget2.move(400, 330) self.widget2.resize(140, 120) self.widget2.setSelectionMode(QAbstractItemView.MultiSelection) self.widget2.setEnabled(False) # Other settings label40 = QLabel('Other settings', self) label40.setStyleSheet("font-weight: bold") label40.move(10, 470) # AR, RR slider label41 = QLabel('Change per iteration: low', self) label41.setFixedWidth(150) label41.move(10, 500) label42 = QLabel('high', self) label42.move(240, 500) self.slider = QSlider(Qt.Horizontal, self) self.slider.setRange(1, 3) self.slider.setSingleStep(1) self.slider.setValue(2) self.slider.move(150, 500) self.slider.resize(80, 30) self.slider.setToolTip( 'Sets mass change per iteration, which is controlled as\n' 'slow: mass_addition_ratio=0.01, mass_removal_ratio=0.02\n' 'middle: mass_addition_ratio=0.015, mass_removal_ratio=0.03\n' 'fast: mass_addition_ratio=0.03, mass_removal_ratio=0.06') # optimization base combobox label51 = QLabel('Optimization base', self) label51.move(10, 530) self.combo51 = QComboBox(self) self.combo51.setToolTip( 'Basic principle to determine if element should remain or be removed:\n' '"stiffness" to maximize stiffness (minimize compliance),\n' '"heat" to maximize heat flow.') self.combo51.addItem("stiffness") self.combo51.addItem("heat") self.combo51.move(120, 530) # mass goal ratio label52 = QLabel('Mass goal ratio', self) label52.move(10, 560) self.textbox52 = QLineEdit(self) self.textbox52.move(120, 560) self.textbox52.resize(50, 20) self.textbox52.setText("0.4") self.textbox52.setToolTip( 'Fraction of all design domains masses to be achieved;\n' 'between 0 and 1.') # generate conf. file button button21 = QPushButton('Generate conf. file', self) button21.setToolTip( 'Writes configuration file with optimization parameters.') button21.move(10, 600) button21.clicked.connect(self.on_click21) # edit conf. file button button22 = QPushButton('Edit conf. file', self) button22.setToolTip('Opens configuration file for hand modifications.') button22.move(10, 630) button22.clicked.connect(self.on_click22) # run optimization button button23 = QPushButton('Run optimization', self) button23.setToolTip('Writes configuration file and runs optimization.') button23.move(10, 660) button23.clicked.connect(self.on_click23) # generate conf file and run optimization button button24 = QPushButton('Generate conf.\nfile and run\noptimization', self) button24.setToolTip('Writes configuration file and runs optimization.') button24.move(120, 600) button24.resize(100, 90) button24.clicked.connect(self.on_click24) # help buttons label41 = QLabel('Help', self) label41.move(440, 560) button31 = QPushButton('Example', self) button31.setToolTip( 'https://github.com/fandaL/beso/wiki/Example-4:-GUI-in-FreeCAD') button31.move(440, 590) # button31.resize(80, 50) button31.clicked.connect(self.on_click31) button32 = QPushButton('Conf. comments', self) button32.setToolTip( 'https://github.com/fandaL/beso/blob/master/beso_conf.py') button32.move(440, 620) # button32.resize(80, 50) button32.clicked.connect(self.on_click32) button33 = QPushButton('Close', self) button33.move(440, 690) # button33.resize(80, 50) button33.clicked.connect(self.on_click33) # open log file button40 = QPushButton('Open log file', self) button40.setToolTip('Opens log file in your text editor.\n' '(Does not refresh automatically.)') button40.move(10, 690) button40.clicked.connect(self.on_click40) self.on_click1() # first update self.show()
class RunnerDialog(QDialog): options_added = Signal(Options) options_running = Signal(Options) options_simulated = Signal(Options) options_error = Signal(Options, Exception) results_saved = Signal(Results, str) results_error = Signal(Results, Exception) def __init__(self, parent=None): QDialog.__init__(self, parent) self.setWindowTitle('Runner') self.setMinimumWidth(750) # Runner self._runner = None self._running_timer = QTimer() self._running_timer.setInterval(500) # Widgets self._dlg_progress = QProgressDialog() self._dlg_progress.setRange(0, 100) self._dlg_progress.setModal(True) self._dlg_progress.hide() lbl_outputdir = QLabel("Output directory") self._txt_outputdir = DirBrowseWidget() max_workers = cpu_count() #@UndefinedVariable lbl_workers = QLabel('Number of workers') self._spn_workers = QSpinBox() self._spn_workers.setRange(1, max_workers) self._spn_workers.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) lbl_max_workers = QLabel('(max: %i)' % max_workers) self._chk_overwrite = QCheckBox("Overwrite existing results in output directory") self._chk_overwrite.setChecked(True) self._lbl_available = QLabel('Available') self._lst_available = QListView() self._lst_available.setModel(_AvailableOptionsListModel()) self._lst_available.setSelectionMode(QListView.SelectionMode.MultiSelection) tlb_available = QToolBar() spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) tlb_available.addWidget(spacer) act_open = tlb_available.addAction(getIcon("document-open"), "Open") act_open.setShortcut(QKeySequence.Open) tlb_available.addSeparator() act_remove = tlb_available.addAction(getIcon("list-remove"), "Remove") act_clear = tlb_available.addAction(getIcon("edit-clear"), "Clear") self._btn_addtoqueue = QPushButton(getIcon("go-next"), "") self._btn_addtoqueue.setToolTip("Add to queue") self._btn_addtoqueue.setEnabled(False) self._btn_addalltoqueue = QPushButton(getIcon("go-last"), "") self._btn_addalltoqueue.setToolTip("Add all to queue") self._btn_addalltoqueue.setEnabled(False) self._lbl_options = QLabel('Queued/Running/Completed') self._tbl_options = QTableView() self._tbl_options.setModel(_StateOptionsTableModel()) self._tbl_options.setItemDelegate(_StateOptionsItemDelegate()) self._tbl_options.setSelectionMode(QListView.SelectionMode.NoSelection) self._tbl_options.setColumnWidth(1, 60) self._tbl_options.setColumnWidth(2, 80) header = self._tbl_options.horizontalHeader() header.setResizeMode(0, QHeaderView.Interactive) header.setResizeMode(1, QHeaderView.Fixed) header.setResizeMode(2, QHeaderView.Fixed) header.setResizeMode(3, QHeaderView.Stretch) self._btn_start = QPushButton(getIcon("media-playback-start"), "Start") self._btn_cancel = QPushButton("Cancel") self._btn_cancel.setEnabled(False) self._btn_close = QPushButton("Close") self._btn_import = QPushButton("Import") self._btn_import.setEnabled(False) # Layouts layout = QVBoxLayout() sublayout = QGridLayout() sublayout.addWidget(lbl_outputdir, 0, 0) sublayout.addWidget(self._txt_outputdir, 0, 1) sublayout.addWidget(lbl_workers, 1, 0) subsublayout = QHBoxLayout() subsublayout.addWidget(self._spn_workers) subsublayout.addWidget(lbl_max_workers) sublayout.addLayout(subsublayout, 1, 1) layout.addLayout(sublayout) sublayout.addWidget(self._chk_overwrite, 2, 0, 1, 3) sublayout = QGridLayout() sublayout.setColumnStretch(0, 1) sublayout.setColumnStretch(2, 3) sublayout.addWidget(self._lbl_available, 0, 0) sublayout.addWidget(self._lst_available, 1, 0) sublayout.addWidget(tlb_available, 2, 0) subsublayout = QVBoxLayout() subsublayout.addStretch() subsublayout.addWidget(self._btn_addtoqueue) subsublayout.addWidget(self._btn_addalltoqueue) subsublayout.addStretch() sublayout.addLayout(subsublayout, 1, 1) sublayout.addWidget(self._lbl_options, 0, 2) sublayout.addWidget(self._tbl_options, 1, 2) layout.addLayout(sublayout) sublayout = QHBoxLayout() sublayout.addStretch() sublayout.addWidget(self._btn_import) sublayout.addWidget(self._btn_start) sublayout.addWidget(self._btn_cancel) sublayout.addWidget(self._btn_close) layout.addLayout(sublayout) self.setLayout(layout) # Signal self._running_timer.timeout.connect(self._onRunningTimer) act_open.triggered.connect(self._onOpen) act_remove.triggered.connect(self._onRemove) act_clear.triggered.connect(self._onClear) self._btn_addtoqueue.released.connect(self._onAddToQueue) self._btn_addalltoqueue.released.connect(self._onAddAllToQueue) self._btn_start.released.connect(self._onStart) self._btn_cancel.released.connect(self._onCancel) self._btn_close.released.connect(self._onClose) self._btn_import.released.connect(self._onImport) self.options_added.connect(self._onOptionsAdded) self.options_running.connect(self._onOptionsRunning) self.options_simulated.connect(self._onOptionsSimulated) self.options_error.connect(self._onOptionsError) self.results_error.connect(self._onResultsError) # Defaults settings = get_settings() section = settings.add_section('gui') if hasattr(section, 'outputdir'): self._txt_outputdir.setPath(section.outputdir) if hasattr(section, 'maxworkers'): self._spn_workers.setValue(int(section.maxworkers)) if hasattr(section, 'overwrite'): state = True if section.overwrite.lower() == 'true' else False self._chk_overwrite.setChecked(state) def _onDialogProgressProgress(self, progress, status): self._dlg_progress.setValue(progress * 100) self._dlg_progress.setLabelText(status) def _onDialogProgressCancel(self): self._dlg_progress.hide() if self._options_reader_thread is None: return self._options_reader_thread.cancel() self._options_reader_thread.quit() self._options_reader_thread.wait() def _onDialogProgressException(self, ex): self._dlg_progress.hide() self._options_reader_thread.quit() self._options_reader_thread.wait() messagebox.exception(self, ex) def _onRunningTimer(self): self._tbl_options.model().reset() def _onOpen(self): settings = get_settings() curdir = getattr(settings.gui, 'opendir', os.getcwd()) filepath, namefilter = \ QFileDialog.getOpenFileName(self, "Open", curdir, 'Options [*.xml] (*.xml)') if not filepath or not namefilter: return settings.gui.opendir = os.path.dirname(filepath) if not filepath.endswith('.xml'): filepath += '.xml' self._options_reader_thread = _OptionsReaderWrapperThread(filepath) self._dlg_progress.canceled.connect(self._onDialogProgressCancel) self._options_reader_thread.resultReady.connect(self._onOpened) self._options_reader_thread.progressUpdated.connect(self._onDialogProgressProgress) self._options_reader_thread.exceptionRaised.connect(self._onDialogProgressException) self._options_reader_thread.start() self._dlg_progress.reset() self._dlg_progress.show() def _onOpened(self, options): self._dlg_progress.hide() self._options_reader_thread.quit() self._options_reader_thread.wait() self._options_reader_thread = None try: self._lst_available.model().addOptions(options) except Exception as ex: messagebox.exception(self, ex) def _onRemove(self): selection = self._lst_available.selectionModel().selection().indexes() if len(selection) == 0: QMessageBox.warning(self, "Queue", "Select an options") return model = self._lst_available.model() for row in sorted(map(methodcaller('row'), selection), reverse=True): model.popOptions(row) def _onClear(self): self._lst_available.model().clearOptions() def _onAddToQueue(self): selection = self._lst_available.selectionModel().selection().indexes() if len(selection) == 0: QMessageBox.warning(self, "Queue", "Select an options") return model = self._lst_available.model() for row in sorted(map(methodcaller('row'), selection), reverse=True): options = model.options(row) try: self._runner.put(options) except Exception as ex: messagebox.exception(self, ex) return def _onAddAllToQueue(self): model = self._lst_available.model() for row in reversed(range(0, model.rowCount())): options = model.options(row) try: self._runner.put(options) except Exception as ex: messagebox.exception(self, ex) return def _onStart(self): outputdir = self._txt_outputdir.path() if not outputdir: QMessageBox.critical(self, 'Start', 'Missing output directory') return max_workers = self._spn_workers.value() overwrite = self._chk_overwrite.isChecked() self.start(outputdir, overwrite, max_workers) def _onCancel(self): self.cancel() def _onClose(self): if self._runner is not None: self._runner.close() self._running_timer.stop() self.close() def _onImport(self): list_options = self._lst_available.model().listOptions() if not list_options: return # Select options dialog = _OptionsSelector(list_options) if not dialog.exec_(): return options = dialog.options() # Start importer outputdir = self._runner.outputdir max_workers = self._runner.max_workers importer = LocalImporter(outputdir, max_workers) importer.start() importer.put(options) self._dlg_progress.show() try: while importer.is_alive(): if self._dlg_progress.wasCanceled(): importer.cancel() break self._dlg_progress.setValue(importer.progress * 100) finally: self._dlg_progress.hide() def _onOptionsAdded(self, options): logging.debug('runner: optionsAdded') self._tbl_options.model().addOptions(options) def _onOptionsRunning(self, options): logging.debug('runner: optionsRunning') self._tbl_options.model().resetOptions(options) def _onOptionsSimulated(self, options): logging.debug('runner: optionsSimulated') self._tbl_options.model().resetOptions(options) def _onOptionsError(self, options, ex): logging.debug('runner: optionsError') self._tbl_options.model().resetOptions(options) def _onResultsError(self, results, ex): logging.debug('runner: resultsError') self._tbl_options.model().reset() def closeEvent(self, event): if self.is_running(): message = 'Runner is running. Do you want to continue?' answer = QMessageBox.question(self, 'Runner', message, QMessageBox.Yes | QMessageBox.No) if answer == QMessageBox.No: event.ignore() return self.cancel() self._dlg_progress.close() settings = get_settings() section = settings.add_section('gui') path = self._txt_outputdir.path() if path: section.outputdir = path section.maxworkers = str(self._spn_workers.value()) section.overwrite = str(self._chk_overwrite.isChecked()) settings.write() event.accept() def addAvailableOptions(self, options): self._lst_available.model().addOptions(options) def removeAvailableOptions(self, options): self._lst_available.model().removeOptions(options) def clearAvailableOptions(self): self._lbl_available.model().clearOptions() def start(self, outputdir, overwrite, max_workers): self._runner = LocalRunner(outputdir=outputdir, overwrite=overwrite, max_workers=max_workers) self._tbl_options.setModel(_StateOptionsTableModel(self._runner)) self._spn_workers.setEnabled(False) self._txt_outputdir.setEnabled(False) self._chk_overwrite.setEnabled(False) self._btn_addtoqueue.setEnabled(True) self._btn_addalltoqueue.setEnabled(True) self._btn_start.setEnabled(False) self._btn_cancel.setEnabled(True) self._btn_close.setEnabled(False) self._btn_import.setEnabled(True) self._runner.options_added.connect(self.options_added.emit) self._runner.options_running.connect(self.options_running.emit) self._runner.options_simulated.connect(self.options_simulated.emit) self._runner.options_error.connect(self.options_error.emit) self._runner.results_saved.connect(self.results_saved.emit) self._runner.results_error.connect(self.results_error.emit) self._running_timer.start() self._runner.start() def cancel(self): if self._runner is None: return self._runner.cancel() self._running_timer.stop() self._runner.options_added.disconnect(self.options_added.emit) self._runner.options_running.disconnect(self.options_running.emit) self._runner.options_simulated.disconnect(self.options_simulated.emit) self._runner.options_error.disconnect(self.options_error.emit) self._runner.results_saved.disconnect(self.results_saved.emit) self._runner.results_error.disconnect(self.results_error.emit) self._runner = None self._spn_workers.setEnabled(True) self._txt_outputdir.setEnabled(True) self._chk_overwrite.setEnabled(True) self._btn_addtoqueue.setEnabled(False) self._btn_addalltoqueue.setEnabled(False) self._btn_start.setEnabled(True) self._btn_cancel.setEnabled(False) self._btn_close.setEnabled(True) self._btn_import.setEnabled(False) def is_running(self): return self._runner is not None and self._runner.is_alive()
class PathEditor(QWidget): """ Custom widget with LineEdit and a Button to browse file """ editingFinished = Signal() def __init__(self, parent=None, index=None): super(PathEditor, self).__init__(parent) self.parent = parent self.index = index self.open_dialog_visible = False self.setFocusPolicy(Qt.StrongFocus) editor_layout = QHBoxLayout() editor_layout.setContentsMargins(0, 0, 0, 0) editor_layout.setSpacing(0) self.line_edit = LineEditor(self) editor_layout.addWidget(self.line_edit) self.button = QPushButton('') self.button.setIcon(QIcon(':/editor_folder')) self.button.setFixedSize(18, 17) self.button.setToolTip('Select a texture') self.button.setStatusTip('Select a texture') self.button.clicked.connect(self.select_file) editor_layout.addWidget(self.button) self.setFocusProxy(self.line_edit) self.setLayout(editor_layout) def setText(self, text): """ Set line edit text :param text: (string) text... """ self.line_edit.setText(text) def text(self): """ return line edit text """ return self.line_edit.text() def select_file(self): """ Maya Open Dialog to select file texture """ self.open_dialog_visible = True if MTTSettings.value('browserFirstStart'): image_dir = cmds.optionVar(query='MTT_browserStartFolder') else: image_dir = cmds.workspace(query=True, rootDirectory=True) + cmds.workspace( fileRuleEntry='sourceImages') MTTSettings.set_value('browserFirstStart', True) file_path = cmds.fileDialog2(fileMode=1, startingDirectory=image_dir, caption='Select a texture', okCaption='Select') if file_path: new_path = file_path[0] cmds.optionVar( sv=['MTT_browserStartFolder', os.path.dirname(new_path)]) if MTTSettings.value('forceRelativePath'): new_path = convert_to_relative_path(new_path) # relative_path = workspace(projectPath=new_path) # if relative_path != new_path: # new_path = '/%s' % relative_path self.line_edit.setText(new_path) self.open_dialog_visible = False self.close() self.editingFinished.emit() cmds.showWindow(WINDOW_NAME)
class CompareSequences(QMainWindow): def __init__(self): super(CompareSequences, self).__init__() self.setWindowTitle('Compare Sequences') self.setFixedHeight(125) self._ledit1 = QLineEdit() self._btn_pick_1 = QPushButton('...') self._ledit2 = QLineEdit() self._btn_pick_2 = QPushButton('...') self._btn_compare = QPushButton('Compare') self._progress_bar = QProgressBar(self.statusBar()) self._setup_ui() self._set_connections() def _compare(self): self._toggle_ui() src_one = self._ledit1.text() src_two = self._ledit2.text() # TODO: put in some checks for valid sequences if not (src_one and src_two): msg = 'Please pick proper sequences.' print msg nuke.message(msg) else: read1 = nuke.createNode('Read', inpanel=False) read1.knob('file').fromUserText(src_one) read2 = nuke.createNode('Read', inpanel=False) read2.knob('file').fromUserText(src_two) read2.setXYpos(read1.xpos() + 100, read1.ypos()) if not (read1.width() == read2.width() and read1.height() == read2.height()): msg = 'Sequences are not the same resolution.' print msg nuke.message(msg) else: # TODO: check for same resolution m = nuke.createNode('Merge2', inpanel=False) m.knob('operation').setValue(6) m.setXYpos(read1.xpos(), read2.ypos() + 100) m.setInput(0, read1) m.setInput(1, read2) c = nuke.createNode('CurveTool', inpanel=False) c.knob('operation').setValue(3) c.knob('ROI').fromDict( { 'x': 0, 'y': 0, 'r': read1.width(), 't': read1.height() } ) v = nuke.createNode('Viewer') check = False frame = None first = read1.knob('first').value() last = read1.knob('last').value() self._progress_bar.setRange(first, last) for i in range(first, last + 1): self._progress_bar.setValue(i) nuke.execute(c, i, i) data = c.knob('maxlumapixvalue').animations() check = False for curve in data: if not curve.constant(): check = True frame = i break if check: break if not check: msg = 'There is no difference.' else: msg = 'There is a difference at frame %d.' % frame nuke.message(msg) self._progress_bar.reset() self._toggle_ui() def _pick_sequence(self): btn = self.sender() le_btn_pair = { self._btn_pick_1: self._ledit1, self._btn_pick_2: self._ledit2 } clip_path = nuke.getClipname('Pick Sequence to compare') le_btn_pair[btn].setText(clip_path) def _set_connections(self): self._btn_pick_1.released.connect(self._pick_sequence) self._btn_pick_2.released.connect(self._pick_sequence) self._btn_compare.released.connect(self._compare) def _setup_ui(self): self._btn_pick_1.setFixedWidth(25) self._btn_pick_1.setToolTip('Pick first sequence.') self._btn_pick_2.setFixedWidth(25) self._btn_pick_2.setToolTip('Pick second sequence.') self._btn_compare.setToolTip('Compare sequences.') self._progress_bar.setFixedHeight(10) lyt_seq1 = QHBoxLayout() lyt_seq1.addWidget(self._ledit1) lyt_seq1.addWidget(self._btn_pick_1) lyt_seq2 = QHBoxLayout() lyt_seq2.addWidget(self._ledit2) lyt_seq2.addWidget(self._btn_pick_2) lyt_main = QVBoxLayout() lyt_main.addLayout(lyt_seq1) lyt_main.addLayout(lyt_seq2) lyt_main.addWidget(self._btn_compare) main_widget = QWidget() main_widget.setLayout(lyt_main) self.setCentralWidget(main_widget) def _toggle_ui(self): self._ledit1.setEnabled(not self._ledit1.isEnabled()) self._ledit2.setEnabled(not self._ledit2.isEnabled()) self._btn_pick_1.setEnabled(not self._btn_pick_1.isEnabled()) self._btn_pick_2.setEnabled(not self._btn_pick_2.isEnabled()) self._btn_compare.setEnabled(not self._btn_compare.isEnabled())
def __create_ui(self): """ Create main UI """ self.setWindowTitle(CREATE_NODE_TITLE) # remove window decoration if path and type is set if self.defined_path and self.defined_type: self.setWindowFlags(Qt.FramelessWindowHint | Qt.Popup) main_layout = QVBoxLayout(self) main_layout.setSpacing(1) main_layout.setContentsMargins(2, 2, 2, 2) # content layout content_layout = QVBoxLayout() self.files_model = QFileSystemModel() self.files_model.setNameFilterDisables(False) self.files_list = MTTFileList() self.files_list.setAlternatingRowColors(True) self.files_list.setSelectionMode(QAbstractItemView.ExtendedSelection) self.files_list.selectionValidated.connect(self.do_validate_selection) self.files_list.goToParentDirectory.connect(self.on_go_up_parent) self.files_list.doubleClicked.connect(self.on_double_click) self.files_list.setModel(self.files_model) buttons_layout = QHBoxLayout() content_layout.addLayout(self.__create_filter_ui()) content_layout.addWidget(self.files_list) content_layout.addLayout(buttons_layout) self.files_list.filter_line = self.filter_line if not self.defined_path: # path line path_layout = QHBoxLayout() # bookmark button bookmark_btn = QPushButton('') bookmark_btn.setFlat(True) bookmark_btn.setIcon(QIcon(':/addBookmark.png')) bookmark_btn.setToolTip('Bookmark this Folder') bookmark_btn.setStatusTip('Bookmark this Folder') bookmark_btn.clicked.connect(self.on_add_bookmark) # path line edit self.path_edit = QLineEdit() self.path_edit.editingFinished.connect(self.on_enter_path) # parent folder button self.parent_folder_btn = QPushButton('') self.parent_folder_btn.setFlat(True) self.parent_folder_btn.setIcon(QIcon(':/SP_FileDialogToParent.png')) self.parent_folder_btn.setToolTip('Parent Directory') self.parent_folder_btn.setStatusTip('Parent Directory') self.parent_folder_btn.clicked.connect(self.on_go_up_parent) # browse button browse_btn = QPushButton('') browse_btn.setFlat(True) browse_btn.setIcon(QIcon(':/navButtonBrowse.png')) browse_btn.setToolTip('Browse Directory') browse_btn.setStatusTip('Browse Directory') browse_btn.clicked.connect(self.on_browse) # parent widget and layout path_layout.addWidget(bookmark_btn) path_layout.addWidget(self.path_edit) path_layout.addWidget(self.parent_folder_btn) path_layout.addWidget(browse_btn) main_layout.addLayout(path_layout) # bookmark list bookmark_parent_layout = QHBoxLayout() bookmark_frame = QFrame() bookmark_frame.setFixedWidth(120) bookmark_layout = QVBoxLayout() bookmark_layout.setSpacing(1) bookmark_layout.setContentsMargins(2, 2, 2, 2) bookmark_frame.setLayout(bookmark_layout) bookmark_frame.setFrameStyle(QFrame.Sunken) bookmark_frame.setFrameShape(QFrame.StyledPanel) self.bookmark_list = MTTBookmarkList() self.bookmark_list.bookmarkDeleted.connect(self.do_delete_bookmark) self.bookmark_list.setAlternatingRowColors(True) self.bookmark_list.dragEnabled() self.bookmark_list.setAcceptDrops(True) self.bookmark_list.setDropIndicatorShown(True) self.bookmark_list.setDragDropMode(QListView.InternalMove) self.bookmark_list_sel_model = self.bookmark_list.selectionModel() self.bookmark_list_sel_model.selectionChanged.connect( self.on_select_bookmark) bookmark_layout.addWidget(self.bookmark_list) bookmark_parent_layout.addWidget(bookmark_frame) bookmark_parent_layout.addLayout(content_layout) main_layout.addLayout(bookmark_parent_layout) self.do_populate_bookmarks() else: main_layout.addLayout(content_layout) if not self.defined_type: # type layout self.types = QComboBox() self.types.addItems(self.supported_node_type) self.types.currentIndexChanged.connect(self.on_node_type_changed) if cmds.optionVar(exists='MTT_lastNodeType'): last = cmds.optionVar(query='MTT_lastNodeType') if last in self.supported_node_type: self.types.setCurrentIndex( self.supported_node_type.index(last)) buttons_layout.addWidget(self.types) if not self.defined_path or not self.defined_type: create_btn = QPushButton('C&reate') create_btn.clicked.connect(self.accept) cancel_btn = QPushButton('&Cancel') cancel_btn.clicked.connect(self.reject) buttons_layout.addStretch() buttons_layout.addWidget(create_btn) buttons_layout.addWidget(cancel_btn)
class MainWindow(QDialog): """monkey_linux UI""" def __init__(self,parent=None): super(MainWindow, self).__init__() self.init_conf() self.setParent(parent) common.Log.info("set up ui") self.setup_ui() self.findDeviceAction.triggered.connect(self.get_device_status) self.deleteDeviceAction.triggered.connect(self.del_device) # self.storeButton.clicked.connect(self.set_conf) self.startButton.clicked.connect(self.start) self.stopButton.clicked.connect(self.stop) self.checkLogButton.clicked.connect(self.check) self.monkeyButton.clicked.connect(self.checkMonkeyLog) self.exportButton.clicked.connect(self.exportConf) self.importButton.clicked.connect(self.importConf) self.setAbout.triggered.connect(self.about) self.startTime = datetime.datetime.now() self.secsTime = float(1) * 60 * 60 def setup_ui(self): # main window width hand height # self.setMinimumWidth(600) self.setMaximumWidth(800) self.setMinimumHeight(600) # main window title self.setWindowTitle(static.title) # file menu bar self.menuBar = QMenuBar() self.menuBar.setMaximumHeight(23) # self.menuFile = self.menuBar.addMenu(static.menuFile) # self.importAction = QAction(QIcon(static.importPNG), static.importFile, self) # self.exportAction = QAction(QIcon(static.exportPNG), static.exportFile, self) # self.menuFile.addAction(self.importAction) # self.menuFile.addAction(self.exportAction) self.setEnvActioin = QAction(QIcon(static.setPNG), static.pcSet, self) self.menuSet = self.menuBar.addMenu(static.menuSet) self.menuSet.addAction(self.setEnvActioin) self.setAbout = QAction(QIcon(static.setPNG), static.menuAbout, self) self.setAbout.setStatusTip('About') # 状态栏提示 self.menuHelp = self.menuBar.addMenu(static.menuHelp) self.menuHelp.addAction(self.setAbout) # set all layout self.hbox = QHBoxLayout(self) # device ======== self.topLeft = QFrame(self) self.topLeft.setMaximumSize(218, 300) self.topLeft.setMinimumSize(218, 200) self.topLeft.setFrameShape(QFrame.StyledPanel) self.topLeftLayout = QVBoxLayout(self.topLeft) self.toolBar = QToolBar() # self.androidDeviceAction = QRadioButton('Android', self) # self.androidDeviceAction.setFocusPolicy(Qt.NoFocus) # self.ipDeviceAction = QRadioButton('IP', self) # self.ipDeviceAction.setFocusPolicy(Qt.NoFocus) # self.ipDeviceAction.move(10, 10) # self.ipDeviceAction.toggle() self.findDeviceAction = QAction(QIcon(static.findDevice), static.findDeviceButton, self) self.deleteDeviceAction = QAction(QIcon(static.deleteDevice), static.deleteDeviceButton, self) # self.toolBar.addWidget(self.androidDeviceAction) # self.toolBar.addWidget(self.ipDeviceAction) self.toolBar.addAction(self.findDeviceAction) self.toolBar.addAction(self.deleteDeviceAction) self.deviceLab = QLabel(static.deviceName, self) self.device = QTableWidget(1, 2) self.device.setHorizontalHeaderLabels(['name', 'status']) self.device.setColumnWidth(0, 100) self.device.setColumnWidth(1, 80) self.topLeftLayout.addWidget(self.deviceLab) self.topLeftLayout.addWidget(self.toolBar) self.topLeftLayout.addWidget(self.device) # set button or other for running monkey or not and status of device and log ======== self.topRight = QFrame(self) self.topRight.setFrameShape(QFrame.StyledPanel) self.topRight.setMaximumHeight(40) self.startButton = QPushButton(QIcon(static.startPNG), "") self.stopButton = QPushButton(QIcon(static.stopPNG), "") self.status = QLabel(static.status) self.statusEdit = QLineEdit(self) self.statusEdit.setReadOnly(True) self.statusEdit.setMaximumWidth(80) self.statusEdit.setMinimumWidth(80) self.statusEdit.setText("") # check log self.checkLogButton = QPushButton(static.checkLog) self.checkLogButton.setMaximumHeight(20) self.checkLogButton.setMinimumHeight(20) self.checkLogButton.setMaximumWidth(60) self.selectLog = QLabel(static.selectlog) self.logfile = QComboBox() self.dirlist = os.listdir(os.path.join(DIR, "Result")) for d in self.dirlist: if d != "AutoMonkey.log": self.logfile.insertItem(0, d) self.logfile.setMaximumWidth(150) self.logfile.setMaximumHeight(20) self.logfile.setMinimumHeight(20) self.topLayout = QHBoxLayout(self.topRight) self.topLayout.addWidget(self.startButton) self.topLayout.addWidget(self.stopButton) self.topLayout.addWidget(self.status) self.topLayout.addWidget(self.statusEdit) self.topLayout.addWidget(self.selectLog) self.topLayout.addWidget(self.logfile) self.topLayout.addWidget(self.checkLogButton) # set parameter for monkey ======= self.midRight = QFrame(self) self.midRight.setMaximumSize(555, 200) self.midRight.setMinimumSize(555, 200) self.midRight.setFrameShape(QFrame.StyledPanel) self.midRightLayout = QVBoxLayout(self.midRight) self.subLayout0 = QVBoxLayout() self.subLayout1 = QVBoxLayout() self.subLayout2 = QHBoxLayout() self.subLayout3 = QVBoxLayout() self.subLayout4 = QVBoxLayout() self.subLayout5 = QHBoxLayout() self.subLayout6 = QHBoxLayout() self.toolBar = QToolBar() # self.storeAction = QAction(QIcon(static.storePNG), static.storeButton, self) self.startAction = QAction(QIcon(static.startPNG), static.startButton, self) self.stopAction = QAction(QIcon(static.stopPNG), static.stopButton, self) # self.toolBar.addAction(self.storeAction) self.toolBar.addAction(self.startAction) self.toolBar.addAction(self.stopAction) self.timeLongLbl = QLabel(static.timeString, self) self.timeLong = QLineEdit(self) self.timeLong.setMaximumWidth(100) self.timeLong.setMinimumWidth(100) self.timeLong.setPlaceholderText(static.timeLong) self.timeLongUnit = QLabel("H") self.etSetLbl = QLabel(static.eventTypeSet) self.etSet = QTableWidget(2, 2) self.etSet.setMaximumHeight(150) self.etSet.setHorizontalHeaderLabels(['option', 'value']) self.etSet.horizontalHeader().setStretchLastSection(True) self.etSet.setItem(0, 0, QTableWidgetItem("--throttle")) self.etSet.setItem(0, 1, QTableWidgetItem(str(static.eventType["--throttle"]))) # set event type percent self.etPercentLbl = QLabel(static.eventTpyePercent, self) self.etPercent = QTableWidget(2, 2) self.etPercent.setMaximumHeight(150) self.etPercent.setHorizontalHeaderLabels(['option', 'value']) self.etPercent.horizontalHeader().setStretchLastSection(True) self.etPercent.setItem(0, 0, QTableWidgetItem("--pct-touch")) self.etPercent.setItem(0, 1, QTableWidgetItem(str(static.eventPercent["--pct-touch"]))) self.etPercent.setItem(1, 0, QTableWidgetItem("--pct-motion")) self.etPercent.setItem(1, 1, QTableWidgetItem(str(static.eventPercent["--pct-motion"]))) # self.storeButton = QPushButton(QIcon(static.storePNG), static.storeButton) # self.storeButton.setToolTip(static.storeButton) self.exportButton = QPushButton(QIcon(static.exportPNG), static.exportFile) self.exportButton.setToolTip(static.exportFile) self.importButton = QPushButton(QIcon(static.importPNG), static.importFile) self.importButton.setToolTip(static.importFile) self.subLayout2.addWidget(self.timeLongLbl) self.subLayout2.addWidget(self.timeLong) self.subLayout2.addWidget(self.timeLongUnit) self.subLayout2.addWidget(QLabel(" " * 300)) # self.subLayout2.addWidget(self.storeButton) self.subLayout2.addWidget(self.exportButton) self.subLayout2.addWidget(self.importButton) self.subLayout0.addLayout(self.subLayout2) self.subLayout3.addWidget(self.etSetLbl) self.subLayout3.addWidget(self.etSet) self.subLayout4.addWidget(self.etPercentLbl) self.subLayout4.addWidget(self.etPercent) self.subLayout5.addLayout(self.subLayout0) self.subLayout6.addLayout(self.subLayout3) self.subLayout6.addLayout(self.subLayout4) self.midRightLayout.addLayout(self.subLayout5) self.midRightLayout.addLayout(self.subLayout6) # log ======== self.bottom = QFrame(self) self.bottom.setFrameShape(QFrame.StyledPanel) # log information self.logInfo = QLabel(static.logInfo) # information filter self.logFilter = QLabel(static.logFilter) self.monkeyButton = QPushButton(static.openMonkeyLog) self.combo = QComboBox() for i in range(len(static.logLevel)): self.combo.addItem(static.logLevel[i]) self.combo.setMaximumWidth(55) self.combo.setMaximumHeight(20) self.combo.setMinimumHeight(20) # information details self.bottomLayout = QVBoxLayout(self.bottom) self.subLayout = QHBoxLayout() self.subLayout.addWidget(self.logInfo) for i in range(10): self.subLayout.addWidget(QLabel("")) self.subLayout.addWidget(self.monkeyButton) self.subLayout.addWidget(self.logFilter) self.subLayout.addWidget(self.combo) self.bottomLayout.addLayout(self.subLayout) self.tabwidget = TabWidget() self.tabwidget.setMinimumHeight(100) self.bottomLayout.addWidget(self.tabwidget) # splitter mainWindow ++++++++++++++++++++++++++++++++++++ self.splitter2 = QSplitter(Qt.Vertical) self.splitter2.addWidget(self.topRight) self.splitter2.addWidget(self.midRight) self.splitter0 = QSplitter(Qt.Horizontal) self.splitter0.addWidget(self.topLeft) self.splitter0.addWidget(self.splitter2) self.splitter1 = QSplitter(Qt.Vertical) self.splitter1.addWidget(self.menuBar) self.splitter1.addWidget(self.splitter0) self.splitter1.addWidget(self.bottom) self.hbox.addWidget(self.splitter1) self.setLayout(self.hbox) self.show() def about(self): common.showDialog(static.menuAbout, static.dialogAbout) def init_conf(self): common.Log.info("init monkey conf") with open(monkeyConfFile, "w") as f: f.write("deviceList = []" + "\n") f.write("times = " + static.times + "\n") f.write("--throttle = " + static.eventType["--throttle"] + "\n") f.write("--pct-touch = " + static.eventPercent["--pct-touch"] + "\n") f.write("--pct-motion = " + static.eventPercent["--pct-motion"] + "\n") def setup_env(self): pass def _set_eventType(self, confFile): try: option = self.etSet.item(0, 0).text() value = self.etSet.item(0, 1).text() if value > "0": with open(confFile, 'a+') as f: f.write(option + " = " + value + "\n") except AttributeError, e: pass
class NewWindow(QWidget): def __init__(self, app=None): super(NewWindow, self).__init__() self.app = app glo = QVBoxLayout(self) if os.name == 'nt': icp = r_path('static\\images\\favicon.png') else: icp = r_path('static/images/favicon.png') # need to used objective message boxs instead of functions to set font self.Arial = QFont("", 15, QFont.Bold) self.Arials = QFont("", 10, QFont.Bold) # Language support varibels used by translate func self.Arabic = None self.Runningo = False icon = QIcon(icp) self.SelfIinit(icon) self.center() self.Llists(glo) self.set_Abutton(icp, glo) self.Lists(glo) self.Flabel(glo) self.set_button(glo) self.setLayout(glo) mip = self.slchange() self.P = rwser(mip[1].split(',')[1], mip[0], self.app) self.activateWindow() self.show() def SelfIinit(self, icon): self.setWindowTitle('Free Queue Manager ' + version) self.setGeometry(300, 300, 200, 150) self.setMinimumWidth(500) self.setMaximumWidth(500) self.setMinimumHeight(400) self.setMaximumHeight(400) # Setting Icon self.setWindowIcon(icon) QToolTip.setFont(self.Arials) def Flabel(self, glo): fontt = self.Arial if os.name == 'nt': self.ic1 = QIcon(r_path('static\\images\\pause.png')) else: self.ic1 = QIcon(r_path('static/images/pause.png')) self.l = QLabel('Icond', self) self.ic1 = self.ic1.pixmap(70, 70, QIcon.Active, QIcon.On) self.l.setPixmap(self.ic1) self.l.setAlignment(Qt.AlignCenter | Qt.AlignHCenter) self.l.setFont(fontt) self.t = QLabel('Texted', self) self.t.setText("Server is <u> Not running </u> <br>") self.t.setOpenExternalLinks(True) self.t.setAlignment(Qt.AlignCenter | Qt.AlignHCenter) self.t.setFont(fontt) self.t.setToolTip('Status of the server') self.l.setToolTip('Status of the server') glo.addStretch() glo.addWidget(self.l) glo.addWidget(self.t) glo.addStretch() def Lists(self, glo): ips = self.get_ips() self.sl = QComboBox() self.sl.addItems(ips) self.sl.setToolTip( 'Select network interface with ip, so the server runs on it') self.sl2 = QComboBox() self.get_ports() self.sl2.setToolTip('Select a port, so server runs through it') self.sl.currentIndexChanged.connect(self.get_ports) glo.addWidget(self.sl) glo.addWidget(self.sl2) def get_ports(self, nauto=True): d_ports = ['5000', '8080', '3000', '80', '9931'] m_ports = [] while len(m_ports) < 10: mip = self.slchange() for p in d_ports: s = socket(AF_INET, SOCK_STREAM) try: s.bind((mip[1].split(',')[1], int(p))) s.close() m_ports.append(p) except: s.close() d_ports.remove(p) s = socket(AF_INET, SOCK_STREAM) p = randint(1000, 9999) try: s.bind((mip[1].split(',')[1], p)) s.close() m_ports.append(str(p)) except: s.close() if len(m_ports) >= 10: break self.sl2.clear() self.sl2.addItems(m_ports) def Llists(self, glo): hlayout = QHBoxLayout() self.lebutton = QPushButton('English', self) self.lebutton.setToolTip('Change language to English') self.lebutton.setEnabled(False) self.lebutton.setFont(self.Arials) self.labutton = QPushButton('Arabic', self) self.labutton.setFont(self.Arials) if os.name == 'nt': self.lebutton.setIcon( QPixmap(r_path('static\\images\\english.png'))) self.labutton.setIcon(QPixmap( r_path('static\\images\\arabic.png'))) else: self.lebutton.setIcon(QPixmap(r_path('static/images/english.png'))) self.labutton.setIcon(QPixmap(r_path('static/images/arabic.png'))) self.labutton.setToolTip('Change language to Arabic') self.labutton.setEnabled(True) self.lebutton.clicked.connect(partial(self.translate, ar=False)) self.labutton.clicked.connect(self.translate) hlayout.addWidget(self.lebutton) hlayout.addWidget(self.labutton) glo.addLayout(hlayout) def slchange(self): return [self.sl2.currentText(), self.sl.currentText()] def set_button(self, glo): hlayout = QHBoxLayout() self.mbutton = QPushButton('Start', self) self.mbutton.clicked.connect(self.s_server) self.mbutton.setFont(self.Arials) if os.name == 'nt': self.mbutton.setIcon(QPixmap(r_path('static\\images\\play.png'))) else: self.mbutton.setIcon(QPixmap(r_path('static/images/play.png'))) self.mbutton2 = QPushButton('Stop', self) self.mbutton2.clicked.connect(self.st_server) if os.name == 'nt': self.mbutton2.setIcon(QPixmap(r_path('static\\images\\pause.png'))) else: self.mbutton2.setIcon(QPixmap(r_path('static/images/pause.png'))) self.mbutton.setToolTip('Start the server') self.mbutton2.setToolTip('Stop the server') self.mbutton2.setEnabled(False) self.mbutton2.setFont(self.Arials) hlayout.addWidget(self.mbutton) hlayout.addWidget(self.mbutton2) glo.addLayout(hlayout) def s_server(self): mip = self.slchange() self.P = rwser(mip[1].split(',')[1], mip[0], self.app) self.P.setTerminationEnabled(True) if not self.P.isRunning(): try: self.pport = mip[0] self.mbutton.setEnabled(False) self.mbutton2.setEnabled(True) self.sl.setEnabled(False) self.sl2.setEnabled(False) if os.name == 'nt': self.ic1 = QIcon(r_path('static\\images\\play.png')) else: self.ic1 = QIcon(r_path('static/images/play.png')) self.ic1 = self.ic1.pixmap(70, 70, QIcon.Active, QIcon.On) self.l.setPixmap(self.ic1) if self.Arabic is None: pp = self.slchange() addr = "Server is <u>Running</u> <br>" addr += " On : <a href='http://" addr += pp[1].split(',')[1] + ":" + pp[0] addr += "'> http://" + pp[1].split(',')[1] + ":" + pp[0] addr += "</a>" self.t.setText(addr) self.t.setFont(self.Arial) else: pp = self.slchange() addr = u"الخدمة <u>مشغــلة</u> و تبث على : <br>" addr += u"<a href='http://" addr += pp[1].split(',')[1] + u":" + pp[0] addr += u"'> http://" + pp[1].split(',')[1] + u":" + pp[0] addr += u"</a>" self.t.setText(addr) self.t.setFont(self.Arial) self.P.start() self.Runningo = True except: self.eout() else: self.eout() def st_server(self): if self.P.isRunning(): try: if self.P.isRunning: self.P.stop() self.mbutton.setEnabled(True) self.mbutton2.setEnabled(False) self.sl.setEnabled(True) self.sl2.setEnabled(True) if self.Arabic is None: self.t.setText("Server is <u> Not running </u> <br>") else: self.t.setText(u"الــخـدمة <u>متــوقفــة</u><br>") # removing the last used port to avoid termination error cind = self.sl2.currentIndex() self.sl2.removeItem(cind) self.get_ports() self.Runningo = False except: self.eout() else: self.eout() def set_Abutton(self, icon, glo): def show_about(nself): if nself.Arabic is None: Amsg = "<center>All credit reserved to the author of FQM " Amsg += " version " + version Amsg += ", This work is a free, open-source project licensed " Amsg += " under Mozilla Public License version 2.0 . <br><br>" Amsg += " visit us for more infos and how-tos :<br> " Amsg += "<b><a href='https://fqms.github.io/'> " Amsg += "https://fqms.github.io/ </a> </b></center>" Amsgb = "About FQM" else: Amsg = u" <center> " Amsg += u" إدارة الحشود الحر النسخة " + version + u" " Amsg += u"حقوق نشر هذا البرنامج محفوظة و تخضع " Amsg += u" لرخصة البرامج الحرة و مفتوحة المصدر " Amsg += u" Mozilla Public License version 2.0 . " Amsg += u"<br><br> " Amsg += u"للمزيد من المعلومات و الشروحات , قم بزيارة :" Amsg += u"<br> <b><a href='https://fqms.github.io/'>" Amsg += u"https://fqms.github.io </a> </b></center>" Amsgb = u"عن النظام" return QMessageBox.about(self, Amsgb, Amsg) self.abutton = QPushButton('', self) self.abutton.setIcon(QPixmap(icon)) self.abutton.setIconSize(QSize(150, 70)) self.abutton.setToolTip('About FQM') self.abutton.clicked.connect(partial(show_about, self)) glo.addWidget(self.abutton) def closeEvent(self, event=None): if self.Runningo: if self.Arabic is None: response = self.msgApp( "Exiting while running", "Are you really sure, you want to exit ?") else: response = self.msgApp( u"تأكيد الخروج", u"تريد بالفعل , الخروج و إيقاف البرنامج ؟") if response == 'y': if event is not None: event.accept() if self.P.isRunning(): self.P.stop() sys.exit(0) else: if event is not None: event.ignore() else: if event is not None: event.accept() if self.P.isRunning(): self.P.stop() sys.exit(0) def msgApp(self, title, msg): uinfo = QMessageBox.question(self, title, msg, QMessageBox.Yes | QMessageBox.No) if uinfo == QMessageBox.Yes: return 'y' if uinfo == QMessageBox.No: return 'n' def eout(self): if self.P.isRunning(): self.P.stop() if self.Arabic is None: msgg = "<center>" msgg += " Opps, a critical error has occurred, we will be " msgg += " grateful if you can help fixing it, by reporting to us " msgg += " at : <br><br> " msgg += "<b><a href='https://fqms.github.io/'> " msgg += "https://fqms.github.io/ </a></b> </center>" mm = QMessageBox.critical(self, "Critical Error", msgg, QMessageBox.Ok) else: msgg = u"<center>" msgg += u"حدث خطأ فادح في تشغيل النظام , سنكون شاكرين لك إن " msgg += u"قمت بتبليغنا عنه , ليتم إصلاحه في أقرب وقت " msgg += u"<br>" msgg += u"<br><b><a href='https://fqms.github.io/'> " msgg += u"https://fqms.github.io </a></b> </center>" mm = QMessageBox.critical(self, u"خطأ في التشغيل", msgg, QMessageBox.Ok) def center(self): qrect = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qrect.moveCenter(cp) self.move(qrect.topLeft()) def get_ips(self): il = [] for i in interfaces(): try: if os.name != 'nt': inf = i + " ," else: inf = ' ,' inf += ifaddresses(i)[2][0].get('addr') il.append(inf) except: pass return il def translate(self, ar=True): if ar: self.Arabic = "arabic" self.labutton.setEnabled(False) self.labutton.setText(u"العربية") self.labutton.setToolTip(u"تغير اللغة إلى العربية") self.lebutton.setText(u"الإنجليزية") self.lebutton.setToolTip(u"تغير اللغة إلى الإنجليزية") self.lebutton.setEnabled(True) self.Amsgb = u"عن النظام" self.abutton.setToolTip(u"عن النظام") self.mbutton.setText(u"تشغــيل") self.mbutton.setToolTip(u"تشغيل الخدمة") self.mbutton2.setText(u"إيــقاف") self.mbutton2.setToolTip(u"إيقاف الخدمة") self.sl.setToolTip(u"إختار عنوان IP ليتم بث الخدمة عليه") self.sl2.setToolTip(u"إختار منفذ ليتم بث الخدمة من خلاله") self.t.setToolTip(u"حالة الخدمة ") self.l.setToolTip(u"حالة الخدمة ") if self.Runningo: pp = self.slchange() addr = u"الخدمة <u>مشغــلة</u> و تبث على : <br>" addr += u"<a href='http://" addr += pp[1].split(',')[1] + u":" + pp[0] addr += u"'> http://" + pp[1].split(',')[1] + u":" + pp[0] addr += u"</a>" self.t.setText(addr) else: self.t.setText(u"الــخـدمة <u>متــوقفــة</u><br>") else: self.Arabic = None self.lebutton.setEnabled(False) self.lebutton.setText("English") self.lebutton.setToolTip('Change language to English') self.labutton.setEnabled(True) self.labutton.setText("Arabic") self.labutton.setToolTip('Change language to Arabic') self.Amsgb = "About FQM" self.abutton.setToolTip('About FQM') self.mbutton.setText("Start") self.mbutton.setToolTip("Start the server") self.mbutton2.setText("Stop") self.mbutton2.setToolTip("Stop the server") self.sl.setToolTip( 'Select network interface with ip, so the server runs on it') self.sl2.setToolTip('Select a port, so server runs through it') self.t.setToolTip('Status of the server') self.l.setToolTip('Status of the server') if self.Runningo: pp = self.slchange() addr = "Server is <u>Running</u> <br>" addr += " On : <a href='http://" addr += pp[1].split(',')[1] + ":" + pp[0] addr += "'> http://" + pp[1].split(',')[1] + ":" + pp[0] addr += "</a>" self.t.setText(addr) else: self.t.setText("Server is <u> Not running </u> <br>")
class Deformation_GUI(QWidget): #Initialize the variable def __init__(self, oriPath, protoPath, oriPointsPath, protoPointsPath, regionsPath): super(Deformation_GUI, self).__init__() localParas, points = preprocess(oriPath, protoPath, oriPointsPath, protoPointsPath, regionsPath, 'L2') self.oriImg, self.protoImg, self.regionsPoints, self.is_in_regions_fun, self.distance_funs, self.affine_funs = localParas self.oriPlotDict, self.protoPlotDict, self.oriPoints, self.protoPoints = points self.oriPoints = np.array(self.oriPoints) self.protoPoints = np.array(self.protoPoints) self.e = 2 self.alpha = 1 self.oriPath = oriPath self.protoPath = protoPath self.oriPointsPath = '' self.protoPointsPath = '' self.regionsPath = regionsPath self.transform = 'Morphing' self.newImg = None self.initUI() #Initialize the GUI def initUI(self): #Set Window QToolTip.setFont(QFont('Serif', 10)) self.setGeometry(280, 210, 800, 450) self.setWindowTitle('Image Registration Based on Control Points') #Set Algorithm self.comboAffineLabel = QLabel(self) self.comboAffineLabel.setText('Algorithm:') self.comboAffineLabel.setGeometry(60, 270, 230, 30) self.comboAffine = QComboBox(self) self.comboAffine.addItem("Morphing") self.comboAffine.addItem("Local Affine Transformation") self.comboAffine.addItem("Moving Least Squares") self.comboAffine.setGeometry(22, 290, 225, 30) self.comboAffine.activated[str].connect(self.affineChoiceChange) #Choose Human Face Image self.oriBtn = QPushButton('Human Face Image', self) self.oriBtn.setToolTip('Human Face Image') self.oriBtn.setGeometry(20, 330, 230, 30) self.oriBtn.clicked.connect(self.showOriDialog) #Choose Ape or another Human image self.protoBtn = QPushButton('Ape or Human image', self) self.protoBtn.setToolTip('Ape or Human image') self.protoBtn.setGeometry(310, 330, 230, 30) self.protoBtn.clicked.connect(self.showProtoDialog) #parameter e self.eLabel = QLabel(self) self.eLabel.setText('E Value:0.00') self.eLabel.setGeometry(550, 300, 200, 30) self.eSld = QSlider(Qt.Horizontal, self) self.eSld.setRange(0, 10**5) self.eSld.setFocusPolicy(Qt.NoFocus) self.eSld.setGeometry(550, 330, 120, 30) self.eSld.valueChanged[int].connect(self.changeEValue) #parameter alpha self.aLabel = QLabel(self) self.aLabel.setText('Alpha Value:0.00') self.aLabel.setGeometry(680, 300, 200, 30) self.aSld = QSlider(Qt.Horizontal, self) self.aSld.setRange(0, 10**5) self.aSld.setFocusPolicy(Qt.NoFocus) self.aSld.setGeometry(680, 330, 100, 30) self.aSld.valueChanged[int].connect(self.changeAlphaValue) # The Image self.oriTextLabel = QLabel(self) self.protoTextLabel = QLabel(self) self.transTextLabel = QLabel(self) self.oriTextLabel.setText('The Human Image') self.protoTextLabel.setText('The Ape or another Human Image') self.transTextLabel.setText('Deformation Image') self.oriTextLabel.move(70, 5) self.protoTextLabel.move(350, 5) self.transTextLabel.move(580, 5) self.oriLabel = QLabel(self) self.protoLabel = QLabel(self) self.transLabel = QLabel(self) pixmap = QPixmap(self.oriPath) pixmap2 = QPixmap(self.protoPath) self.oriLabel.setPixmap(pixmap) self.protoLabel.setPixmap(pixmap2) self.transLabel.setPixmap(pixmap) #Set Position self.oriLabel.setGeometry(20, 20, 230, 230) self.protoLabel.setGeometry(290, 20, 230, 230) self.transLabel.setGeometry(560, 20, 230, 230) self.oriLabel.setScaledContents(True) self.protoLabel.setScaledContents(True) self.transLabel.setScaledContents(True) #import points self.loadOriBtn = QPushButton('Deformed Points', self) self.loadOriBtn.setToolTip('Load Control Points From Txt File') self.loadOriBtn.setGeometry(20, 365, 230, 30) self.loadOriBtn.clicked.connect(self.showLoadOriDialog) self.loadProtoBtn = QPushButton('Control Points', self) self.loadProtoBtn.setToolTip('Load Control Points From Txt File') self.loadProtoBtn.setGeometry(310, 365, 230, 30) self.loadProtoBtn.clicked.connect(self.showLoadProtoDialog) #Deformed self.confirmBtn = QPushButton('Deformed', self) self.confirmBtn.setToolTip('Deformed') self.confirmBtn.setGeometry(580, 365, 150, 30) self.confirmBtn.clicked.connect(self.transformAction) self.show() #Deformed Generate def transformAction(self): try: #three algorithm if self.transform == 'Morphing': self.oriImg = np.array(Image.open(self.oriPath)) self.protoImg = np.array(Image.open(self.protoPath)) newImg = morphingAction((self.oriPath).encode('utf-8'), self.protoPath.encode('utf-8'), self.oriPointsPath.encode('utf-8'), self.protoPointsPath.encode('utf-8'), self.alpha) else: localParas, points = preprocess(self.oriPath, self.protoPath, self.oriPointsPath, self.protoPointsPath, self.regionsPath, 'L2') if points == None: QtGui.QMessageBox.information(self, "Error", localParas) return self.oriImg, self.protoImg, self.regionsPoints, self.is_in_regions_fun, self.distance_funs, self.affine_funs = localParas self.oriPlotDict, self.protoPlotDict, self.oriPoints, self.protoPoints = points if self.oriImg.shape[len(self.oriImg.shape) - 1] != self.protoImg.shape[ len(self.protoImg.shape) - 1]: QtGui.QMessageBox.information( self, "Error", "The type of the figures is not the same, please choose another figure" ) return if self.transform == 'Local Affine Transformation': newImg = local_affine(self.oriImg, self.protoImg, self.e, self.regionsPoints, self.is_in_regions_fun, self.distance_funs, self.affine_funs) elif self.transform == "Moving Least Squares": newImg = MLS(self.oriImg, self.protoImg, self.oriPoints, self.protoPoints, self.alpha) except BaseException: QtGui.QMessageBox.information( self, "Error", "There are error in the point choice or other things.") newImg = morphingAction((self.oriPath).encode('utf-8'), self.protoPath.encode('utf-8'), self.oriPointsPath.encode('utf-8'), self.protoPointsPath.encode('utf-8'), self.alpha) self.newImg = np.uint8(newImg) newImg = rgb2bgr(np.uint8(newImg)) qimage = QImage(newImg, newImg.shape[1], newImg.shape[0], QImage.Format_ARGB32) pixmap_array = QPixmap.fromImage(qimage) self.transLabel.setPixmap(pixmap_array) def showProtoDialog(self): fname, _ = QtGui.QFileDialog.getOpenFileName( self, 'Open file', '/home', "Image Files (*.png *.jpg *.bmp)") if fname != None and fname != '': self.protoPath = fname self.protoLabel.setPixmap(QPixmap(self.protoPath)) def showLoadOriDialog(self): fname, _ = QtGui.QFileDialog.getOpenFileName(self, 'Open file', '/home', "Text files (*.txt)") if fname != None and fname != '': self.oriPointsPath = fname def showLoadProtoDialog(self): fname, _ = QtGui.QFileDialog.getOpenFileName(self, 'Open file', '/home', "Text files (*.txt)") if fname != None and fname != '': self.protoPointsPath = fname else: self.protoPointsPath = '' def showOriDialog(self): fname, _ = QtGui.QFileDialog.getOpenFileName( self, 'Open file', '/home', "Image Files (*.png *.jpg *.bmp)") if fname != None and fname != '': self.oriPath = fname print(self.oriPath) self.oriLabel.setPixmap(QPixmap(self.oriPath)) #e value in Local Affine Algorithm def changeEValue(self, x): self.e = 4.0 * x / 10**5 self.eLabel.setText('E Value:' + str('%.2f' % self.e)) #alpha value in MLS and Morphing Algorithm #the alpha range is different def changeAlphaValue(self, x): if self.transform == 'Moving Least Squares': self.alpha = 2.0 * x / 10**5 elif self.transform == 'Morphing': self.alpha = 1.0 * x / 10**5 self.aLabel.setText('Alpha Value:' + str('%.2f' % self.alpha)) # 3 Algorithm def affineChoiceChange(self, item): if self.transform in ['Moving Least Squares', 'Morphing'] and item in [ 'Moving Least Squares', 'Morphing' ] and item != self.transform: self.alpha = 0.0 self.aSld.setValue(self.alpha) self.transform = item
class NodeLister(QFrame): def __init__(self): super(NodeLister, self).__init__() self.setWindowTitle('Node Lister') self._btn_refresh = QPushButton('Refresh') self._btn_expand = QPushButton('Expand/Collapse') self._tree = NodeTree() self._ledit_search = QLineEdit() self._expand_state = False self._setup_ui() self._set_connections() def _expand_toggle(self): self._expand_state = not self._expand_state if self._expand_state: self._tree.expandAll() else: self._tree.collapseAll() def _filter_list(self): search_strings = str(self._ledit_search.text()).split() proxy = self._tree.model() model = proxy.sourceModel() show_rows = list() node_rows = list() rows = model.get_rows() class_rows = filter(lambda x: type(x) == ClassRow, rows) for class_row in class_rows: node_rows.extend(class_row.get_node_rows()) for row in class_rows + node_rows: item = row.first_item() index = model.indexFromItem(item) proxy_index = proxy.mapFromSource(index) self._tree.setRowHidden(proxy_index.row(), proxy_index.parent(), False) if search_strings: for search_item in search_strings: for row in node_rows: if search_item.strip().lower() in row.get_item('Node').text().lower(): show_rows.append(row) self._tree.expandAll() self._expand_state = True show_class_rows = list(set(map(lambda x: x.get_parent_class_row(), show_rows))) for row in node_rows: if row not in show_rows: item = row.first_item() index = model.indexFromItem(item) proxy_index = proxy.mapFromSource(index) self._tree.setRowHidden(proxy_index.row(), proxy_index.parent(), True) for row in class_rows: if row not in show_class_rows: item = row.first_item() index = model.indexFromItem(item) proxy_index = proxy.mapFromSource(index) self._tree.setRowHidden(proxy_index.row(), proxy_index.parent(), True) else: self._tree.collapseAll() self._expand_state = False def _refresh(self): model = self._tree.model().sourceModel() nodes = nuke.allNodes() node_dict = {} for node in nodes: if node.Class() not in node_dict.keys(): node_dict[node.Class()] = [] node_dict[node.Class()].append(node) model.clear_rows() model.populate(node_dict) def _set_connections(self): self._btn_refresh.released.connect(self._refresh) self._ledit_search.textChanged.connect(self._filter_list) self._btn_expand.released.connect(self._expand_toggle) def _setup_ui(self): self._btn_refresh.setIcon(QIcon(':qrc/images/Refresh.png')) self._btn_refresh.setToolTip('Populate tree with nodes') self._btn_expand.setToolTip('Toggle expanding and collapsing the tree') self._ledit_search.setToolTip('Search by node name') lyt_refresh = QHBoxLayout() lyt_refresh.addWidget(self._btn_refresh) lyt_refresh.addWidget(self._btn_expand) lyt_search = QHBoxLayout() lbl_search = QLabel('Name Search') lyt_search.addWidget(lbl_search) lyt_search.addWidget(self._ledit_search) lyt_main = QVBoxLayout() lyt_main.addLayout(lyt_refresh) lyt_main.addWidget(self._tree) lyt_main.addLayout(lyt_search) self.setLayout(lyt_main)
def __create_ui(self): """ Create main UI """ self.setWindowTitle(CREATE_NODE_TITLE) # remove window decoration if path and type is set if self.defined_path and self.defined_type: self.setWindowFlags(Qt.FramelessWindowHint | Qt.Popup) main_layout = QVBoxLayout(self) main_layout.setSpacing(1) main_layout.setContentsMargins(2, 2, 2, 2) # content layout content_layout = QVBoxLayout() self.files_model = QFileSystemModel() self.files_model.setNameFilterDisables(False) self.files_list = MTTFileList() self.files_list.setAlternatingRowColors(True) self.files_list.setSelectionMode(QAbstractItemView.ExtendedSelection) self.files_list.selectionValidated.connect(self.do_validate_selection) self.files_list.goToParentDirectory.connect(self.on_go_up_parent) self.files_list.doubleClicked.connect(self.on_double_click) self.files_list.setModel(self.files_model) buttons_layout = QHBoxLayout() content_layout.addLayout(self.__create_filter_ui()) content_layout.addWidget(self.files_list) content_layout.addLayout(buttons_layout) self.files_list.filter_line = self.filter_line if not self.defined_path: # path line path_layout = QHBoxLayout() # bookmark button bookmark_btn = QPushButton('') bookmark_btn.setFlat(True) bookmark_btn.setIcon(QIcon(':/addBookmark.png')) bookmark_btn.setToolTip('Bookmark this Folder') bookmark_btn.setStatusTip('Bookmark this Folder') bookmark_btn.clicked.connect(self.on_add_bookmark) # path line edit self.path_edit = QLineEdit() self.path_edit.editingFinished.connect(self.on_enter_path) # parent folder button self.parent_folder_btn = QPushButton('') self.parent_folder_btn.setFlat(True) self.parent_folder_btn.setIcon( QIcon(':/SP_FileDialogToParent.png')) self.parent_folder_btn.setToolTip('Parent Directory') self.parent_folder_btn.setStatusTip('Parent Directory') self.parent_folder_btn.clicked.connect(self.on_go_up_parent) # browse button browse_btn = QPushButton('') browse_btn.setFlat(True) browse_btn.setIcon(QIcon(':/navButtonBrowse.png')) browse_btn.setToolTip('Browse Directory') browse_btn.setStatusTip('Browse Directory') browse_btn.clicked.connect(self.on_browse) # parent widget and layout path_layout.addWidget(bookmark_btn) path_layout.addWidget(self.path_edit) path_layout.addWidget(self.parent_folder_btn) path_layout.addWidget(browse_btn) main_layout.addLayout(path_layout) # bookmark list bookmark_parent_layout = QHBoxLayout() bookmark_frame = QFrame() bookmark_frame.setFixedWidth(120) bookmark_layout = QVBoxLayout() bookmark_layout.setSpacing(1) bookmark_layout.setContentsMargins(2, 2, 2, 2) bookmark_frame.setLayout(bookmark_layout) bookmark_frame.setFrameStyle(QFrame.Sunken) bookmark_frame.setFrameShape(QFrame.StyledPanel) self.bookmark_list = MTTBookmarkList() self.bookmark_list.bookmarkDeleted.connect(self.do_delete_bookmark) self.bookmark_list.setAlternatingRowColors(True) self.bookmark_list.dragEnabled() self.bookmark_list.setAcceptDrops(True) self.bookmark_list.setDropIndicatorShown(True) self.bookmark_list.setDragDropMode(QListView.InternalMove) self.bookmark_list_sel_model = self.bookmark_list.selectionModel() self.bookmark_list_sel_model.selectionChanged.connect( self.on_select_bookmark) bookmark_layout.addWidget(self.bookmark_list) bookmark_parent_layout.addWidget(bookmark_frame) bookmark_parent_layout.addLayout(content_layout) main_layout.addLayout(bookmark_parent_layout) self.do_populate_bookmarks() else: main_layout.addLayout(content_layout) if not self.defined_type: # type layout self.types = QComboBox() self.types.addItems(self.supported_node_type) self.types.currentIndexChanged.connect(self.on_node_type_changed) if cmds.optionVar(exists='MTT_lastNodeType'): last = cmds.optionVar(query='MTT_lastNodeType') if last in self.supported_node_type: self.types.setCurrentIndex( self.supported_node_type.index(last)) buttons_layout.addWidget(self.types) if not self.defined_path or not self.defined_type: create_btn = QPushButton('C&reate') create_btn.clicked.connect(self.accept) cancel_btn = QPushButton('&Cancel') cancel_btn.clicked.connect(self.reject) buttons_layout.addStretch() buttons_layout.addWidget(create_btn) buttons_layout.addWidget(cancel_btn)
class MTTFilterFileDialog(QDialog): def __init__(self, define_path='', define_type=None): super(MTTFilterFileDialog, self).__init__(get_maya_window()) self.supported_node_type = sorted( [node_type for (node_type, nice, attr) in MTTSettings.SUPPORTED_TYPE]) self.defined_path = ( define_path if os.path.isdir(define_path) or define_path == SOURCEIMAGES_TAG else None) self.defined_type = ( define_type if define_type in self.supported_node_type else None) self.path_edit = None self.filter_reset_btn = None self.filter_line = None self.parent_folder_btn = None self.files_model = None self.files_list = None self.bookmark_list = None self.bookmark_list_sel_model = None self.types = None # move window to cursor position win_geo = MTTSettings.value( 'FilterFileDialog/windowGeometry', QRect(0, 0, 400, 300)) self.setGeometry(win_geo) mouse_pos = QCursor.pos() mouse_pos.setX(mouse_pos.x() - (win_geo.width() * 0.5)) self.move(mouse_pos) self.__create_ui() self.filter_line.setFocus() self.on_change_root_path(self.defined_path or SOURCEIMAGES_TAG) def __create_ui(self): """ Create main UI """ self.setWindowTitle(CREATE_NODE_TITLE) # remove window decoration if path and type is set if self.defined_path and self.defined_type: self.setWindowFlags(Qt.FramelessWindowHint | Qt.Popup) main_layout = QVBoxLayout(self) main_layout.setSpacing(1) main_layout.setContentsMargins(2, 2, 2, 2) # content layout content_layout = QVBoxLayout() self.files_model = QFileSystemModel() self.files_model.setNameFilterDisables(False) self.files_list = MTTFileList() self.files_list.setAlternatingRowColors(True) self.files_list.setSelectionMode(QAbstractItemView.ExtendedSelection) self.files_list.selectionValidated.connect(self.do_validate_selection) self.files_list.goToParentDirectory.connect(self.on_go_up_parent) self.files_list.doubleClicked.connect(self.on_double_click) self.files_list.setModel(self.files_model) buttons_layout = QHBoxLayout() content_layout.addLayout(self.__create_filter_ui()) content_layout.addWidget(self.files_list) content_layout.addLayout(buttons_layout) self.files_list.filter_line = self.filter_line if not self.defined_path: # path line path_layout = QHBoxLayout() # bookmark button bookmark_btn = QPushButton('') bookmark_btn.setFlat(True) bookmark_btn.setIcon(QIcon(':/addBookmark.png')) bookmark_btn.setToolTip('Bookmark this Folder') bookmark_btn.setStatusTip('Bookmark this Folder') bookmark_btn.clicked.connect(self.on_add_bookmark) # path line edit self.path_edit = QLineEdit() self.path_edit.editingFinished.connect(self.on_enter_path) # parent folder button self.parent_folder_btn = QPushButton('') self.parent_folder_btn.setFlat(True) self.parent_folder_btn.setIcon(QIcon(':/SP_FileDialogToParent.png')) self.parent_folder_btn.setToolTip('Parent Directory') self.parent_folder_btn.setStatusTip('Parent Directory') self.parent_folder_btn.clicked.connect(self.on_go_up_parent) # browse button browse_btn = QPushButton('') browse_btn.setFlat(True) browse_btn.setIcon(QIcon(':/navButtonBrowse.png')) browse_btn.setToolTip('Browse Directory') browse_btn.setStatusTip('Browse Directory') browse_btn.clicked.connect(self.on_browse) # parent widget and layout path_layout.addWidget(bookmark_btn) path_layout.addWidget(self.path_edit) path_layout.addWidget(self.parent_folder_btn) path_layout.addWidget(browse_btn) main_layout.addLayout(path_layout) # bookmark list bookmark_parent_layout = QHBoxLayout() bookmark_frame = QFrame() bookmark_frame.setFixedWidth(120) bookmark_layout = QVBoxLayout() bookmark_layout.setSpacing(1) bookmark_layout.setContentsMargins(2, 2, 2, 2) bookmark_frame.setLayout(bookmark_layout) bookmark_frame.setFrameStyle(QFrame.Sunken) bookmark_frame.setFrameShape(QFrame.StyledPanel) self.bookmark_list = MTTBookmarkList() self.bookmark_list.bookmarkDeleted.connect(self.do_delete_bookmark) self.bookmark_list.setAlternatingRowColors(True) self.bookmark_list.dragEnabled() self.bookmark_list.setAcceptDrops(True) self.bookmark_list.setDropIndicatorShown(True) self.bookmark_list.setDragDropMode(QListView.InternalMove) self.bookmark_list_sel_model = self.bookmark_list.selectionModel() self.bookmark_list_sel_model.selectionChanged.connect( self.on_select_bookmark) bookmark_layout.addWidget(self.bookmark_list) bookmark_parent_layout.addWidget(bookmark_frame) bookmark_parent_layout.addLayout(content_layout) main_layout.addLayout(bookmark_parent_layout) self.do_populate_bookmarks() else: main_layout.addLayout(content_layout) if not self.defined_type: # type layout self.types = QComboBox() self.types.addItems(self.supported_node_type) self.types.currentIndexChanged.connect(self.on_node_type_changed) if cmds.optionVar(exists='MTT_lastNodeType'): last = cmds.optionVar(query='MTT_lastNodeType') if last in self.supported_node_type: self.types.setCurrentIndex( self.supported_node_type.index(last)) buttons_layout.addWidget(self.types) if not self.defined_path or not self.defined_type: create_btn = QPushButton('C&reate') create_btn.clicked.connect(self.accept) cancel_btn = QPushButton('&Cancel') cancel_btn.clicked.connect(self.reject) buttons_layout.addStretch() buttons_layout.addWidget(create_btn) buttons_layout.addWidget(cancel_btn) def __create_filter_ui(self): """ Create filter widgets """ filter_layout = QHBoxLayout() filter_layout.setSpacing(1) filter_layout.setContentsMargins(0, 0, 0, 0) self.filter_reset_btn = QPushButton() icon = QIcon(':/filtersOff.png') self.filter_reset_btn.setIcon(icon) self.filter_reset_btn.setIconSize(QSize(22, 22)) self.filter_reset_btn.setFixedSize(24, 24) self.filter_reset_btn.setToolTip('Reset filter') self.filter_reset_btn.setFlat(True) self.filter_reset_btn.clicked.connect( partial(self.on_filter_set_text, '')) self.filter_line = QLineEdit() self.filter_line.setPlaceholderText('Enter filter string here') self.filter_line.textChanged.connect(self.on_filter_change_text) completer = QCompleter(self) completer.setCaseSensitivity(Qt.CaseInsensitive) completer.setModel(QStringListModel([], self)) self.filter_line.setCompleter(completer) filter_layout.addWidget(self.filter_reset_btn) filter_layout.addWidget(self.filter_line) return filter_layout def on_filter_set_text(self, text=''): """ Set text in filter field """ self.filter_line.setText(text) def on_filter_change_text(self, text): """ Apply filter string """ if len(text): icon = QIcon(':/filtersOn.png') self.filter_reset_btn.setIcon(icon) else: icon = QIcon(':/filtersOff.png') self.filter_reset_btn.setIcon(icon) self.files_model.setNameFilters( ['*%s*' % item.strip() for item in text.split(',') if item.strip()]) def on_node_type_changed(self, index): cmds.optionVar(sv=['MTT_lastNodeType', self.supported_node_type[index]]) def on_double_click(self, index): current_item = self.files_model.filePath(index) if os.path.isdir(current_item): self.on_change_root_path(current_item) elif os.path.isfile(current_item): self.accept() def on_change_root_path(self, current_path): if current_path == SOURCEIMAGES_TAG: current_path = os.path.join( cmds.workspace(query=True, rootDirectory=True), cmds.workspace(fileRuleEntry='sourceImages') ) self.files_model.setRootPath(current_path) self.files_list.setRootIndex(self.files_model.index(current_path)) if self.path_edit: self.path_edit.setText(current_path) if self.parent_folder_btn: current_dir = QDir(current_path) self.parent_folder_btn.setEnabled(current_dir.cdUp()) def on_go_up_parent(self): current_path = QDir(self.files_model.rootPath()) current_path.cdUp() self.on_change_root_path(current_path.absolutePath()) def on_enter_path(self): new_path = self.path_edit.text() if os.path.isdir(new_path): self.on_change_root_path(new_path) else: self.path_edit.setText(self.files_model.rootPath()) def on_browse(self): current_path = self.files_model.rootPath() file_dialog = QFileDialog(self, 'Select a Folder', current_path) file_dialog.setFileMode(QFileDialog.Directory) file_dialog.setOption(QFileDialog.ShowDirsOnly) if file_dialog.exec_(): self.on_change_root_path(file_dialog.selectedFiles()[0]) def on_select_bookmark(self, selected, deselected): current_item = selected.indexes() if current_item: self.on_change_root_path( self.bookmark_list.selectedItems()[0].root_path) def on_add_bookmark(self): current_path = self.files_model.rootPath() self.on_add_bookmark_item( '%s|%s' % (os.path.basename(current_path), current_path)) def on_add_bookmark_item(self, item): if item == '': return current_item = MTTBookmarkItem() current_item.add_raw_data(item) current_item.setSizeHint(QSize(40, 25)) current_item.setFlags( Qt.ItemIsEnabled | Qt.ItemIsEditable | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled ) self.bookmark_list.addItem(current_item) def do_delete_bookmark(self): current_item = self.bookmark_list.selectedItems() if current_item: item_row = self.bookmark_list.row(current_item[0]) self.bookmark_list.takeItem(item_row) del current_item[0] def do_save_bookmark(self): if not self.bookmark_list: return row_count = self.bookmark_list.count() ordered_list = list() for i in range(row_count): item = self.bookmark_list.item(i) name = item.text().replace(',', '_').replace('|', '_') path = item.root_path if name != 'sourceimages': ordered_list.append('%s|%s' % (name, path)) MTTSettings.set_value( 'FilterFileDialog/bookmarks', ','.join(ordered_list)) def do_populate_bookmarks(self): bookmarks = ['sourceimages|%s' % SOURCEIMAGES_TAG] bookmarks.extend( MTTSettings.value('FilterFileDialog/bookmarks').split(',')) for bm in bookmarks: self.on_add_bookmark_item(bm) def do_validate_selection(self): selection = self.files_list.selectedIndexes() if len(selection) == 1: current_path = self.files_model.filePath(selection[0]) if os.path.isdir(current_path): self.on_change_root_path(current_path) return self.accept() def get_selected_files(self): selected_items = list() for item_index in self.files_list.selectedIndexes(): current_path = self.files_model.filePath(item_index) if os.path.isfile(current_path): selected_items.append(current_path) return selected_items def get_node_type(self): return self.types.currentText() if self.types else self.defined_type def closeEvent(self, event): MTTSettings.set_value( 'FilterFileDialog/windowGeometry', self.geometry()) self.do_save_bookmark() self.deleteLater() event.accept()
class TransferPanel(QWidget): ''' Transfer Panel This Panel is the main dialog box for the Dive Computer Transfer GUI ''' def __init__(self, parent=None): super(TransferPanel, self).__init__(parent) self._logbook = None self._logbookName = 'None' self._logbookPath = None self._createLayout() self._readSettings() self.setWindowTitle(self.tr('DC Transfer - %s') % self._logbookName) def _createLayout(self): 'Create the Widget Layout' self._txtLogbook = QLineEdit() self._txtLogbook.setReadOnly(True) self._lblLogbook = QLabel(self.tr('&Logbook File:')) self._lblLogbook.setBuddy(self._txtLogbook) self._btnBrowse = QPushButton('...') self._btnBrowse.clicked.connect(self._btnBrowseClicked) self._btnBrowse.setStyleSheet('QPushButton { min-width: 24px; max-width: 24px; }') self._btnBrowse.setToolTip(self.tr('Browse for a Logbook')) self._cbxComputer = QComboBox() self._lblComputer = QLabel(self.tr('Dive &Computer:')) self._lblComputer.setBuddy(self._cbxComputer) self._btnAddComputer = QPushButton(QPixmap(':/icons/list-add.png'), self.tr('')) self._btnAddComputer.setStyleSheet('QPushButton { min-width: 24px; min-height: 24; max-width: 24px; max-height: 24; }') self._btnAddComputer.clicked.connect(self._btnAddComputerClicked) self._btnRemoveComputer = QPushButton(QPixmap(':/icons/list-remove.png'), self.tr('')) self._btnRemoveComputer.setStyleSheet('QPushButton { min-width: 24px; min-height: 24; max-width: 24px; max-height: 24; }') self._btnRemoveComputer.clicked.connect(self._btnRemoveComputerClicked) hbox = QHBoxLayout() hbox.addWidget(self._btnAddComputer) hbox.addWidget(self._btnRemoveComputer) gbox = QGridLayout() gbox.addWidget(self._lblLogbook, 0, 0) gbox.addWidget(self._txtLogbook, 0, 1) gbox.addWidget(self._btnBrowse, 0, 2) gbox.addWidget(self._lblComputer, 1, 0) gbox.addWidget(self._cbxComputer, 1, 1) gbox.addLayout(hbox, 1, 2) gbox.setColumnStretch(1, 1) self._pbTransfer = QProgressBar() self._pbTransfer.reset() self._txtStatus = QTextEdit() self._txtStatus.setReadOnly(True) self._btnTransfer = QPushButton(self.tr('&Transfer Dives')) self._btnTransfer.clicked.connect(self._btnTransferClicked) self._btnExit = QPushButton(self.tr('E&xit')) self._btnExit.clicked.connect(self.close) hbox = QHBoxLayout() hbox.addWidget(self._btnTransfer) hbox.addStretch() hbox.addWidget(self._btnExit) vbox = QVBoxLayout() vbox.addLayout(gbox) vbox.addWidget(self._pbTransfer) vbox.addWidget(self._txtStatus) vbox.addLayout(hbox) self.setLayout(vbox) def _closeLogbook(self): 'Close the current Logbook' if self._logbook is None: return self._logbook = None self._logbookName = 'None' self._logbookPath = None self._txtLogbook.clear() self._cbxComputer.setModel(None) self._writeSettings() self.setWindowTitle(self.tr('DC Transfer - %s') % self._logbookName) def _openLogbook(self, path): 'Open an existing Logbook' if self._logbook is not None: self._closeLogbook() if not os.path.exists(path): QMessageBox.critical(self, self.tr('Missing Logbook'), self.tr('Logbook File "%s" does not exist.') % path) return #TODO: Handle a Schema Upgrade in a user-friendly manner self._logbook = Logbook(path, auto_update=False) self._logbookName = os.path.basename(path) self._logbookPath = path self._txtLogbook.setText(self._logbookPath) self._cbxComputer.setModel(DiveComputersModel(self._logbook)) self._writeSettings() self.setWindowTitle(self.tr('DC Transfer - %s') % self._logbookName) def _readSettings(self): 'Read main window settings from the configuration' settings = QSettings() settings.beginGroup('MainWindow') max = settings.value('max') size = settings.value('size') pos = settings.value('pos') file = settings.value('file') settings.endGroup() # Size and Position the Main Window if size is not None: self.resize(size) if pos is not None: self.move(pos) # HAX because QVariant is not exposed in PySide and the default # coercion to string is just stupid if max is not None and (max == 'true'): self.showMaximized() # Open the Logbook if file is not None: self._openLogbook(file) def _writeSettings(self): 'Write settings to the configuration' settings = QSettings() settings.beginGroup('MainWindow') settings.setValue('pos', self.pos()) settings.setValue('size', self.size()) settings.setValue('max', self.isMaximized()) settings.setValue('file', self._logbookPath) settings.endGroup() def closeEvent(self, e): 'Intercept an OnClose event' self._writeSettings() e.accept() #-------------------------------------------------------------------------- # Slots @QtCore.Slot() def _btnAddComputerClicked(self): 'Add a Dive Computer' dc = AddDiveComputerWizard.RunWizard(self) if dc is not None: self._logbook.session.add(dc) self._logbook.session.commit() self._cbxComputer.model().reload() self._cbxComputer.setCurrentIndex(self._cbxComputer.findText(dc.name)) @QtCore.Slot() def _btnRemoveComputerClicked(self): 'Remove a Dive Computer' idx = self._cbxComputer.currentIndex() dc = self._cbxComputer.itemData(idx, Qt.UserRole+0) if QMessageBox.question(self, self.tr('Delete Dive Computer?'), self.tr('Are you sure you want to delete "%s"?') % dc.name, QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) == QMessageBox.Yes: self._logbook.session.delete(dc) self._logbook.session.commit() self._cbxComputer.model().reload() @QtCore.Slot() def _btnBrowseClicked(self): 'Browse for a Logbook File' if self._logbook is not None: dir = os.path.dirname(self._logbookPath) else: dir = os.path.expanduser('~') fn = QFileDialog.getOpenFileName(self, caption=self.tr('Select a Logbook file'), dir=dir, filter='Logbook Files (*.lbk);;All Files(*.*)')[0] if fn == '': return if not os.path.exists(fn): if QMessageBox.question(self, self.tr('Create new Logbook?'), self.tr('Logbook "%s" does not exist. Would you like to create it?') % os.path.basename(fn), QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) != QMessageBox.Yes: return Logbook.Create(fn) self._openLogbook(fn) @QtCore.Slot() def _btnTransferClicked(self): 'Transfer Dives' idx = self._cbxComputer.currentIndex() dc = self._cbxComputer.itemData(idx, Qt.UserRole+0) if self._logbook.session.dirty: print "Flushing dirty session" self._logbook.rollback() self._txtLogbook.setEnabled(False) self._btnBrowse.setEnabled(False) self._cbxComputer.setEnabled(False) self._btnAddComputer.setEnabled(False) self._btnRemoveComputer.setEnabled(False) self._btnTransfer.setEnabled(False) self._btnExit.setEnabled(False) self._txtStatus.clear() thread = QThread(self) #FIXME: ZOMG HAX: Garbage Collector will eat TransferWorker when moveToThread is called #NOTE: Qt.QueuedConnection is important... self.worker = None self.worker = TransferWorker(dc) thread.started.connect(self.worker.start, Qt.QueuedConnection) self.worker.moveToThread(thread) self.worker.finished.connect(self._transferFinished, Qt.QueuedConnection) self.worker.finished.connect(self.worker.deleteLater, Qt.QueuedConnection) self.worker.finished.connect(thread.deleteLater, Qt.QueuedConnection) self.worker.progress.connect(self._transferProgress, Qt.QueuedConnection) self.worker.started.connect(self._transferStart, Qt.QueuedConnection) self.worker.status.connect(self._transferStatus, Qt.QueuedConnection) thread.start() @QtCore.Slot(str) def _transferStatus(self, msg): 'Transfer Status Message' self._txtStatus.append(msg) @QtCore.Slot(int) def _transferStart(self, nBytes): 'Transfer Thread Stated' if nBytes > 0: self._pbTransfer.setMaximum(nBytes) else: self._pbTransfer.setMaximum(100) self._pbTransfer.reset() @QtCore.Slot(int) def _transferProgress(self, nTransferred): 'Transfer Thread Progress Event' self._pbTransfer.setValue(nTransferred) @QtCore.Slot(models.Dive) def _transferParsed(self, dive): 'Transfer Thread Parsed Dive' self._logbook.session.add(dive) @QtCore.Slot() def _transferFinished(self): 'Transfer Thread Finished' self._logbook.session.commit() self._txtLogbook.setEnabled(True) self._btnBrowse.setEnabled(True) self._cbxComputer.setEnabled(True) self._btnAddComputer.setEnabled(True) self._btnRemoveComputer.setEnabled(True) self._btnTransfer.setEnabled(True) self._btnExit.setEnabled(True)