class MultiListDialog(QDialog): def __init__(self, items): # , parent=None super(MultiListDialog, self).__init__() # parent self.resize(800, 550) self.entries = items layout = QVBoxLayout(self) self.listWidget = QListWidget(self) self.listWidget.setSelectionMode(QAbstractItemView.ExtendedSelection) self.HlineInputfiles = ConfigLineDir(u"Verzeichnis NI XML:", "dir") self.HlineOutputfiles = ConfigLineDir(u"Verzeichnis Report:", "dir") if os.path.isfile(PICKLE_TEMP_FILE): pkl_file = open(PICKLE_TEMP_FILE, 'rb') inPath = pickle.load(pkl_file) outPath = pickle.load(pkl_file) pkl_file.close() if os.path.isdir(inPath): self.HlineInputfiles.editText.setText(inPath) if os.path.isdir(outPath): self.HlineOutputfiles.editText.setText(outPath) layout.addLayout(self.HlineInputfiles) layout.addLayout(self.HlineOutputfiles) layout.addWidget(self.listWidget) layout.addWidget(QLabel("Mehrfachauswahl -> Strg + Mausklick")) # OK and Cancel buttons buttons = QDialogButtonBox(QDialogButtonBox.Apply | QDialogButtonBox.Close, Qt.Horizontal, self) # Apply before Close buttons.setStyleSheet("* { button-layout: 2 }") layout.addWidget(buttons) buttons.rejected.connect(self.close) buttons.button(QDialogButtonBox.Apply).clicked.connect(self.Apply_Clicked) self.SetListItems() self.HlineInputfiles.editText.textChanged.connect(self.RefreshList) self.HlineInputfiles.editText.textChanged.connect(self.SetListItems) # def SetOutputDir(self): # self.HlineOutputfiles.editText.setText(self.HlineInputfiles.getText()) def SetListItems(self, parent=None): itemslist = os.listdir(self.HlineInputfiles.getText()) for it in itemslist: if it.endswith(".xml"): self.listWidget.addItem(it) def GetMarkedItems(self): results = [] try: for el in self.listWidget.selectedItems(): results.append(str(el.text())) return (results) except: return (None) def RefreshList(self): self.listWidget.clear() print "refresh" def Apply_Clicked(self): SelectedItems = self.GetMarkedItems() textMsg = "Selektierte Dateie(n):\r\n" if len(SelectedItems) > 0: for file in SelectedItems: filePath = os.path.join(self.HlineInputfiles.getText(), file) textMsg += (file + "\r\n") XmlAnalysis.XmlAnalysis(filePath, self.HlineOutputfiles.getText()) #QMessageBox.information(self, "Report", textMsg) textMsg += "\r\nReport-Verzeichnis öffnen?\r\n" msgBox = QMessageBox.StandardButton.Yes msgBox |= QMessageBox.StandardButton.No if QMessageBox.question(self, "Report", textMsg, msgBox) == QMessageBox.Yes: os.startfile(self.HlineOutputfiles.getText()) else: QMessageBox.warning(self, "Achtung", "Keine Datei selektiert!") pass
class ConfigEditor(QMainWindow): def __init__(self, app, cfg, title='Config Editor'): super(ConfigEditor, self).__init__() self.app = app self.config = cfg self.title = title def setup(self): self.dirty = False self.def_cfg = copy.deepcopy(self.config) self.config.update_from_user_file() self.base_cfg = copy.deepcopy(self.config) self.categories = QListWidget() #self.categories.setSizePolicy(QSizePolicy.Fixed,QSizePolicy.Expanding) self.settings = QStackedWidget() #self.categories.setSizePolicy(QSizePolicy.MinimumExpanding,QSizePolicy.Expanding) QObject.connect(self.categories, SIGNAL('itemSelectionChanged()'), self.category_selected) self.widget_list = {} for cat in self.config.get_categories(): self.widget_list[cat] = {} longest_cat = 0 for cat in self.config.get_categories(): if len(cat) > longest_cat: longest_cat = len(cat) self.categories.addItem(cat) settings_layout = QGridLayout() r = 0 c = 0 for setting in self.config.get_settings(cat): info = self.config.get_setting(cat, setting, True) s = QWidget() s.setSizePolicy(QSizePolicy.Expanding,QSizePolicy.Fixed) sl = QVBoxLayout() label = QLabel() if info.has_key('alias'): label.setText(info['alias']) else: label.setText(setting) if info.has_key('about'): label.setToolTip(info['about']) sl.addWidget(label) if info['type'] == constants.CT_LINEEDIT: w = LineEdit(self, self.config,cat,setting,info) elif info['type'] == constants.CT_CHECKBOX: w = CheckBox(self, self.config,cat,setting,info) elif info['type'] == constants.CT_SPINBOX: w = SpinBox(self, self.config,cat,setting,info) elif info['type'] == constants.CT_DBLSPINBOX: w = DoubleSpinBox(self, self.config,cat,setting,info) elif info['type'] == constants.CT_COMBO: w = ComboBox(self, self.config,cat,setting,info) w.setSizePolicy(QSizePolicy.Expanding,QSizePolicy.Fixed) self.widget_list[cat][setting] = w sl.addWidget(w) s.setLayout(sl) c = self.config.config[cat].index(setting) % 2 settings_layout.addWidget(s, r, c) if c == 1: r += 1 settings = QWidget() settings.setLayout(settings_layout) settings_scroller = QScrollArea() settings_scroller.setWidget(settings) settings_scroller.setWidgetResizable(True) self.settings.addWidget(settings_scroller) font = self.categories.font() fm = QFontMetrics(font) self.categories.setMaximumWidth(fm.widthChar('X')*(longest_cat+4)) self.main = QWidget() self.main_layout = QVBoxLayout() self.config_layout = QHBoxLayout() self.config_layout.addWidget(self.categories) self.config_layout.addWidget(self.settings) self.mainButtons = QDialogButtonBox(QDialogButtonBox.RestoreDefaults | QDialogButtonBox.Reset | QDialogButtonBox.Apply) self.main_apply = self.mainButtons.button(QDialogButtonBox.StandardButton.Apply) self.main_reset = self.mainButtons.button(QDialogButtonBox.StandardButton.Reset) self.main_defaults = self.mainButtons.button(QDialogButtonBox.StandardButton.LastButton) QObject.connect(self.mainButtons, SIGNAL('clicked(QAbstractButton *)'), self.mainbutton_clicked) self.dirty_check() self.main_layout.addLayout(self.config_layout) self.main_layout.addWidget(self.mainButtons) self.main.setLayout(self.main_layout) self.setCentralWidget(self.main) self.setWindowTitle(self.title) self.setUnifiedTitleAndToolBarOnMac(True) self.categories.setCurrentItem(self.categories.item(0)) self.menuBar = QMenuBar() self.filemenu = QMenu('&File') self.quitAction = QAction(self) self.quitAction.setText('&Quit') if platform.system() != 'Darwin': self.quitAction.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_Q)) QObject.connect(self.quitAction, SIGNAL('triggered()'), self.quitApp) self.filemenu.addAction(self.quitAction) self.menuBar.addMenu(self.filemenu) self.setMenuBar(self.menuBar) self.show() self.activateWindow() self.raise_() self.setMinimumWidth(self.geometry().width()*1.2) screen = QDesktopWidget().screenGeometry() size = self.geometry() self.move((screen.width()-size.width())/2, (screen.height()-size.height())/2) def category_selected(self): self.settings.setCurrentIndex(self.config.config.index(self.categories.selectedItems()[0].text())) def mainbutton_clicked(self, button): if button == self.main_reset: for cat in self.base_cfg.get_categories(): for setting in self.base_cfg.get_settings(cat): self.widget_list[cat][setting].updateValue(self.base_cfg.get_setting(cat,setting)) elif button == self.main_defaults: for cat in self.def_cfg.get_categories(): for setting in self.def_cfg.get_settings(cat): self.widget_list[cat][setting].updateValue(self.def_cfg.get_setting(cat,setting)) elif button == self.main_apply: bad_settings = self.validate_settings() if bad_settings == []: self.save_settings() self.main_apply.setEnabled(False) self.main_reset.setEnabled(False) else: msgBox = QMessageBox() msgBox.setText("Must fix the following invalid settings before quitting:") msgBox.setStandardButtons(QMessageBox.Ok) info = '' for setting in bad_settings: new = '%s,%s<br>' % setting info = '%s%s' % (info, new) msgBox.setInformativeText(info) msgBox.exec_() def quitApp(self): self.app.closeAllWindows() def get_changes(self): enc = MyEncoder() if enc.encode(self.def_cfg.config) == enc.encode(self.config.config): return False if enc.encode(self.base_cfg.config) != enc.encode(self.config.config): newC = Config() for c in self.config.config.keys(): for s in self.config.config[c].keys(): if self.config.config[c][s]['value'] != self.def_cfg.config[c][s]['value']: newC.add_setting(c, s, self.config.config[c][s]['value'], stub=True) return json.dumps(newC.config, separators=(',',': '), indent=4, sort_keys=True) else: return None def validate_settings(self): ret = [] for cat in self.config.get_categories(): for setting in self.config.get_settings(cat): info = self.config.get_setting(cat, setting, True) if info.has_key('validate'): if not info['validate'](info): ret.append((cat,setting)) return ret def dirty_check(self): if str(self.base_cfg) != str(self.config): self.dirty = True self.main_apply.setEnabled(True) self.main_reset.setEnabled(True) else: self.dirty = False self.main_apply.setEnabled(False) self.main_reset.setEnabled(False) if str(self.def_cfg) == str(self.config): self.main_defaults.setEnabled(False) else: self.main_defaults.setEnabled(True) def save_settings(self): config = self.get_changes() if config == False: if os.path.isfile(self.config.user_file): os.remove(self.config.user_file) elif config != None: with open(self.config.user_file, 'w+') as f: f.write(config) self.base_cfg = copy.deepcopy(self.config) def closeEvent(self, event=None): self.quitApp()
class MainWindow(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.resize(800,600) self.setWindowTitle('PDF Merger') about = QAction('About', self) self.connect(about, SIGNAL('triggered()'), self.show_about) exit = QAction('Exit', self) exit.setShortcut('Ctrl+Q') self.connect(exit, SIGNAL('triggered()'), SLOT('close()')) self.statusBar() menubar = self.menuBar() file = menubar.addMenu('File') file.addAction(about) file.addAction(exit) self.main_widget = QWidget(self) self.setCentralWidget(self.main_widget) self.up_down_widget = QWidget(self) self.options_widget = QWidget(self) input_files_label = QLabel("Input PDFs\nThis is the order in which the files will be merged too") self.files_list = QListWidget() self.files_list.setSelectionMode(QAbstractItemView.ExtendedSelection) add_button = QPushButton("Add PDF(s) to merge...") add_button.clicked.connect(self.clicked_add) up_button = QPushButton("Up") up_button.clicked.connect(self.move_file_up) down_button = QPushButton("Down") down_button.clicked.connect(self.move_file_down) remove_button = QPushButton("Remove PDF") remove_button.clicked.connect(self.remove_file) select_path_label = QLabel("Output PDF") self.dest_path_edit = QLineEdit() self.dest_path_edit.setReadOnly(True) select_path = QPushButton("Select...") select_path.clicked.connect(self.select_save_path) start = QPushButton("Start") start.clicked.connect(self.merge_pdf) up_down_vbox = QVBoxLayout(self.up_down_widget) up_down_vbox.addWidget(up_button) up_down_vbox.addWidget(down_button) up_down_vbox.addWidget(remove_button) self.up_down_widget.setLayout(up_down_vbox) group_input = QGroupBox() grid_input = QGridLayout() grid_input.addWidget(add_button, 0, 0) grid_input.addWidget(input_files_label, 1, 0) grid_input.addWidget(self.files_list, 2, 0) grid_input.addWidget(self.up_down_widget, 2, 1) group_input.setLayout(grid_input) group_output = QGroupBox() grid_output = QGridLayout() grid_output.addWidget(select_path_label, 0, 0) grid_output.addWidget(self.dest_path_edit, 1, 0) grid_output.addWidget(select_path, 1, 1) group_output.setLayout(grid_output) vbox_options = QVBoxLayout(self.options_widget) vbox_options.addWidget(group_input) vbox_options.addWidget(group_output) vbox_options.addWidget(start) self.options_widget.setLayout(vbox_options) splitter_filelist = QSplitter() splitter_filelist.setOrientation(Qt.Vertical) splitter_filelist.addWidget(self.options_widget) vbox_main = QVBoxLayout(self.main_widget) vbox_main.addWidget(splitter_filelist) vbox_main.setContentsMargins(0,0,0,0) def show_about(self): #TODO add hyperlinks and create simple base website #TODO versioning system QMessageBox.about(self, 'About', 'PDF Merger\n2013 Nikola Peric\n\n' + 'http://www.example.com/\nhttps://github.com/nikolap/pdfmerger/\n\n' + 'Licensed under The MIT License\nhttp://opensource.org/licenses/MIT' ) def clicked_add(self): fname, _ = QFileDialog.getOpenFileNames(self, 'Select two or more PDFs to merge', QDir.homePath(), "*.pdf") self.files_list.addItems(fname) def move_file_up(self): sorted_selected_items = self.get_sorted_selected_items() if 0 not in sorted_selected_items: for row in sorted_selected_items: item = self.files_list.takeItem(row) self.files_list.insertItem(row - 1, item) def move_file_down(self): sorted_selected_items = self.get_sorted_selected_items(descending=True) if (self.files_list.count() - 1) not in sorted_selected_items: for row in sorted_selected_items: item = self.files_list.takeItem(row) self.files_list.insertItem(row + 1, item) def get_sorted_selected_items(self, descending=False): items_list = [] for item in self.files_list.selectedItems(): items_list.append(self.files_list.row(item)) return sorted(items_list, key=int, reverse = descending) def remove_file(self): for item in self.files_list.selectedItems(): row = self.files_list.row(item) self.files_list.takeItem(row) def select_save_path(self): fname, _ = QFileDialog.getSaveFileName(self, 'Save file', QDir.homePath(), "*.pdf") self.dest_path_edit.setText(fname) def merge_pdf(self): save_path = self.dest_path_edit.text() if save_path is '': raise Exception(QMessageBox.warning(self, 'Warning!', 'No location to save file selected.\n' + 'Cannot proceed with merger.')) input_files = [] for i in range(0, self.files_list.count()): file_path = self.files_list.item(i).text() if '.pdf' not in file_path and '.PDF' not in file_path: QMessageBox.warning(self, 'Warning!', 'Some files not PDFs\n' + 'Please examine' + file_path) raise Exception("PDF file error!") else: input_files.append(file_path) if len(input_files) >= 2: merge_pdf(destination=save_path, pdf_files=input_files) else: QMessageBox.warning(self, 'Warning!', 'Not enough PDFs selected.\n' + 'Please choose 2 or more files to merge.')
class MainWindow(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.resize(800, 600) self.setWindowTitle('PDF Merger') about = QAction('About', self) self.connect(about, SIGNAL('triggered()'), self.show_about) exit = QAction('Exit', self) exit.setShortcut('Ctrl+Q') self.connect(exit, SIGNAL('triggered()'), SLOT('close()')) self.statusBar() menubar = self.menuBar() file = menubar.addMenu('File') file.addAction(about) file.addAction(exit) self.main_widget = QWidget(self) self.setCentralWidget(self.main_widget) self.up_down_widget = QWidget(self) self.options_widget = QWidget(self) input_files_label = QLabel( "Input PDFs\nThis is the order in which the files will be merged too" ) self.files_list = QListWidget() self.files_list.setSelectionMode(QAbstractItemView.ExtendedSelection) add_button = QPushButton("Add PDF(s) to merge...") add_button.clicked.connect(self.clicked_add) up_button = QPushButton("Up") up_button.clicked.connect(self.move_file_up) down_button = QPushButton("Down") down_button.clicked.connect(self.move_file_down) remove_button = QPushButton("Remove PDF") remove_button.clicked.connect(self.remove_file) select_path_label = QLabel("Output PDF") self.dest_path_edit = QLineEdit() self.dest_path_edit.setReadOnly(True) select_path = QPushButton("Select...") select_path.clicked.connect(self.select_save_path) start = QPushButton("Start") start.clicked.connect(self.merge_pdf) up_down_vbox = QVBoxLayout(self.up_down_widget) up_down_vbox.addWidget(up_button) up_down_vbox.addWidget(down_button) up_down_vbox.addWidget(remove_button) self.up_down_widget.setLayout(up_down_vbox) group_input = QGroupBox() grid_input = QGridLayout() grid_input.addWidget(add_button, 0, 0) grid_input.addWidget(input_files_label, 1, 0) grid_input.addWidget(self.files_list, 2, 0) grid_input.addWidget(self.up_down_widget, 2, 1) group_input.setLayout(grid_input) group_output = QGroupBox() grid_output = QGridLayout() grid_output.addWidget(select_path_label, 0, 0) grid_output.addWidget(self.dest_path_edit, 1, 0) grid_output.addWidget(select_path, 1, 1) group_output.setLayout(grid_output) vbox_options = QVBoxLayout(self.options_widget) vbox_options.addWidget(group_input) vbox_options.addWidget(group_output) vbox_options.addWidget(start) self.options_widget.setLayout(vbox_options) splitter_filelist = QSplitter() splitter_filelist.setOrientation(Qt.Vertical) splitter_filelist.addWidget(self.options_widget) vbox_main = QVBoxLayout(self.main_widget) vbox_main.addWidget(splitter_filelist) vbox_main.setContentsMargins(0, 0, 0, 0) def show_about(self): #TODO add hyperlinks and create simple base website #TODO versioning system QMessageBox.about( self, 'About', 'PDF Merger\n2013 Nikola Peric\n\n' + 'http://www.example.com/\nhttps://github.com/nikolap/pdfmerger/\n\n' + 'Licensed under The MIT License\nhttp://opensource.org/licenses/MIT' ) def clicked_add(self): fname, _ = QFileDialog.getOpenFileNames( self, 'Select two or more PDFs to merge', QDir.homePath(), "*.pdf") self.files_list.addItems(fname) def move_file_up(self): sorted_selected_items = self.get_sorted_selected_items() if 0 not in sorted_selected_items: for row in sorted_selected_items: item = self.files_list.takeItem(row) self.files_list.insertItem(row - 1, item) def move_file_down(self): sorted_selected_items = self.get_sorted_selected_items(descending=True) if (self.files_list.count() - 1) not in sorted_selected_items: for row in sorted_selected_items: item = self.files_list.takeItem(row) self.files_list.insertItem(row + 1, item) def get_sorted_selected_items(self, descending=False): items_list = [] for item in self.files_list.selectedItems(): items_list.append(self.files_list.row(item)) return sorted(items_list, key=int, reverse=descending) def remove_file(self): for item in self.files_list.selectedItems(): row = self.files_list.row(item) self.files_list.takeItem(row) def select_save_path(self): fname, _ = QFileDialog.getSaveFileName(self, 'Save file', QDir.homePath(), "*.pdf") self.dest_path_edit.setText(fname) def merge_pdf(self): save_path = self.dest_path_edit.text() if save_path is '': raise Exception( QMessageBox.warning( self, 'Warning!', 'No location to save file selected.\n' + 'Cannot proceed with merger.')) input_files = [] for i in range(0, self.files_list.count()): file_path = self.files_list.item(i).text() if '.pdf' not in file_path and '.PDF' not in file_path: QMessageBox.warning( self, 'Warning!', 'Some files not PDFs\n' + 'Please examine' + file_path) raise Exception("PDF file error!") else: input_files.append(file_path) if len(input_files) >= 2: merge_pdf(destination=save_path, pdf_files=input_files) else: QMessageBox.warning( self, 'Warning!', 'Not enough PDFs selected.\n' + 'Please choose 2 or more files to merge.')
class beso_gui(QDialog): def __init__(self): super().__init__() self.title = 'BESO Topology Optimization (experimental)' self.left = 250 self.top = 30 self.width = 550 self.height = 730 beso_gui.inp_file = "" beso_gui.beso_dir = os.path.dirname(__file__) self.initUI() # def closeEvent(self, event): # self.close() 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() # @pyqtSlot() def on_click(self): ex2 = SelectFile() self.show() self.textbox_file_name.setText(self.inp_file) def on_click1(self): # get material objects self.materials = [] self.thicknesses = [] for obj in App.ActiveDocument.Objects: if obj.Name[:23] in ["MechanicalSolidMaterial", "SolidMaterial"]: self.materials.append(obj) elif obj.Name[:17] == "ElementGeometry2D": self.thicknesses.append(obj) # update materials combo boxes self.combo.clear() self.combo.addItem("None") self.combo1.clear() self.combo1.addItem("None") self.combo2.clear() self.combo2.addItem("None") self.combo0t.clear() self.combo0t.addItem("None") self.combo1t.clear() self.combo1t.addItem("None") self.combo2t.clear() self.combo2t.addItem("None") self.widget.clear() self.widget.addItem("All defined") self.widget.addItem("Domain 0") self.widget.addItem("Domain 1") self.widget.addItem("Domain 2") self.widget.setCurrentItem(self.widget.item(0)) self.widget1.clear() self.widget1.addItem("All defined") self.widget1.addItem("Domain 0") self.widget1.addItem("Domain 1") self.widget1.addItem("Domain 2") self.widget1.setCurrentItem(self.widget1.item(0)) self.widget2.clear() self.widget2.addItem("All defined") self.widget2.addItem("Domain 0") self.widget2.addItem("Domain 1") self.widget2.addItem("Domain 2") self.widget2.setCurrentItem(self.widget2.item(0)) for mat in self.materials: self.combo.addItem(mat.Label) self.combo1.addItem(mat.Label) self.combo2.addItem(mat.Label) if self.materials: self.combo.setCurrentIndex(1) for th in self.thicknesses: self.combo0t.addItem(th.Label) self.combo1t.addItem(th.Label) self.combo2t.addItem(th.Label) def on_click21(self): """Overwrite beso_conf.py file in the macro directory""" file_name = os.path.split(self.textbox_file_name.text())[1] path = os.path.split(self.textbox_file_name.text())[0] fea = ccxtools.FemToolsCcx() fea.setup_ccx() path_calculix = fea.ccx_binary optimization_base = self.combo51.currentText() elset_id = self.combo.currentIndex() - 1 thickness_id = self.combo0t.currentIndex() - 1 if elset_id != -1: if thickness_id != -1: elset = self.materials[elset_id].Name + self.thicknesses[ thickness_id].Name else: # 0 means None thickness selected elset = self.materials[elset_id].Name + "Solid" modulus = float( self.materials[elset_id].Material["YoungsModulus"].split() [0]) # MPa if self.materials[elset_id].Material["YoungsModulus"].split( )[1] != "MPa": raise Exception(" units not recognised in " + self.materials[elset_id].Name) poisson = float( self.materials[elset_id].Material["PoissonRatio"].split()[0]) try: density = float(self.materials[elset_id].Material["Density"]. split()[0]) * 1e-12 # kg/m3 -> t/mm3 if self.materials[elset_id].Material["Density"].split( )[1] not in ["kg/m^3", "kg/m3"]: raise Exception(" units not recognised in " + self.materials[elset_id].Name) except KeyError: density = 0. try: conductivity = float( self.materials[elset_id].Material["ThermalConductivity"]. split()[0]) # W/m/K if self.materials[elset_id].Material[ "ThermalConductivity"].split()[1] != "W/m/K": raise Exception(" units not recognised in " + self.materials[elset_id].Name) except KeyError: conductivity = 0. try: if self.materials[elset_id].Material[ "ThermalExpansionCoefficient"].split()[1] == "um/m/K": expansion = float(self.materials[elset_id]. Material["ThermalExpansionCoefficient"]. split()[0]) * 1e-6 # um/m/K -> mm/mm/K elif self.materials[elset_id].Material[ "ThermalExpansionCoefficient"].split()[1] == "m/m/K": expansion = float( self.materials[elset_id]. Material["ThermalExpansionCoefficient"].split() [0]) # m/m/K -> mm/mm/K else: raise Exception(" units not recognised in " + self.materials[elset_id].Name) except KeyError: expansion = 0. try: specific_heat = float( self.materials[elset_id].Material["SpecificHeat"].split() [0]) * 1e6 # J/kg/K -> mm^2/s^2/K if self.materials[elset_id].Material["SpecificHeat"].split( )[1] != "J/kg/K": raise Exception(" units not recognised in " + self.materials[elset_id].Name) except KeyError: specific_heat = 0. if thickness_id != -1: thickness = str( self.thicknesses[thickness_id].Thickness).split()[0] # mm if str(self.thicknesses[thickness_id].Thickness).split( )[1] != "mm": raise Exception(" units not recognised in " + self.thicknesses[thickness_id].Name) else: thickness = 0. optimized = self.checkbox.isChecked() if self.textbox.text(): von_mises = float(self.textbox.text()) else: von_mises = 0. elset_id1 = self.combo1.currentIndex() - 1 thickness_id1 = self.combo0t.currentIndex() - 1 if elset_id1 != -1: if thickness_id1 != -1: elset1 = self.materials[elset_id1].Name + self.thicknesses[ thickness_id1].Name else: # 0 means None thickness selected elset1 = self.materials[elset_id1].Name + "Solid" modulus1 = float( self.materials[elset_id1].Material["YoungsModulus"].split() [0]) # MPa if self.materials[elset_id1].Material["YoungsModulus"].split( )[1] != "MPa": raise Exception(" units not recognised in " + self.materials[elset_id1].Name) poisson1 = float( self.materials[elset_id1].Material["PoissonRatio"].split()[0]) try: density1 = float(self.materials[elset_id1].Material["Density"]. split()[0]) * 1e-12 # kg/m3 -> t/mm3 if self.materials[elset_id1].Material["Density"].split( )[1] not in ["kg/m^3", "kg/m3"]: raise Exception(" units not recognised in " + self.materials[elset_id1].Name) except KeyError: density1 = 0. try: conductivity1 = float( self.materials[elset_id1].Material["ThermalConductivity"]. split()[0]) # W/m/K if self.materials[elset_id1].Material[ "ThermalConductivity"].split()[1] != "W/m/K": raise Exception(" units not recognised in " + self.materials[elset_id1].Name) except KeyError: conductivity1 = 0. try: if self.materials[elset_id1].Material[ "ThermalExpansionCoefficient"].split()[1] == "um/m/K": expansion1 = float(self.materials[elset_id1]. Material["ThermalExpansionCoefficient"]. split()[0]) * 1e-6 # um/m/K -> mm/mm/K elif self.materials[elset_id1].Material[ "ThermalExpansionCoefficient"].split()[1] == "m/m/K": expansion1 = float( self.materials[elset_id1]. Material["ThermalExpansionCoefficient"].split() [0]) # m/m/K -> mm/mm/K else: raise Exception(" units not recognised in " + self.materials[elset_id1].Name) except KeyError: expansion1 = 0. try: specific_heat1 = float( self.materials[elset_id1].Material["SpecificHeat"].split() [0]) * 1e6 # J/kg/K -> mm^2/s^2/K if self.materials[elset_id1].Material["SpecificHeat"].split( )[1] != "J/kg/K": raise Exception(" units not recognised in " + self.materials[elset_id1].Name) except KeyError: specific_heat1 = 0. if thickness_id1 != -1: thickness1 = str( self.thicknesses[thickness_id1].Thickness).split()[0] # mm if str(self.thicknesses[thickness_id1].Thickness).split( )[1] != "mm": raise Exception(" units not recognised in " + self.thicknesses[thickness_id1].Name) else: thickness1 = 0. optimized1 = self.checkbox1.isChecked() if self.textbox1.text(): von_mises1 = float(self.textbox1.text()) else: von_mises1 = 0. elset_id2 = self.combo2.currentIndex() - 1 thickness_id2 = self.combo0t.currentIndex() - 1 if elset_id2 != -1: if thickness_id2 != -1: elset2 = self.materials[elset_id2].Name + self.thicknesses[ thickness_id2].Name else: # 0 means None thickness selected else2t = self.materials[elset_id2].Name + "Solid" modulus2 = float( self.materials[elset_id2].Material["YoungsModulus"].split() [0]) # MPa if self.materials[elset_id2].Material["YoungsModulus"].split( )[1] != "MPa": raise Exception(" units not recognised in " + self.materials[elset_id2].Name) poisson2 = float( self.materials[elset_id2].Material["PoissonRatio"].split()[0]) try: density2 = float(self.materials[elset_id2].Material["Density"]. split()[0]) * 1e-12 # kg/m3 -> t/mm3 if self.materials[elset_id2].Material["Density"].split( )[1] not in ["kg/m^3", "kg/m3"]: raise Exception(" units not recognised in " + self.materials[elset_id2].Name) except KeyError: density2 = 0. try: conductivity2 = float( self.materials[elset_id2].Material["ThermalConductivity"]. split()[0]) # W/m/K if self.materials[elset_id2].Material[ "ThermalConductivity"].split()[1] != "W/m/K": raise Exception(" units not recognised in " + self.materials[elset_id2].Name) except KeyError: conductivity2 = 0. try: if self.materials[elset_id2].Material[ "ThermalExpansionCoefficient"].split()[1] == "um/m/K": expansion2 = float(self.materials[elset_id2]. Material["ThermalExpansionCoefficient"]. split()[0]) * 1e-6 # um/m/K -> mm/mm/K elif self.materials[elset_id2].Material[ "ThermalExpansionCoefficient"].split()[1] == "m/m/K": expansion2 = float( self.materials[elset_id2]. Material["ThermalExpansionCoefficient"].split() [0]) # m/m/K -> mm/mm/K else: raise Exception(" units not recognised in " + self.materials[elset_id2].Name) except KeyError: expansion2 = 0. try: specific_heat2 = float( self.materials[elset_id2].Material["SpecificHeat"].split() [0]) * 1e6 # J/kg/K -> mm^2/s^2/K if self.materials[elset_id2].Material["SpecificHeat"].split( )[1] != "J/kg/K": raise Exception(" units not recognised in " + self.materials[elset_id2].Name) except KeyError: specific_heat2 = 0. if thickness_id2 != -1: thickness2 = str( self.thicknesses[thickness_id2].Thickness).split()[0] # mm if str(self.thicknesses[thickness_id2].Thickness).split( )[1] != "mm": raise Exception(" units not recognised in " + self.thicknesses[thickness_id2].Name) else: thickness2 = 0. optimized2 = self.checkbox2.isChecked() if self.textbox2.text(): von_mises2 = float(self.textbox2.text()) else: von_mises2 = 0. with open(os.path.join(self.beso_dir, "beso_conf.py"), "w") as f: f.write( "# This is the configuration file with input parameters. It will be executed as python commands\n" ) f.write("# Written by beso_fc_gui.py at {}\n".format( datetime.datetime.now())) f.write("\n") f.write("path_calculix = '{}'\n".format(path_calculix)) f.write("path = '{}'\n".format(path)) f.write("file_name = '{}'\n".format(file_name)) f.write("\n") if elset_id != -1: f.write("elset_name = '{}'\n".format(elset)) f.write( "domain_optimized[elset_name] = {}\n".format(optimized)) f.write("domain_density[elset_name] = [{}, {}]\n".format( density * 1e-6, density)) if thickness: f.write("domain_thickness[elset_name] = [{}, {}]\n".format( thickness, thickness)) if von_mises: f.write( "domain_FI[elset_name] = [[('stress_von_Mises', {:.6})],\n" .format(von_mises * 1e6)) f.write( " [('stress_von_Mises', {:.6})]]\n" .format(von_mises)) f.write( "domain_material[elset_name] = ['*ELASTIC\\n{:.6}, {}\\n*DENSITY\\n{:.6}\\n*CONDUCTIVITY\\n" "{:.6}\\n*EXPANSION\\n{:.6}\\n*SPECIFIC HEAT\\n{:.6}\\n',\n" .format(modulus * 1e-6, poisson, density * 1e-6, conductivity * 1e-6, expansion * 1e-6, specific_heat * 1e-6)) f.write( " '*ELASTIC\\n{:.6}, {:.6}\\n*DENSITY\\n{:.6}\\n*CONDUCTIVITY\\n" "{:.6}\\n*EXPANSION\\n{:.6}\\n*SPECIFIC HEAT\\n{:.6}\\n']\n" .format(modulus, poisson, density, conductivity, expansion, specific_heat)) f.write("\n") if elset_id1 != -1: f.write("elset_name = '{}'\n".format(elset1)) f.write( "domain_optimized[elset_name] = {}\n".format(optimized1)) f.write("domain_density[elset_name] = [{}, {}]\n".format( density1 * 1e-6, density1)) if thickness1: f.write("domain_thickness[elset_name] = [{}, {}]\n".format( thickness1, thickness1)) if von_mises1: f.write( "domain_FI[elset_name] = [[('stress_von_Mises', {:.6})],\n" .format(von_mises1 * 1e6)) f.write( " [('stress_von_Mises', {:.6})]]\n" .format(von_mises1)) f.write( "domain_material[elset_name] = ['*ELASTIC\\n{:.6}, {:.6}\\n*DENSITY\\n{:.6}\\n*CONDUCTIVITY" "\\n{:.6}\\n*EXPANSION\\n{:.6}\\n*SPECIFIC HEAT\\n{:.6}\\n',\n" .format(modulus1 * 1e-6, poisson1, density1 * 1e-6, conductivity1 * 1e-6, expansion1 * 1e-6, specific_heat1 * 1e-6)) f.write( " '*ELASTIC\\n{:.6}, {:.6}\\n*DENSITY\\n{:.6}\\n*CONDUCTIVITY\\n" "{:.6}\\n" "*EXPANSION\\n{:.6}\\n*SPECIFIC HEAT\\n{:.6}\\n']\n". format(modulus1, poisson1, density1, conductivity1, expansion1, specific_heat1)) f.write("\n") if elset_id2 != -1: f.write("elset_name = '{}'\n".format(elset2)) f.write( "domain_optimized[elset_name] = {}\n".format(optimized2)) f.write("domain_density[elset_name] = [{}, {}]\n".format( density2 * 1e-6, density2)) if thickness2: f.write("domain_thickness[elset_name] = [{}, {}]\n".format( thickness2, thickness2)) if von_mises2: f.write( "domain_FI[elset_name] = [[('stress_von_Mises', {:.6})],\n" .format(von_mises2 * 1e6)) f.write( " [('stress_von_Mises', {:.6})]]\n" .format(von_mises2)) f.write( "domain_material[elset_name] = ['*ELASTIC\\n{:.6}, {:.6}\\n*DENSITY\\n{:.6}\\n*CONDUCTIVITY" "\\n{:.6}\\n*EXPANSION\\n{:.6}\\n*SPECIFIC HEAT\\n{:.6}\\n',\n" .format(modulus2 * 1e-6, poisson2, density2 * 1e-6, conductivity2 * 1e-6, expansion2 * 1e-6, specific_heat2 * 1e-6)) f.write( " '*ELASTIC\\n{:.6}, {:.6}\\n*DENSITY\\n{:.6}\\n*CONDUCTIVITY\\n" "{:.6}\\n*EXPANSION\\n{:.6}\\n*SPECIFIC HEAT\\n{:.6}\\n']\n" .format(modulus2, poisson2, density2, conductivity2, expansion2, specific_heat2)) f.write("\n") f.write("mass_goal_ratio = " + self.textbox52.text()) f.write("\n") f.write("filter_list = [") filter = self.combo6.currentText() range = self.textbox6.text() direction = self.textbox9.text() selection = [item.text() for item in self.widget.selectedItems()] filter_domains = [] if "All defined" not in selection: if "Domain 0" in selection: filter_domains.append(elset) if "Domain 1" in selection: filter_domains.append(elset1) if "Domain 2" in selection: filter_domains.append(elset2) if filter == "simple": f.write("['simple', {}".format(range)) for dn in filter_domains: f.write(", '{}'".format(dn)) f.write("],\n") elif filter == "casting": f.write("['casting', {}, ({})".format(range, direction)) for dn in filter_domains: f.write(", '{}'".format(dn)) f.write("],\n") filter1 = self.combo7.currentText() range1 = self.textbox7.text() direction1 = self.textbox10.text() selection = [item.text() for item in self.widget1.selectedItems()] filter_domains1 = [] if "All defined" not in selection: if "Domain 0" in selection: filter_domains1.append(elset) if "Domain 1" in selection: filter_domains1.append(elset1) if "Domain 2" in selection: filter_domains1.append(elset2) if filter1 == "simple": f.write(" ['simple', {}".format(range1)) for dn in filter_domains1: f.write(", '{}'".format(dn)) f.write("],\n") elif filter1 == "casting": f.write(" ['casting', {}, ({})".format( range1, direction1)) for dn in filter_domains1: f.write(", '{}'".format(dn)) f.write("],\n") filter2 = self.combo8.currentText() range2 = self.textbox8.text() direction2 = self.textbox11.text() selection = [item.text() for item in self.widget2.selectedItems()] filter_domains2 = [] if "All defined" not in selection: if "Domain 0" in selection: filter_domains2.append(elset) if "Domain 1" in selection: filter_domains2.append(elset1) if "Domain 2" in selection: filter_domains2.append(elset2) if filter2 == "simple": f.write(" ['simple', {}".format(range2)) for dn in filter_domains2: f.write(", '{}'".format(dn)) f.write("],\n") elif filter2 == "casting": f.write(" ['casting', {}, ({})".format( range2, direction2)) for dn in filter_domains2: f.write(", '{}'".format(dn)) f.write("],\n") f.write(" ]\n") f.write("\n") f.write("optimization_base = '{}'\n".format(optimization_base)) f.write("\n") slider_position = self.slider.value() if slider_position == 1: f.write("mass_addition_ratio = 0.01\n") f.write("mass_removal_ratio = 0.02\n") if slider_position == 2: f.write("mass_addition_ratio = 0.015\n") f.write("mass_removal_ratio = 0.03\n") if slider_position == 3: f.write("mass_addition_ratio = 0.03\n") f.write("mass_removal_ratio = 0.06\n") f.write("ratio_type = 'relative'\n") f.write("\n") def on_click22(self): """Open beso_conf.py in FreeCAD editor""" FreeCADGui.insert(os.path.join(self.beso_dir, "beso_conf.py")) def on_click23(self): """"Run optimization""" # run in own thread (not freezing FreeCAD): needs also to comment "plt.show()" on the end of beso_main.py # self.optimization_thread = RunOptimization("beso_main") # self.optimization_thread.start() # run in foreground (freeze FreeCAD) exec(open(os.path.join(beso_gui.beso_dir, "beso_main.py")).read()) def on_click24(self): self.on_click21() # generate beso_conf.py self.on_click23() # run optimization def on_click31(self): webbrowser.open_new_tab( "https://github.com/fandaL/beso/wiki/Example-4:-GUI-in-FreeCAD") def on_click32(self): webbrowser.open_new_tab( "https://github.com/fandaL/beso/blob/master/beso_conf.py") def on_click33(self): self.close() def on_click40(self): """Open log file""" if self.textbox_file_name.text() in [ "None analysis file selected", "" ]: print("None analysis file selected") else: log_file = os.path.normpath(self.textbox_file_name.text()[:-4] + ".log") webbrowser.open(log_file) def on_change(self): if self.combo.currentText() == "None": self.combo0t.setEnabled(False) self.checkbox.setEnabled(False) self.textbox.setEnabled(False) else: self.combo0t.setEnabled(True) self.checkbox.setEnabled(True) self.textbox.setEnabled(True) def on_change1(self): if self.combo1.currentText() == "None": self.combo1t.setEnabled(False) self.checkbox1.setEnabled(False) self.textbox1.setEnabled(False) else: self.combo1t.setEnabled(True) self.checkbox1.setEnabled(True) self.textbox1.setEnabled(True) def on_change2(self): if self.combo2.currentText() == "None": self.combo2t.setEnabled(False) self.checkbox2.setEnabled(False) self.textbox2.setEnabled(False) else: self.combo2t.setEnabled(True) self.checkbox2.setEnabled(True) self.textbox2.setEnabled(True) def on_change6(self): if self.combo6.currentText() == "None": self.textbox6.setEnabled(False) self.textbox9.setEnabled(False) self.widget.setEnabled(False) elif self.combo6.currentText() == "casting": self.textbox6.setEnabled(True) self.textbox9.setEnabled(True) self.widget.setEnabled(True) else: self.textbox6.setEnabled(True) self.textbox9.setEnabled(False) self.widget.setEnabled(True) def on_change7(self): if self.combo7.currentText() == "None": self.textbox7.setEnabled(False) self.textbox10.setEnabled(False) self.widget1.setEnabled(False) elif self.combo7.currentText() == "casting": self.textbox7.setEnabled(True) self.textbox10.setEnabled(True) self.widget1.setEnabled(True) else: self.textbox7.setEnabled(True) self.textbox10.setEnabled(False) self.widget1.setEnabled(True) def on_change8(self): if self.combo8.currentText() == "None": self.textbox8.setEnabled(False) self.textbox11.setEnabled(False) self.widget2.setEnabled(False) elif self.combo8.currentText() == "casting": self.textbox8.setEnabled(True) self.textbox11.setEnabled(True) self.widget2.setEnabled(True) else: self.textbox8.setEnabled(True) self.textbox11.setEnabled(False) self.widget2.setEnabled(True)
class TagSelecion(QGroupBox): def __init__(self, parent=None, opc=None): super(TagSelecion, self).__init__() self.opc = opc self.setTitle('Tag Selection') self.layout = QVBoxLayout(self) self.button_refresh = QPushButton('Refresh', self) self.button_refresh.clicked.connect(self._refresh) self.layout.addWidget(self.button_refresh) self.button_all = QPushButton('Select All', self) self.button_all.clicked.connect(self._select_all) self.layout.addWidget(self.button_all) self.button_none = QPushButton('Select None', self) self.button_none.clicked.connect(self._select_none) self.layout.addWidget(self.button_none) self.hbox_pattern = QHBoxLayout(self) self.button_pattern = QPushButton('Toggle Pattern', self) self.button_pattern.clicked.connect(self._toggle_pattern) self._next_toggle = 'select' self.hbox_pattern.addWidget(self.button_pattern) self.le_pattern = QLineEdit(self) self.le_pattern.setPlaceholderText('Pattern') self.hbox_pattern.addWidget(self.le_pattern) self.layout.addLayout(self.hbox_pattern) self.label = QLabel('Select Tags', self) self.layout.addWidget(self.label) self.listw_tags = QListWidget(self) self.listw_tags.setSelectionMode(QAbstractItemView.MultiSelection) self.layout.addWidget(self.listw_tags) self.setLayout(self.layout) def selected_tags(self): return [item.text() for item in self.listw_tags.selectedItems()] def _refresh(self): self.tags_all = opcda.tags(self.opc) self.listw_tags.clear() self.listw_tags.addItems(self.tags_all) def _select_all(self): self.listw_tags.selectAll() def _select_none(self): self.listw_tags.clearSelection() def _toggle_pattern(self): toggle = self._next_toggle if toggle is 'select': self._next_toggle = 'deselect' elif toggle is 'deselect': self._next_toggle = 'select' pattern = self.le_pattern.text().lower() if len(pattern) is 0: matched_tags = [] else: matched_tags = [ tag for tag in self.tags_all if pattern in tag.lower() ] for tag in matched_tags: item = self.listw_tags.findItems(tag, Qt.MatchExactly)[0] if toggle is 'select': item.setSelected(True) elif toggle is 'deselect': item.setSelected(False)
class ProfileSelection(QDialog): ''' classdocs ''' removeProfile = Signal(Athlete_Model) profileSelected = Signal(Athlete_Model) profileUpdate_request = Signal(Athlete_Model, Athlete_Model) lastProfileDeleted = Signal() def __init__(self, athletesList): ''' Constructor ''' QDialog.__init__(self) self.setWindowTitle("Profile Selection") self.athletesList = athletesList self._initGUI() def _initGUI(self): topHLayout = QHBoxLayout() hLayout = QHBoxLayout() vLayout = QVBoxLayout() # Label greeterText = QLabel("Welcome to <b>Pushup app</b>." + \ "<br><br> Select a profile:") vLayout.addWidget(greeterText) # List self.list = QListWidget() self.list.setMinimumWidth(150) self.list.setSelectionMode(QAbstractItemView.SingleSelection) # SingleSelection is the default value, but I prefer to be sure self.list.itemSelectionChanged.connect(self._activateButtons) for athlete in self.athletesList: iconW = QIcon.fromTheme("user-available") # doens't work on Mac and Windows # http://qt-project.org/doc/qt-4.8/qicon.html#fromTheme listW = QListWidgetItem(iconW, athlete._name) listW.setData(Qt.UserRole, athlete) self.list.addItem(listW) topHLayout.addWidget(self.list) self.profileWidget = ProfileFormWidget() self.profileWidget.hide() topHLayout.addWidget(self.profileWidget) vLayout.addLayout(topHLayout) vLayout.addLayout(hLayout) # Buttons self.okBtn = QPushButton("Ok") self.okBtn.setDisabled(True) self.okBtn.setDefault(True) self.okBtn.clicked.connect(self._okButtonSlot) self.list.itemDoubleClicked.connect(self._okButtonSlot) cancelBtn = QPushButton("Cancel") cancelBtn.clicked.connect(self._cancelButtonSlot) self.editBtn = QPushButton("Edit") self.editBtn.setDisabled(True) self.editBtn.setCheckable(True) self.editBtn.clicked.connect(self._toggleProfileEdit) self.saveBtn = QPushButton("Save changes") # Saves the changes made on the profile self.saveBtn.hide() self.saveBtn.clicked.connect(self._saveButtonSlot) self.removeProfileBtn = QPushButton("Remove Profile") self.removeProfileBtn.setDisabled(True) self.removeProfileBtn.clicked.connect(self._removeProfile_Dialog) hLayout.addWidget(self.editBtn) hLayout.addWidget(self.removeProfileBtn) hLayout.addWidget(cancelBtn) hLayout.addWidget(self.okBtn) hLayout.addWidget(self.saveBtn) self.setLayout(vLayout) def getSelectedProfile(self): selectedListItem = self.list.selectedItems()[0] athleteProfile = selectedListItem.data(Qt.UserRole) return athleteProfile def updateList(self, athletes): self.list.clear() self.athletesList = athletes for athlete in self.athletesList: iconW = QIcon.fromTheme("user-available") # doens't work on Mac and Windows # http://qt-project.org/doc/qt-4.8/qicon.html#fromTheme listW = QListWidgetItem(iconW, athlete._name) listW.setData(Qt.UserRole, athlete) self.list.addItem(listW) def resetWidget(self): """ Resets the widget to the initial laoyout. Should be used only in specific cases """ self.editBtn.setChecked(False) self._toggleProfileEdit() def _removeProfile_Dialog(self): """Runs a prompt dialog. Ask the user if he really wants to remove the selected profile. """ confirmationDialog = QMessageBox() confirmationDialog.setText("Do you really want to remove the selected profile ?") confirmationDialog.setInformativeText("Profile deletion can not be undone") confirmationDialog.setIcon(QMessageBox.Question) confirmationDialog.setStandardButtons(QMessageBox.Yes | QMessageBox.No) confirmationDialog.accepted.connect(self._emitRemoveProfile) ret = confirmationDialog.exec_() if ret==QMessageBox.Yes: self._emitRemoveProfile() def _emitRemoveProfile(self): athlete = self.getSelectedProfile() rowToDelete = 0 for index, element in enumerate(self.athletesList): if element == athlete: rowToDelete = index self.list.takeItem(rowToDelete) self.athletesList.remove(athlete) self.removeProfile.emit(athlete) def _okButtonSlot(self): athlete = self.list.selectedItems()[0].data(Qt.UserRole) self.accept() # is it correct ? Maybe self.close() is better ? # Or should I redefine the accept() method ? #athleteProfile = self.getSelectedProfile() self.profileSelected.emit(athlete) def _cancelButtonSlot(self): if len(self.athletesList) == 0: self.lastProfileDeleted.emit() self.reject() def _saveButtonSlot(self): selectedProfile = self.getSelectedProfile() updatedProfile = self.profileWidget.getProfile() self.profileUpdate_request.emit(selectedProfile, updatedProfile) #self._toggleProfileEdit() def _toggleProfileEdit(self): if self.editBtn.isChecked(): self.profileWidget.setProfile(self.getSelectedProfile()) self.profileWidget.show() self.saveBtn.show() self.okBtn.hide() self.removeProfileBtn.hide() else: self.saveBtn.hide() self.profileWidget.hide() self.okBtn.show() self.removeProfileBtn.show() def _activateButtons(self): selectedItems = self.list.selectedItems() if len(selectedItems)!=0 : self.okBtn.setDisabled(False) self.removeProfileBtn.setDisabled(False) self.editBtn.setDisabled(False) else : self.okBtn.setDisabled(True) self.removeProfileBtn.setDisabled(True) self.editBtn.setDisabled(True)
class RobocompDslGui(QMainWindow): def __init__(self, parent=None): super(RobocompDslGui, self).__init__(parent) self.setWindowTitle("Create new component") # self._idsl_paths = [] self._communications = { "implements": [], "requires": [], "subscribesTo": [], "publishes": [] } self._interfaces = {} self._cdsl_doc = CDSLDocument() self._command_process = QProcess() self._main_widget = QWidget() self._main_layout = QVBoxLayout() self.setCentralWidget(self._main_widget) self._name_layout = QHBoxLayout() self._name_line_edit = QLineEdit() self._name_line_edit.textEdited.connect(self.update_component_name) self._name_line_edit.setPlaceholderText("New component name") self._name_layout.addWidget(self._name_line_edit) self._name_layout.addStretch() # DIRECTORY SELECTION self._dir_line_edit = QLineEdit() # self._dir_line_edit.textEdited.connect(self.update_completer) self._dir_completer = QCompleter() self._dir_completer_model = QFileSystemModel() if os.path.isdir(ROBOCOMP_COMP_DIR): self._dir_line_edit.setText(ROBOCOMP_COMP_DIR) self._dir_completer_model.setRootPath(ROBOCOMP_COMP_DIR) self._dir_completer.setModel(self._dir_completer_model) self._dir_line_edit.setCompleter(self._dir_completer) self._dir_button = QPushButton("Select directory") self._dir_button.clicked.connect(self.set_output_directory) self._dir_layout = QHBoxLayout() self._dir_layout.addWidget(self._dir_line_edit) self._dir_layout.addWidget(self._dir_button) # LIST OF ROBOCOMP INTERFACES self._interface_list = QListWidget() self._interface_list.setSelectionMode( QAbstractItemView.ExtendedSelection) self._interface_list.itemSelectionChanged.connect( self.set_comunication) # LIST OF CONNECTION TyPES self._type_combo_box = QComboBox() self._type_combo_box.addItems( ["publishes", "implements", "subscribesTo", "requires"]) self._type_combo_box.currentIndexChanged.connect( self.reselect_existing) # BUTTON TO ADD A NEW CONNECTION # self._add_connection_button = QPushButton("Add") # self._add_connection_button.clicked.connect(self.add_new_comunication) self._add_connection_layout = QHBoxLayout() # self._add_connection_layout.addWidget(self._add_connection_button) self._language_combo_box = QComboBox() self._language_combo_box.addItems(["Python", "Cpp", "Cpp11"]) self._language_combo_box.currentIndexChanged.connect( self.update_language) self._add_connection_layout.addWidget(self._language_combo_box) self._add_connection_layout.addStretch() self._gui_check_box = QCheckBox() self._gui_check_box.stateChanged.connect(self.update_gui_selection) self._gui_label = QLabel("Use Qt GUI") self._add_connection_layout.addWidget(self._gui_label) self._add_connection_layout.addWidget(self._gui_check_box) # WIDGET CONTAINING INTERFACES AND TYPES self._selection_layout = QVBoxLayout() self._selection_layout.addWidget(self._type_combo_box) self._selection_layout.addWidget(self._interface_list) self._selection_layout.addLayout(self._add_connection_layout) self._selection_widget = QWidget() self._selection_widget.setLayout(self._selection_layout) # TEXT EDITOR WITH THE RESULTING CDSL CODE self._editor = QTextEdit(self) self._editor.setHtml("") self._document = self._editor.document() self._component_directory = None # SPLITTER WITH THE SELECTION AND THE CODE self._body_splitter = QSplitter(Qt.Horizontal) self._body_splitter.addWidget(self._selection_widget) self._body_splitter.addWidget(self._editor) self._body_splitter.setStretchFactor(0, 2) self._body_splitter.setStretchFactor(1, 9) # CREATION BUTTONS self._create_button = QPushButton("Create .cdsl") self._create_button.clicked.connect(self.write_cdsl_file) self._creation_layout = QHBoxLayout() self._creation_layout.addStretch() self._creation_layout.addWidget(self._create_button) self._console = QConsole() self._command_process.readyReadStandardOutput.connect( self._console.standard_output) self._command_process.readyReadStandardError.connect( self._console.error_output) # ADDING WIDGETS TO MAIN LAYOUT self._main_widget.setLayout(self._main_layout) self._main_layout.addLayout(self._name_layout) self._main_layout.addLayout(self._dir_layout) self._main_layout.addWidget(self._body_splitter) self._main_layout.addLayout(self._creation_layout) self._main_layout.addWidget(self._console) self.setMinimumSize(800, 500) self._editor.setText(self._cdsl_doc.generate_doc()) # self.editor->show(); # def update_completer(self, path): # print "update_completer %s"%path # info = QFileInfo(path) # if info.exists() and info.isDir(): # if not path.endswith(os.path.pathsep): # new_path = os.path.join(path, os.sep) # # self._dir_line_edit.setText(new_path) # all_dirs_output = [dI for dI in os.listdir(path) if os.path.isdir(os.path.join(path, dI))] # print all_dirs_output # self._dir_completer.complete() def load_idsl_files(self, fullpath=None): if fullpath is None: fullpath = ROBOCOMP_INTERFACES idsls_dir = os.path.join(ROBOCOMP_INTERFACES, "IDSLs") if os.path.isdir(idsls_dir): for full_filename in os.listdir(idsls_dir): file_name, file_extension = os.path.splitext(full_filename) if "idsl" in file_extension.lower(): full_idsl_path = os.path.join(idsls_dir, full_filename) # self._idsl_paths.append(os.path.join(idsls_dir,full_filename)) self.parse_idsl_file(full_idsl_path) self._interface_list.addItems(self._interfaces.keys()) def parse_idsl_file(self, fullpath): with open(fullpath, 'r') as fin: interface_name = None for line in fin: result = re.findall(r'^\s*interface\s+(\w+)\s*\{?\s*$', line, flags=re.MULTILINE) if len(result) > 0: interface_name = result[0] print("%s for idsl %s" % (interface_name, fullpath)) if interface_name is not None: self._interfaces[interface_name] = fullpath def add_new_comunication(self): interface_names = self._interface_list.selectedItems() com_type = str(self._type_combo_box.currentText()) for iface_name_item in interface_names: iface_name = str(iface_name_item.text()) self._communications[com_type].append(iface_name) idsl_full_path = self._interfaces[iface_name] idsl_full_filename = os.path.basename(idsl_full_path) self._cdsl_doc.add_comunication(com_type, iface_name) self._cdsl_doc.add_import(idsl_full_filename) self.update_editor() def set_comunication(self): interface_names = self._interface_list.selectedItems() com_type = str(self._type_combo_box.currentText()) self._communications[com_type] = [] self._cdsl_doc.clear_comunication(com_type) for iface_name_item in interface_names: iface_name = str(iface_name_item.text()) self._communications[com_type].append(iface_name) self._cdsl_doc.add_comunication(com_type, iface_name) self.update_imports() self.update_editor() def update_imports(self): self._cdsl_doc.clear_imports() for com_type in self._communications: for iface_name in self._communications[com_type]: idsl_full_path = self._interfaces[iface_name] idsl_full_filename = os.path.basename(idsl_full_path) self._cdsl_doc.add_import(idsl_full_filename) def update_language(self): language = self._language_combo_box.currentText() self._cdsl_doc.set_language(str(language)) self.update_editor() def update_gui_selection(self): checked = self._gui_check_box.isChecked() if checked: self._cdsl_doc.set_qui(True) else: self._cdsl_doc.set_qui(False) self.update_editor() def update_component_name(self, name): self._cdsl_doc.set_name(name) self.update_editor() def update_editor(self): self._editor.setText(self._cdsl_doc.generate_doc()) def set_output_directory(self): dir_set = False while not dir_set: dir = QFileDialog.getExistingDirectory( self, "Select Directory", ROBOCOMP_COMP_DIR, QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks) if self.check_dir_is_empty(str(dir)): self._dir_line_edit.setText(dir) dir_set = True def write_cdsl_file(self): component_dir = str(self._dir_line_edit.text()) text = self._cdsl_doc.generate_doc() if not self._name_line_edit.text(): component_name, ok = QInputDialog.getText(self, 'No component name set', 'Enter component name:') if ok: self.update_component_name(component_name) self._name_line_edit.setText(component_name) else: return False if not os.path.exists(component_dir): if QMessageBox.Yes == QMessageBox.question( self, "Directory doesn't exist.", "Do you want create the directory %s?" % component_dir, QMessageBox.Yes | QMessageBox.No): os.makedirs(component_dir) else: QMessageBox.question( self, "Directory not exist", "Can't create a component witout a valid directory") return False file_path = os.path.join(component_dir, str(self._name_line_edit.text()) + ".cdsl") if os.path.exists(file_path): if QMessageBox.No == QMessageBox.question( self, "File already exists", "Do you want to overwrite?", QMessageBox.Yes | QMessageBox.No): return False with open(file_path, 'w') as the_file: the_file.write(text) self.execute_robocomp_cdsl() return True def execute_robocomp_cdsl(self): cdsl_file_path = os.path.join( str(self._dir_line_edit.text()), str(self._name_line_edit.text()) + ".cdsl") command = "python -u %s/robocompdsl.py %s %s" % ( ROBOCOMPDSL_DIR, cdsl_file_path, os.path.join(str(self._dir_line_edit.text()))) self._console.append_custom_text("%s\n" % command) self._command_process.start(command, QProcess.Unbuffered | QProcess.ReadWrite) def reselect_existing(self): com_type = self._type_combo_box.currentText() selected = self._communications[com_type] self._interface_list.clearSelection() for iface in selected: items = self._interface_list.findItems(iface, Qt.MatchFlag.MatchExactly) if len(items) > 0: item = items[0] item.setSelected(True) def check_dir_is_empty(self, dir_path): if len(os.listdir(dir_path)) > 0: msgBox = QMessageBox() msgBox.setWindowTitle("Directory not empty") msgBox.setText( "The selected directory is not empty.\n" "For a new Component you usually want a new directory.\n" "Do you want to use this directory anyway?") msgBox.setStandardButtons(QMessageBox.Yes) msgBox.addButton(QMessageBox.No) msgBox.setDefaultButton(QMessageBox.No) if msgBox.exec_() == QMessageBox.Yes: return True else: return False else: return True
class MainControl(QWidget): toChangeChunk = Signal(tuple) toChangeSlice = Signal(int) def __init__(self, parent): super(MainControl, self).__init__(parent) self.parent = parent self.selectedMinerals = parent.selectedMinerals self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) lb0 = QLabel('Minecraft Prism chunk minerals finder') lb1 = QLabel('Chunk X') lb2 = QLabel('Chunk Z') lb3 = QLabel('Show deposits of:') lb4 = QLabel('Slice Elevation') #lb0.setFrameStyle(QFrame.Box) lb0.setAlignment(Qt.AlignVCenter | Qt.AlignCenter) lb2.setAlignment(Qt.AlignVCenter | Qt.AlignRight) self.txtChunkX = QLineEdit() self.txtChunkZ = QLineEdit() self.txtElevation = QLineEdit(str(self.parent.presenter.elevation)) self.txtChunkX.setAlignment(Qt.AlignVCenter | Qt.AlignCenter) self.txtChunkZ.setAlignment(Qt.AlignVCenter | Qt.AlignCenter) self.txtElevation.setAlignment(Qt.AlignVCenter | Qt.AlignCenter) self.btnViewChunk = QPushButton('View Chunk') self.btnViewChunk.clicked.connect(self.btnViewChunk_OnClick) self.btnSliceUp = QPushButton('Slice Up') self.btnSliceUp.clicked.connect(self.btnSliceUp_OnClick) self.btnSliceDown = QPushButton('Slice Down') self.btnSliceDown.clicked.connect(self.btnSliceDown_OnClick) self.lstMinerals = QListWidget() self.lstMinerals.setSelectionMode(QAbstractItemView.ExtendedSelection) self.lstMinerals.addItem(SelectedMineral('Gold', 14)) self.lstMinerals.addItem(SelectedMineral('Iron', 15)) self.lstMinerals.addItem(SelectedMineral('Diamond', 56)) self.lstMinerals.addItem(SelectedMineral('Redstone', 73)) self.lstMinerals.addItem(SelectedMineral('Obsidian', 49)) self.lstMinerals.addItem(SelectedMineral('Coal', 16)) self.lstMinerals.addItem(SelectedMineral('Lazurit', 21)) self.lstMinerals.setCurrentItem(self.lstMinerals.item(0)) self.lstMinerals.itemSelectionChanged.connect(self.onSelectedMinerals) elevBox = QHBoxLayout() elevBox.addWidget(lb4) elevBox.addWidget(self.txtElevation) elevBox.addWidget(self.btnSliceUp) elevBox.addWidget(self.btnSliceDown) ly = QGridLayout() ly.addWidget(lb0, 0, 0, 1, 4) ly.addWidget(lb1, 1, 0, 1, 1) ly.addWidget(self.txtChunkX, 1, 1, 1, 1) ly.addWidget(lb2, 1, 2, 1, 1) ly.addWidget(self.txtChunkZ, 1, 3, 1, 1) ly.addWidget(lb3, 2, 0, 1, 2) ly.addWidget(self.lstMinerals, 2, 2, 1, 2) ly.addWidget(self.btnViewChunk, 3, 1, 1, 2) ly.addLayout(elevBox, 4, 0, 1, 4) ly.setColumnStretch(0, 20) ly.setColumnStretch(1, 15) ly.setColumnStretch(2, 46) ly.setColumnStretch(3, 19) self.setLayout(ly) def sizeHint(self): return QSize(self.parent.controlsWidth, 180) def btnViewChunk_OnClick(self): chX = int(self.txtChunkX.text()) chZ = int(self.txtChunkZ.text()) self.toChangeChunk.emit((chX, chZ)) def btnSliceUp_OnClick(self): elev = int(self.txtElevation.text()) + 1 if elev < 64: self.toChangeSlice.emit(elev) self.txtElevation.setText(str(elev)) def btnSliceDown_OnClick(self): elev = int(self.txtElevation.text()) - 1 if elev > -1: self.toChangeSlice.emit(elev) self.txtElevation.setText(str(elev)) def onSelectedMinerals(self): selMin = [] for item in self.lstMinerals.selectedItems(): selMin.append(item.blockCode) self.parent.selectedMinerals.setSelectedMinerals(selMin)