def __init__(self, parent): QSqlTableModel.__init__(self, parent) self.setTable("t1") # 这一步应该是执行查询的操作,不太理解 self.select() # 数据更新的策略,详细可以查看Qt文档 self.setEditStrategy(QSqlTableModel.OnManualSubmit)
def __init__(self, m, connection): QAbstractItemModel.__init__(self, m) # попробуем сделать композицию self.dbmodel = QSqlTableModel(self, connection) self.dbmodel.setEditStrategy(0) # при каждом изменении поля #print (self.dbmodel.hasIndex(1,12)) self.headers=['id', '_buy', 'deadline', 'made', 'significance', 'urgency', '_children', '_next', '_parents', '_prev', 'season', 'short text', 'tags', 'text'] self.rootItem = TreeItem (self.headers)
def show(self, tab_wanted: str = 'general'): from genial.services import document_service if document_service.database is not None: if self.question_type_model is None: self.question_type_model = QSqlTableModel( self, document_service.database ) self.question_type_model.setTable("question_type") self.question_type_model.setEditStrategy( QSqlTableModel.OnManualSubmit ) self.question_type_filter_proxy_model = QuestionTypeFilterProxyModel() self.question_type_filter_proxy_model.setSourceModel( self.question_type_model ) self.question_type_filter_proxy_model.sort( self.question_type_model.fieldIndex("position"), Qt.AscendingOrder ) self.question_type_filter_proxy_model.setDynamicSortFilter(True) if self.controller is None: self.controller = PropertiesController() self.controller.start() self.controller.show(tab_wanted)
def __init__(self, tableName, parent=None): super(TableEditor, self).__init__(parent) self.model = QSqlTableModel(self) self.model.setTable(tableName) self.model.setEditStrategy(QSqlTableModel.OnManualSubmit) self.model.select() self.model.setHeaderData(0, Qt.Horizontal, "ID") self.model.setHeaderData(1, Qt.Horizontal, "First name") self.model.setHeaderData(2, Qt.Horizontal, "Last name") view = QTableView() view.setModel(self.model) submitButton = QPushButton("Submit") submitButton.setDefault(True) revertButton = QPushButton("&Revert") quitButton = QPushButton("Quit") buttonBox = QDialogButtonBox(Qt.Vertical) buttonBox.addButton(submitButton, QDialogButtonBox.ActionRole) buttonBox.addButton(revertButton, QDialogButtonBox.ActionRole) buttonBox.addButton(quitButton, QDialogButtonBox.RejectRole) submitButton.clicked.connect(self.submit) revertButton.clicked.connect(self.model.revertAll) quitButton.clicked.connect(self.close) mainLayout = QHBoxLayout() mainLayout.addWidget(view) mainLayout.addWidget(buttonBox) self.setLayout(mainLayout) self.setWindowTitle("Cached Table")
def showTable(self, table): """ Public slot to show the contents of a table. @param table name of the table to be shown (string) """ model = QSqlTableModel(self.table, self.connections.currentDatabase()) model.setEditStrategy(QSqlTableModel.OnRowChange) model.setTable(table) model.select() if model.lastError().type() != QSqlError.NoError: self.statusMessage.emit(model.lastError().text()) self.table.setModel(model) self.table.setEditTriggers(QAbstractItemView.DoubleClicked | QAbstractItemView.EditKeyPressed) self.table.resizeColumnsToContents() self.table.selectionModel().currentRowChanged.connect(self.updateActions) self.updateActions()
def data(self, index, role): if role < Qt.UserRole: return QSqlTableModel.data(self, index, role) record = self.record(index.row()) if role < Qt.UserRole + self.columnCount(): column = role - Qt.UserRole - 1 return record.value(column) dataValue = record.value('itemData') data = deserializeData(dataValue) if role == self.itemHtmlRole: return data.get(mimeHtml, '') if role == self.itemHasImage: return mimePng in data return None
def __init__(self,parent=None): logger.debug("_init__:begin") super(WinsWidgetView, self).__init__(parent) self.setupUi(self) self.dbPath="test.db" self.curTable="test2" self.setObjectName('winsWidget') self.setWindowFlags(Qt.FramelessWindowHint) self.setWindowTitle('wins的小工具') self.setWindowIcon(QIcon('icons/titleIcon.png')) self.tableModel=QSqlTableModel(self,QSqlDatabase.addDatabase('QSQLITE')) self.initThread() self.set_buttons() self.set_labels() self.set_lines() self.load_tableview() self.init_bottom() logger.debug("_init__:end")
def __init__(self,dbPath,tblName,parent=None): super(MainWindowView, self).__init__(parent) self.setupUi(self) self.addBtn.clicked.connect(self.addBtnFunc) self.updBtn.clicked.connect(self.updBtnFunc) self.delBtn.clicked.connect(self.delBtnFunc) self.dbPath="test.db" self.curTable="test2" ###tableView与model绑定 self.tableModel=QSqlTableModel(self,QSqlDatabase.addDatabase('QSQLITE')) self.tableModel.setEditStrategy(QSqlTableModel.OnManualSubmit) self.tableView.setModel(self.tableModel) ###self.model数据初始化 self.tableModel.database().setDatabaseName(self.dbPath) self.tableModel.database().open() self.tableModel.setTable(self.curTable) self.tableModel.select()
def __init__(self): super(MyMainWindowView, self).__init__() self.setupUi(self) self._selfSignal.connect(self.allBtnShow) self.actionAbout.triggered.connect(self.aboutFun) self.actionExit.triggered.connect(QApplication.instance().quit) self.actionChange_title.triggered.connect(self.changeTitle) self.qryBtn.clicked.connect(self.qryFunc) self.addBtn.clicked.connect(self.addFunc) self.delBtn.clicked.connect(self.delFunc) self.del2Btn.clicked.connect(self.del2Func) self.db=DBConn() #model 与 view绑定 self.myTableModel=QSqlTableModel(self) self.myTableModel.setTable("t1") self.myTableModel.select() self.myTableModel.setEditStrategy(QSqlTableModel.OnManualSubmit) # 数据更新的策略,详细可以查看Qt文档 self.myTableView.setModel(self.myTableModel) self.myTableView.setSelectionBehavior(QAbstractItemView.SelectRows) self.myTableView.setSelectionMode(QAbstractItemView.ExtendedSelection)
def __init__(self, list, table, addButton, editButton, deleteButton, dbase): super().__init__() self.list = list self.table = table self.addButton = addButton self.editButton = editButton self.deleteButton = deleteButton self.dbase = dbase self.shopModel = QSqlTableModel(db = dbase) self.shopModel.setTable("shop") self.shopModel.select() self.list.setModel(ComplexListModel(self.shopModel, "{name}")) self.list.selectionModel().currentChanged.connect(self.listSelectionChanged) self._checkPrivileges() if self.only_select: self.addButton.setEnabled(False) self.deleteButton.setEnabled(False) self.addButton.clicked.connect(self.addButtonClicked) self.editButton.clicked.connect(self.editButtonClicked) self.deleteButton.clicked.connect(self.deleteButtonClicked)
class MyMainWindowView(QMainWindow, Ui_myMainWindow): # 增加自定义信号 _selfSignal = QtCore.pyqtSignal(str) def __init__(self): super(MyMainWindowView, self).__init__() self.setupUi(self) self._selfSignal.connect(self.allBtnShow) self.actionAbout.triggered.connect(self.aboutFun) self.actionExit.triggered.connect(QApplication.instance().quit) self.actionChange_title.triggered.connect(self.changeTitle) self.qryBtn.clicked.connect(self.qryFunc) self.addBtn.clicked.connect(self.addFunc) self.delBtn.clicked.connect(self.delFunc) self.del2Btn.clicked.connect(self.del2Func) self.db=DBConn() #model 与 view绑定 self.myTableModel=QSqlTableModel(self) self.myTableModel.setTable("t1") self.myTableModel.select() self.myTableModel.setEditStrategy(QSqlTableModel.OnManualSubmit) # 数据更新的策略,详细可以查看Qt文档 self.myTableView.setModel(self.myTableModel) self.myTableView.setSelectionBehavior(QAbstractItemView.SelectRows) self.myTableView.setSelectionMode(QAbstractItemView.ExtendedSelection) # 增加自定义槽函数 def allBtnHide(self): print("test2") self.pushButton.hide() self.pushButton_2.hide() time.sleep(1) self._selfSignal.emit("我是自定义信号") # self.pushButton_3.hide() #增加自定义槽函数 def allBtnShow(self, signalstr): self.pushButton.show() self.pushButton_2.show() self.pushButton_3.setText(signalstr) # 增加自定义槽函数 def aboutFun(self): QMessageBox.about( self, 'PyQt', "About") def changeTitle(self): self.setWindowTitle("xxx Window") #查询按钮关联的槽函数 def qryFunc(self): #self.db.execSQL("select * from t1") QMessageBox.about( self, 'qryFuncCall', "qryFunc") #插入按钮关联的槽函数 def addFunc(self): # f1=random.randint(1, 9999) # sql = "insert into t1(f1,f2) values (%s,%s)"%(f1,f1) # self.db.execSQL(sql) f1=random.randint(1, 99) self.myTableModel.insertRows(0, 1) self.myTableModel.setData(self.myTableModel.index(0, 0), f1) self.myTableModel.setData(self.myTableModel.index(0, 1), "test") self.myTableModel.submitAll() QMessageBox.about( self, 'addFuncCall', "addFunc") # #删除按钮关联的槽函数 def del2Func(self): if self.myTableModel.select() : if self.myTableModel.rowCount() != 0: for i in self.myTableView.selectedIndexes(): self.myTableModel.removeRows(i.row(), 1) self.myTableModel.submitAll() # #删除按钮关联的槽函数 # def delFunc(self): # if self.myTableModel.select() : # if self.myTableModel.rowCount() != 0: # index = self.myTableView.currentIndex() # self.myTableModel.removeRows(0,1) # self.myTableModel.submitAll() # QMessageBox.about( self, 'delFuncCall', "delFunc") def delFunc(self): rs=list(map(lambda x:x.row(),self.myTableView.selectedIndexes())) if len(rs)==0: QMessageBox.information(self,'提醒','请先选中至少一行,再点击此按钮!') return for i in reversed(rs): self.myTableModel.removeRows(i,1) self.myTableModel.submitAll()
def __init__(self,dbPath,tblName='',parent=None): self.app=QApplication(sys.argv) self.SqliteDbTypes=['integer','real','text','blob'] self.DbPath,self.CurrentTable=dbPath,tblName #连接数据库 self.Db=sqlite3.connect(self.DbPath) #构建Gui组件 super(SqliteDbTableEditer,self).__init__(parent) self.setWindowTitle('Sqlite数据库表修改器') screen=QDesktopWidget().availableGeometry(0) self.setGeometry(screen.width()/3/2-1, screen.height()/5/2-1, screen.width()*2/3, screen.height()*4/5 ) #lay lay=QVBoxLayout() self.setLayout(lay) #数据库表设置控件 ##layDb layDb=QHBoxLayout() lay.addLayout(layDb) ###lblDb lblDb=QLabel('数据库:') layDb.addWidget(lblDb) ###self.leDb self.leDb=QLineEdit() self.leDb.setText(self.DbPath) layDb.addWidget(self.leDb) ###btnDb btnChangeDb=QPushButton('浏览') btnChangeDb.clicked.connect(self.btnChangeDb_Clicked) layDb.addWidget(btnChangeDb) ###lblTbl lblTbl=QLabel('数据表:') layDb.addWidget(lblTbl) ###self.cbbTbls self.cbbTbls=QComboBox() tbls=list(map(lambda x:x[1], list(filter(lambda x:x[0]=='table', self.Db.execute( 'Select * From sqlite_master' ).fetchall() ) ) ) ) self.cbbTbls.addItems(tbls) if self.CurrentTable!='' : self.cbbTbls.setCurrentIndex(tbls.index(self.CurrentTable)) else: self.CurrentTable=tbls[0] self.makeTableInfo() self.cbbTbls.setCurrentIndex(0) layDb.addWidget(self.cbbTbls) ###lblRename lblRename=QLabel('重命名为:') layDb.addWidget(lblRename) ###self.leRename self.leRename=QLineEdit() self.leRename.setFixedWidth(100) layDb.addWidget(self.leRename) ###btnRename btnRenameTable=QPushButton('重命名') btnRenameTable.clicked.connect(self.btnRenameTable_Clicked) layDb.addWidget(btnRenameTable) ###btnDeleteTable btnDeleteTable=QPushButton('删除表') btnDeleteTable.clicked.connect(self.btnDeleteTable_Clicked) layDb.addWidget(btnDeleteTable) ###btnShow self.btnShow=QPushButton('查看表结构') self.btnShow.clicked.connect(self.btnShow_Clicked) layDb.addWidget(self.btnShow) ###设置TableView控件self.tv,以呈现表数据 self.tv=QTableView() lay.addWidget(self.tv) ###self.model基本初始化 self.model=QSqlTableModel(self,QSqlDatabase.addDatabase('QSQLITE')) self.model.setEditStrategy(QSqlTableModel.OnFieldChange) ###self.tv链接到数据源 self.tv.setModel(self.model) ###self.model数据初始化 self.model.database().setDatabaseName(self.DbPath) self.model.database().open() self.model.setTable(self.CurrentTable) self.model.select() self.cbbTbls.currentIndexChanged.connect(self.changeTable) ##layBtns layBtns=QHBoxLayout() lay.addLayout(layBtns) ###btnAddColumn btnAddColumn=QPushButton('添加列') btnAddColumn.setToolTip('给当前表添加列') btnAddColumn.clicked.connect(self.btnAddColumn_Clicked) layBtns.addWidget(btnAddColumn) ###btnDeleteColumn btnDeleteColumn=QPushButton('删除列') btnDeleteColumn.setToolTip('删除当前表的列') btnDeleteColumn.clicked.connect(self.btnDeleteColumn_Clicked) layBtns.addWidget(btnDeleteColumn) ###btnRenameColumn btnRenameColumn=QPushButton('重命名列') btnRenameColumn.setToolTip('重命名当前表的列') btnRenameColumn.clicked.connect(self.btnRenameColumn_Clicked) layBtns.addWidget(btnRenameColumn) ###btnModifyColumnType btnModifyColumnType=QPushButton('修改列数据类型') btnModifyColumnType.setToolTip('修改当前表的列的数据类型') btnModifyColumnType.clicked.connect(self.btnModifyColumnType_Clicked) layBtns.addWidget(btnModifyColumnType) ###btnModifyColumnConstraint btnModifyColumnConstraint=QPushButton('修改列约束') btnModifyColumnConstraint.setToolTip('修改当前表的列的约束') btnModifyColumnConstraint.clicked.connect( self.btnModifyColumnConstraint_Clicked) layBtns.addWidget(btnModifyColumnConstraint) ###btnOrderColumns btnOrderColumns=QPushButton('调整列顺序') btnOrderColumns.setToolTip('调整当前表的列的顺序') btnOrderColumns.clicked.connect(self.btnOrderColumns_Clicked) layBtns.addWidget(btnOrderColumns) ###btnModifyTableStruct btnModifyTableStruct=QPushButton('修改表结构') btnModifyTableStruct.setToolTip('功能:1.增加列;2.删除列;' +'3.修改列名;4.修改列类型;' +'5.修改列约束;6.调整列顺序' ) btnModifyTableStruct.clicked.connect(self.btnModifyTableStruct_Clicked) layBtns.addWidget(btnModifyTableStruct) ###btnInsertRow btnInsertRow=QPushButton('插入行') btnInsertRow.setToolTip('将在数据表最后增加一行新记录') btnInsertRow.clicked.connect(self.btnInsertRow_Clicked) layBtns.addWidget(btnInsertRow) ###btnDeleteRows btnDeleteRows=QPushButton('删除行') btnDeleteRows.setToolTip('删除所有选中项所在的行') btnDeleteRows.clicked.connect(self.btnDeleteRows_Clicked) layBtns.addWidget(btnDeleteRows) ###btnQuery btnQuery=QPushButton('查询数据') btnQuery.setToolTip('对当前表或数据库进行查询,查询语句将被直接链接到self.model上') btnQuery.clicked.connect(self.btnQuery_Clicked) layBtns.addWidget(btnQuery) self.show() self.app.exec_()
class AppContext(ApplicationContext): def run(self): check = self.checkFiles() if not check: return self.initVar() self.database = Database(deff=self.aapm_db, ctdi=self.ctdi_db, ssde=self.ssde_db, patient=self.patients_database(), windowing=self.windowing_db) self.phantom_model = QSqlTableModel(db=self.database.ssde_db) self.phantom_model.setTable("Phantom") self.phantom_model.select() self.windowing_model = QSqlTableModel(db=self.database.windowing_db) self.windowing_model.setTable("Parameter") self.windowing_model.setEditStrategy(QSqlTableModel.OnManualSubmit) self.windowing_model.select() self.app_data = AppData() self.axes = plt.Axes(lock_aspect=True) self.phantom = HEAD self.phantom_name = "HEAD" self.records_count = get_records_num(self.patients_database(), 'PATIENTS') self.main_window.show() return self.app.exec_() def initVar(self): self.dicoms = [] self.images = [] self.img_dims = (0,0) self.recons_dim = 0 self.current_img = 0 self.total_img = 0 self.isImage = False def get_current_img(self): return get_hu_img(self.dicoms[self.current_img-1]) def get_img_from_ds(self, ds): return get_hu_img(ds) def checkFiles(self): if not os.path.isfile(self.config_file()): configs = { 'patients_db': self.default_patients_database, } try: cfg_dir = self.app_data_dir() if not os.path.exists(cfg_dir): os.makedirs(cfg_dir, exist_ok=True) with open(self.config_file(), 'w') as f: json.dump(configs, f, sort_keys=True, indent=4) except: self.ioError() return False if not os.path.isfile(self.default_patients_database): if self.patients_database() == self.default_patients_database: db_dir = os.path.join(self.app_data_dir(), 'Database') if not os.path.exists(db_dir): os.makedirs(db_dir, exist_ok=True) try: create_patients_table(self.default_patients_database) except: self.ioError() return False if not os.path.isfile(self.patients_database()): QMessageBox.warning(None, "Database Error", "Database file is corrupt or missing.\nAn empty database will be created.") try: create_patients_table(self.patients_database()) except: self.ioError() return False return True def ioError(self): QMessageBox.critical(None, "I/O Error", "Failed to write config or database file.\nTry running as administrator.") @cached_property def main_window(self): return MainWindow(self) @cached_property def open_icon(self): return QIcon(self.get_resource("assets/icons/open.png")) @cached_property def save_icon(self): return QIcon(self.get_resource("assets/icons/save.png")) @cached_property def launch_icon(self): return QIcon(self.get_resource("assets/icons/launch.png")) @cached_property def setting_icon(self): return QIcon(self.get_resource("assets/icons/setting.png")) @cached_property def next_icon(self): return QIcon(self.get_resource("assets/icons/navigate_next.png")) @cached_property def prev_icon(self): return QIcon(self.get_resource("assets/icons/navigate_before.png")) @cached_property def export_icon(self): return QIcon(self.get_resource("assets/icons/export.png")) @cached_property def tree_icon(self): return QIcon(self.get_resource("assets/icons/tree.png")) @cached_property def folder_icon(self): return QIcon(self.get_resource("assets/icons/open_folder.png")) @cached_property def close_img_icon(self): return QIcon(self.get_resource("assets/icons/close_image.png")) @cached_property def sample_icon(self): return QIcon(self.get_resource("assets/icons/snippet.png")) @cached_property def help_icon(self): return QIcon(self.get_resource("assets/icons/help.png")) # @cached_property def help_file(self, lang='id'): return self.get_resource(f"assets/files/user_guide_{lang}.pdf") @cached_property def sample_dir(self): return self.get_resource("assets/dicom_sample") @cached_property def aapm_db(self): return self.get_resource("assets/db/aapm.db") @cached_property def ssde_db(self): return self.get_resource("assets/db/ssde.db") @cached_property def ctdi_db(self): return self.get_resource("assets/db/ctdi.db") @cached_property def windowing_db(self): return self.get_resource("assets/db/windowing.db") @cached_property def default_patients_database(self): return os.path.join(self.app_data_dir(), 'Database', 'patient_data.db') @cached_property def hk_data(self): return self.get_resource("assets/db/DataHdanK.wt") @cached_property def app_logo(self): return qimage2ndarray.imread(self.get_resource("assets/img/logo.png")) def config_file(self): return os.path.join(self.app_data_dir(), 'config.json') def app_data_dir(self): return os.path.join(os.path.expanduser('~'), 'Documents', 'IndoseCT') def patients_database(self): with open(self.config_file(), 'r') as f: js = json.load(f) path = js['patients_db'] return path
class EspePecheElec_dialog(QDialog, Ui_espePecheElecForm): '''Gére le fonctionnement interne du Dialog "Export pêche électrique" après son ouverture via le menu''' def __init__(self, iface): ''' Constructeur. :param iface: Une instance d'interface qui sera passée à cette classe qui fournit le crochet par lequel vous pouvez manipuler l'application QGIS au moment de l'exécution. :type iface: QgsInterface ''' QDialog.__init__(self) self.iface = iface self.setupUi(self) # Méthodes communes self.gc = Gedopi_common(self) # Variables de connexion à la base de données self.db = None self.dbType = "" self.dbSchema = "" self.btnAnnuler.clicked.connect(self.onReject) self.btnEnregistrer.clicked.connect(self.enregistrer) # Initialisation du formulaire if self.verifiePresenceCouche(): self.setupModel() else: self.iface.messageBar().pushMessage( "Erreur : ", u"La couche des opérations de pêches électriques n'est pas chargée ...", level=QgsMessageBar.CRITICAL, duration=5) self.btnEnregistrer.setEnabled(False) self.cmbEspece.setEnabled(False) def verifiePresenceCouche(self): ''' Vérifie la présence de différentes couches et renvoi dans __init__, True ou False, active le setupModel si return True, affiche un message si return False ''' self.layer = None self.layer = self.gc.getLayerFromLegendByTableProps( 'ope_peche_elec', 'opep_geom', '') if self.layer: return True else: return False def setupModel(self): ''' Initialise le formulaire en le connectant à la base de données et en attribuant aux différents champs leurs tables ou colonnes PostgreSQL ''' self.infoMessage = u"Gedopi - Pêche électrique" if not self.db: connectionParams = self.gc.getConnectionParameterFromDbLayer( self.layer) if (connectionParams['dbType'] == u'postgres' or connectionParams['dbType'] == u'postgis'): self.dbType = "postgres" self.db = QSqlDatabase.addDatabase("QPSQL", 'db1') self.db.setDatabaseName(connectionParams['dbname']) self.db.setUserName(connectionParams['user']) self.db.setPassword(connectionParams['password']) self.db.setHostName(connectionParams['host']) self.dbSchema = connectionParams['schema'] self.host = connectionParams['host'] self.user = connectionParams['user'] self.password = connectionParams['password'] self.dbname = connectionParams['dbname'] if (not self.db.open()): QMessageBox.critical( self, "Erreur", u"Impossible de se connecter à la base de données ...", QMessageBox.Ok) QApplication.restoreOverrideCursor() return # Remplissage de la liste déroulante des espèces self.model = QSqlTableModel(self, self.db) wrelation = "espece" if self.dbType == "postgres": wrelation = self.dbSchema + "." + wrelation self.model.setTable(wrelation) self.model.setSort(1, Qt.AscendingOrder) if (not self.model.select()): QMessageBox.critical( self, u"Remplissage du modèle", u"Erreur au modèle Espèce dans le Ope_peche_ajout_dialog.__init__() : \n" + self.model.lastError().text(), QMessageBox.Ok) self.cmbEspece.setModel(self.model) self.cmbEspece.setModelColumn(1) def enregistrer(self): requete = "" savefile = "" self.cheminExport = "" # Récupération de l'ID et du sigle de l'espèce en cours dans la combobox wrecord = self.cmbEspece.model().record(self.cmbEspece.currentIndex()) wespeceId = wrecord.value(0) wespeceSigle = wrecord.value(1) # Écriture de la requête SQL en fonction de l'espèce choisi dans la liste déroulante requete = ( "SELECT DISTINCT operation.ope_code AS CODE, " + "station.sta_xl93_aval AS X, " + "station.sta_yl93_aval AS Y, " + "cours_eau.ceau_nom AS RIVIERE, " + "(masse_eau.meau_code || ' ; '::text) || masse_eau.meau_nom AS MASSEEAU, " + "contexte_pdpg.pdpg_nom AS PDPG, " + "ope_peche_elec.opep_date AS DATE, " + "motif_peche.mope_motif AS MOTIF, " + "condition_peche.cope_condition AS CONDITION, " + "ope_peche_elec.opep_nbre_anode AS NANODE, " + "ope_peche_elec.opep_longueur_prospec AS LONGUEUR, " + "ope_peche_elec.opep_profondeur_moy AS PROFONDEUR, " + "ope_peche_elec.opep_largeur_moy AS LARGEUR, " + "ope_peche_elec.opep_surf_peche AS SURFACE, " + "ope_peche_elec.opep_pente AS PENTE, " + "ope_peche_elec.opep_ntt_reel AS NTTREEL, " + "ope_peche_elec.opep_ntt AS NTT, " + "(ope_peche_elec.ipro_valeur || ' ; '::text) || ipr.ipr_correspondance AS IPR, " + "string_agg(espece.esp_sigle, ' ; '::text) AS ESPECE, " + "f_poisson_params.espe_densite AS VALDEN_" + wespeceSigle + ", " + "f_poisson_params.clde_val_correspond AS CLADEN_" + wespeceSigle + ", " + "f_poisson_params.espe_biomasse AS VALBIO_" + wespeceSigle + ", " + "f_poisson_params.clbi_val_correspond CLABIO_" + wespeceSigle + ", " + "ope_peche_elec.opep_geom " + "FROM data.masse_eau, " + "data.cours_eau, " + "data.station, " + "data.contexte_pdpg, " + "data.operation, " + "data.ope_peche_elec " + "JOIN data.motif_peche ON motif_peche.mope_id = ope_peche_elec.opep_mope_id " + "JOIN data.condition_peche ON condition_peche.cope_id = ope_peche_elec.opep_cope_id " + "JOIN data.ipr ON ipr.ipr_id = ope_peche_elec.opep_ipr_id " + "JOIN data.espece_peche ON espece_peche.espe_opep_id = ope_peche_elec.opep_id " + "JOIN data.espece ON espece_peche.espe_esp_id = espece.esp_id " + "FULL JOIN data.f_poisson_params(" + str(wespeceId) + ") f_poisson_params(ope_code, espe_biomasse, clbi_val_correspond, espe_densite, clde_val_correspond) ON f_poisson_params.ope_code = ope_peche_elec.opep_ope_code " + "WHERE station.sta_meau_code = masse_eau.meau_code AND " + "station.sta_ceau_id = cours_eau.ceau_id AND " + "station.sta_pdpg_id = contexte_pdpg.pdpg_id AND " + "operation.ope_sta_id = station.sta_id AND " + "operation.ope_code = ope_peche_elec.opep_ope_code " + "GROUP BY operation.ope_code, station.sta_xl93_aval, station.sta_yl93_aval, cours_eau.ceau_nom, ((masse_eau.meau_code || ' ; '::text) || masse_eau.meau_nom), contexte_pdpg.pdpg_nom, ope_peche_elec.opep_date, motif_peche.mope_motif, condition_peche.cope_condition, ope_peche_elec.opep_nbre_anode, ope_peche_elec.opep_longueur_prospec, ope_peche_elec.opep_profondeur_moy, ope_peche_elec.opep_largeur_moy, ope_peche_elec.opep_surf_peche, ope_peche_elec.opep_pente, ope_peche_elec.opep_ntt_reel, ope_peche_elec.opep_ntt, ((ope_peche_elec.ipro_valeur || ' ; '::text) || ipr.ipr_correspondance), f_poisson_params.espe_densite, f_poisson_params.clde_val_correspond, f_poisson_params.espe_biomasse, f_poisson_params.clbi_val_correspond, ope_peche_elec.opep_geom " + "ORDER BY cours_eau.ceau_nom ") # Récupération du chemin où enregistrer l'export savefile = QFileDialog.getSaveFileName(self, "Save File", "", u"ESRI Shapefile (*.shp)") if savefile != "": cheminExport = unicode(savefile) # Récupération du nom du fichier path = QFileInfo(cheminExport) filename = path.completeBaseName() if cheminExport != "": query = QSqlQuery(self.db) query.prepare(requete) # Exécution de la requête afin de vérifier sa validité if query.exec_(): # Création d'une ligne de commande DOS qui utilisera pgsql2shp pour créer un shapefile en fonction de la requête cmd = "cd C:\\Program Files\\PostgreSQL\\9.5\\bin & pgsql2shp.exe -f " + str( cheminExport ) + " -h " + self.host + " -u " + self.user + " -P " + self.password + " " + self.dbname + " \"" + requete + "\"" # Exécution de la ligne de commande (une fenêtre DOS s'ouvre le temps de l'exécution os.system(cmd) self.onReject() # Ajout du shape créé au caneva layer = self.iface.addVectorLayer(cheminExport, filename, "ogr") else: QMessageBox.critical(self, u"Erreur SQL", query.lastError().text(), QMessageBox.Ok) def onReject(self): '''Ferme la fenêtre si clic sur le bouton annuler''' QDialog.reject(self)
# QMessageBox.about(dlg,"错误","数据超出范围") def findrow(i): delrow = i.row() print('del row ={}'.format(str(delrow))) app = QApplication(sys.argv) #创建app对象**************************** db = QSqlDatabase.addDatabase("QSQLITE") db.setDatabaseName('num_sql.db') #创建并打开一个到sqlite3的连接>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> model = QSqlTableModel() delrow = -1 initializeModel(model) view1 = createView("Table Model (View 1)", model) view1.clicked.connect(findrow) dlg = QDialog() layout = QVBoxLayout() layout.addWidget(view1) addBtn = QPushButton("zen") addBtn.clicked.connect(addrow) layout.addWidget(addBtn) delBtn = QPushButton("del") #这个删除有问题
def _init_model(self): self.model = QSqlTableModel(db=self.db) self.model.setTable(self.TABLE) self.model.setEditStrategy(QSqlTableModel.OnManualSubmit) self.setModel(self.model) self.model.select()
class WarehouseController(QObject): def __init__(self, list, table, addButton, editButton, deleteButton, dbase): super().__init__() self.list = list self.table = table self.addButton = addButton self.editButton = editButton self.deleteButton = deleteButton self.dbase = dbase self.shopModel = QSqlTableModel(db = dbase) self.shopModel.setTable("shop") self.shopModel.select() self.list.setModel(ComplexListModel(self.shopModel, "{name}")) self.list.selectionModel().currentChanged.connect(self.listSelectionChanged) self._checkPrivileges() if self.only_select: self.addButton.setEnabled(False) self.deleteButton.setEnabled(False) self.addButton.clicked.connect(self.addButtonClicked) self.editButton.clicked.connect(self.editButtonClicked) self.deleteButton.clicked.connect(self.deleteButtonClicked) def _checkPrivileges(self): query = QSqlQuery("SHOW GRANTS") only_select = None table_pattern = "`{}`".format("shop_detail").lower() while query.next(): s = query.value(0).lower() if table_pattern in s: if "select" in s and only_select is None: only_select = True else: only_select = False self.only_select = bool(only_select) def listSelectionChanged(self, cur, prev): if not cur.isValid(): return self.table.setModel(None) else: self.setShopIndex(cur.row()) def setShopIndex(self, row): record = self.shopModel.record(row) self.detailModel = QSqlQueryModel() query = "SELECT detail.id as id, CONCAT(detail.article, \": \", detail.name) as dtl, shop_detail.quantity as qnt \ FROM shop_detail INNER JOIN detail \ ON shop_detail.detail_id = detail.id \ WHERE shop_detail.shop_id={} ORDER BY dtl".format(record.value("id")) self.detailModel.setQuery(query) self.detailModel.setHeaderData(1, Qt.Horizontal, "Наименование") self.detailModel.setHeaderData(2, Qt.Horizontal, "Количество") self.table.setModel(self.detailModel) self.table.hideColumn(0) self.table.resizeColumnsToContents() self.table.selectionModel().currentChanged.connect(self.tableSelectionChanged) if not self.detailModel.query().isActive(): print(self.detailModel.lastError().text()) self.deleteButton.setEnabled(False) self.editButton.setEnabled(False) def tableSelectionChanged(self, cur, prev): if self.only_select: return if cur.isValid(): self.deleteButton.setEnabled(True) self.editButton.setEnabled(True) else: self.deleteButton.setEnabled(False) self.editButton.setEnabled(False) self.addButton.setEnabled(True) def addButtonClicked(self): shop = self.shopModel.record(self.list.currentIndex().row()) query = QSqlQuery("SELECT detail.id as id, CONCAT(detail.article, \": \", detail.name) as name \ FROM detail WHERE NOT(detail.id IN (SELECT detail_id FROM shop_detail \ WHERE shop_id={}))".format(shop.value("id"))) details = {} while query.next(): details[query.value("name")] = query.value("id") if not details: return QMessageBox.warning(None, "Ошибка добавления", "Не удалось добавить новый товар на склад: все возможные товары уже добавлены.") choice, ok = QInputDialog.getItem(None, "Товар", "Укажите товар:", list(details.keys()), 0, False) if not ok: return qnt, ok = QInputDialog.getInt(None, "Количество", "Укажите количество товара:", 1, 1) if not ok: return detail_id = details[choice] shop_id = shop.value("id") query = QSqlQuery("INSERT INTO shop_detail (shop_id, detail_id, quantity) \ VALUES ({}, {}, {})".format(shop_id, detail_id, qnt)) if not query.isActive(): print(query.lastError().text()) self.setShopIndex(self.list.currentIndex().row()) self.table.selectionModel().clearSelection() def editButtonClicked(self): detail = self.detailModel.record(self.table.currentIndex().row()) qnt, ok = QInputDialog.getInt(None, "Количество", "Укажите количество товара:", detail.value("qnt"), 0) if not ok: return shop = self.shopModel.record(self.list.currentIndex().row()) if qnt > 0: query = QSqlQuery("UPDATE shop_detail SET quantity={} \ WHERE shop_id={} AND detail_id={}".format(qnt, shop.value("id"), detail.value("id"))) else: query = QSqlQuery("DELETE FROM shop_detail WHERE \ shop_id={} AND detail_id={} LIMIT 1".format( shop.value("id"), detail.value("id"))) if not query.isActive(): print(query.lastError().text()) self.setShopIndex(self.list.currentIndex().row()) def deleteButtonClicked(self): if not self.table.currentIndex().isValid(): return detail = self.detailModel.record(self.table.currentIndex().row()) shop = self.shopModel.record(self.list.currentIndex().row()) query = QSqlQuery("DELETE FROM shop_detail WHERE \ shop_id={} AND detail_id={} LIMIT 1".format( shop.value("id"), detail.value("id"))) if not query.isActive(): print(query.lastError().text()) self.setShopIndex(self.list.currentIndex().row()) def update(self): cur = self.list.currentIndex() if cur.isValid(): row = cur.row() else: row = 0 self.shopModel.select() self.list.reset() self.selectRow(row) def selectRow(self, row): self.list.selectionModel().clearSelection() self.list.selectionModel().setCurrentIndex( self.shopModel.index(row, 0), QItemSelectionModel.Select)
class AdminWindow(QMainWindow, Ui_MainWindow): """ Ui_MainWindow: Class containing widgets and their respective settings context: This is the overall application context, containing resources used through out the app. Seriously aren't the variable names and function names intuitive enough? """ def __init__(self, context, *args, **kwargs): super(AdminWindow, self).__init__(*args, **kwargs) self.context = context self.setupUi(self) # create widgets from Ui_MainWindow self.setWindowIcon(self.context.window_icon) self.load_tables() # create tables from database self.actionAbout.setIcon(self.context.about_icon) self.actionAbout.triggered.connect(self.show_about) self.actionLog_Out.setIcon(self.context.logout_icon) self.actionLog_Out.triggered.connect(self.logout) self.add_product_button.clicked.connect(self.add_product) self.delete_product_button.clicked.connect(lambda: self.product_model.removeRow( self.product_table_view.currentIndex().row())) self.add_user_button.clicked.connect(self.add_user) self.delete_user_button.clicked.connect( lambda: self.users_model.removeRow( self.user_table_view.currentIndex().row() )) def show_about(self): dlg = AboutDialog(self.context, self) dlg.exec_() def load_tables(self): self.connect_database() self.load_products_table() self.load_users_table() self.load_orders_table() def connect_database(self): # connection to database and open connection db = QSqlDatabase.addDatabase('QSQLITE') db.setDatabaseName(self.context.get_database) db.open() def load_products_table(self): # The model used by the view self.product_model = QSqlTableModel() self.product_model.setTable('products') self.product_model.setEditStrategy(QSqlTableModel.OnFieldChange) self.product_model.select() # Use the product model as the model. MV programming self.product_table_view.setModel(self.product_model) def load_users_table(self): self.users_model = QSqlTableModel() self.users_model.setTable('users') self.users_model.setEditStrategy(QSqlTableModel.OnFieldChange) self.users_model.select() self.user_table_view.setModel(self.users_model) def load_orders_table(self): self.orders_model = QSqlTableModel() self.orders_model.setTable('orders') self.orders_model.select() self.orders_table_view.setModel(self.orders_model) def logout(self): # Go to login window self.loginwindow = LoginWindow(context=self.context) self.loginwindow.show() self.hide() def add_product(self): self.product_model.insertRows(self.product_model.rowCount(), 1) def add_user(self): self.users_model.insertRows(self.users_model.rowCount(), 1)
class WinsWidget(QWidget): """主窗口。""" def __init__(self, parent=None): logger.debug("_init__:begin") super(WinsWidget, self).__init__(parent) self.setObjectName('winsWidget') self.setWindowFlags(Qt.FramelessWindowHint) self.setWindowTitle('wins的小工具') self.setWindowIcon(QIcon('icons/titleIcon.png')) self.resize(1000, 650) # 按钮start. self.btn_exit = QPushButton(self) self.btn_min = QPushButton(self) self.btn_max = QPushButton(self) self.btn_login = QPushButton("Unlogin", self) self.btn_search = QPushButton(self) self.btn_qry_stock = QPushButton(self) self.btn_add_stock = QPushButton(self) self.btn_del_stock = QPushButton(self) # 按钮end. # 标签start. self.lbe_pic = QLabel(self) self.header_hr = QLabel(self) self.header_icon = QLabel(self) self.header_text = QLabel(self) self.spacing = QLabel(self) self.spacing2 = QLabel(self) self.spacing3 = QFrame() self.spacing4 = QFrame() # ------- # 输入框start. self.search_line = QLineEdit(self) # 输入框end. # ------- # 列表框start. self.stockTableView = QtWidgets.QTableView(self) self.stockTableModel=QSqlTableModel(self) # ------- # 布局与属性设置。 self.mainLayout = QGridLayout() self.topLayout = QHBoxLayout() self.leftLayout = QVBoxLayout() self.centerLayout = QHBoxLayout() self.rightLayout = QVBoxLayout() self.rightLayout1 = QHBoxLayout() self.rightLayout2 = QVBoxLayout() self.rightLayout21 = QHBoxLayout() self.bottomLayout = QHBoxLayout() self.bottomLayout1 = QVBoxLayout() self.playLayout = QHBoxLayout() self.set_buttons() self.set_labels() self.set_lines() self.load_stock_tableview() # ------- # 其他功能。 self.load_login() self.setLayout(self.set_layouts()) logger.debug("_init__:end") # 设置布局。 def set_layouts(self): """ 布局。 """ # 头布局start. logger.debug("set_layouts:begin") self.topLayout.setObjectName('Headerhbox') self.topLayout.addWidget(self.header_icon) self.topLayout.addWidget(self.header_text) self.topLayout.addWidget(self.spacing2) self.topLayout.addWidget(self.search_line) self.topLayout.addWidget(self.btn_search) self.topLayout.addStretch(1) self.topLayout.addWidget(self.lbe_pic) self.topLayout.addWidget(self.btn_login) self.topLayout.addWidget(self.spacing) self.topLayout.addWidget(self.btn_min) self.topLayout.addWidget(self.btn_max) self.topLayout.addWidget(self.btn_exit) self.topLayout.setSpacing(7) # ------- self.mainLayout.addLayout(self.topLayout, 0, 0, Qt.AlignTop) self.mainLayout.addWidget(self.header_hr, 1, 0, Qt.AlignTop) # 头布局end. # -------- # 中心布局start. # 左部分start. self.leftLayout.addWidget(self.btn_qry_stock) self.leftLayout.addWidget(self.btn_add_stock) self.leftLayout.addWidget(self.btn_del_stock) self.leftLayout.setSpacing(10) # 左部分end。 # ------- # 右部分end. # ------- self.centerLayout.addLayout(self.leftLayout) self.centerLayout.addWidget(self.spacing3) self.centerLayout.addWidget(self.stockTableView) self.centerLayout.addLayout(self.rightLayout) self.centerLayout.setStretch(0, 180) self.centerLayout.setStretch(1, 1) self.centerLayout.setStretch(2, 0) self.centerLayout.setStretch(3, 830) self.centerLayout.setStretch(4, 0) self.mainLayout.addLayout(self.centerLayout, 2, 0, Qt.AlignTop | Qt.AlignLeft) # 中心布局end. # ------- # 下部分start. self.mainLayout.addWidget(self.spacing4, 3, 0, Qt.AlignTop) self.mainLayout.addLayout(self.bottomLayout, 3, 0, Qt.AlignBottom) # self.mainLayout.addWidget(self.current_list, 2, 0, Qt.AlignBottom | Qt.AlignRight) # 下部分end. self.mainLayout.setRowStretch(1, 1) self.mainLayout.setRowStretch(2, 20) self.mainLayout.setRowStretch(3, 3) logger.debug("set_layouts:end") return self.mainLayout def set_labels(self): """ 全部的标签组件。 """ p = QPixmap() p.load('icons/unlogin.png') p2 = QPixmap() p2.load('icons/titleIcon.png') # 头部装饰start。 self.lbe_pic.setObjectName("headpic") self.lbe_pic.setPixmap(p.scaled(40, 40)) self.header_hr.setObjectName('Headerhr') self.header_hr.setText("推荐") self.header_icon.setObjectName('HIcon') self.header_icon.setPixmap(p2.scaled(50, 50)) self.header_text.setObjectName('HText') self.header_text.setText(" Music") def load_login(self): """ 登录 """ logger.debug("load_login:"******""" 退出 """ logger.debug("quit_login:"******""" 加载表格 """ logger.debug("load_stock_tableview:begin") self.stockTableModel.setTable("t1") self.stockTableModel.select() self.stockTableModel.setEditStrategy(QSqlTableModel.OnManualSubmit) # 数据更新的策略,详细可以查看Qt文档 self.stockTableView.setModel(self.stockTableModel) self.stockTableView.setSelectionBehavior(QAbstractItemView.SelectRows) self.stockTableView.setSelectionMode(QAbstractItemView.ExtendedSelection) #self.stockTableView.setGeometry(QtCore.QRect(290, 110, 471, 221)) self.stockTableView.setObjectName("stockTableView") logger.debug("load_stock_tableview:end") def set_buttons(self): """ 全部的按钮组件。 """ # 退出。 logger.debug("set_buttons:begin") self.btn_exit.setObjectName('exit') self.btn_exit.setText('×') self.btn_exit.clicked.connect(self.close) self.btn_exit.setToolTip('退出') # 最小化。 self.btn_min.setObjectName('mini') self.btn_min.setText('-') self.btn_min.clicked.connect(self.showMinimized) self.btn_min.setToolTip('最小化') # 最大化。 self.btn_max.setObjectName('maxi') self.btn_max.setText('□') self.btn_max.setToolTip('^_^此功能已上火星') # 登陆。 self.btn_login.setObjectName('login') self.btn_login.setToolTip('登陆') # 搜索。 self.btn_search.setObjectName('searchBtn') self.btn_search.resize(48, 48) # 查询。 self.btn_qry_stock.setObjectName('btnQryStock') self.btn_qry_stock.setIcon(QIcon('icons/qryBtn.png')) self.btn_qry_stock.setText("查询") self.btn_qry_stock.clicked.connect(self.qryStockFunc) # 增加。 self.btn_add_stock.setObjectName('btnAddStock') self.btn_add_stock.setIcon(QIcon('icons/addBtn.png')) self.btn_add_stock.setText("增加") self.btn_add_stock.clicked.connect(self.addStockFunc) # 删除。 self.btn_del_stock.setObjectName('btnDelStock') self.btn_del_stock.setIcon(QIcon('icons/delBtn.png')) self.btn_del_stock.setText("删除") self.btn_del_stock.clicked.connect(self.delStockFunc) logger.debug("set_buttons:end") def set_lines(self): """ 输入框。 """ logger.debug("set_lines:begin") self.search_line.setObjectName('SearchLine') self.search_line.setPlaceholderText('搜索') logger.debug("set_lines:end") def set_sliders(self): """ 滚动组件。 """ logger.debug("set_sliders:begin") self.slider.setObjectName("slider") self.slider.setOrientation(Qt.Horizontal) logger.debug("set_sliders:end") def hide_index(self): """ 隐藏主页, 显示歌单详细信息。 """ logger.debug("hide_index") def show_index(self): """ 显示主页。 """ logger.debug("show_index") # 切换页面end. """重写鼠标事件,实现窗口拖动。""" def mousePressEvent(self, event): logger.debug("mousePressEvent:") if event.buttons() == Qt.LeftButton: self.m_drag = True self.m_DragPosition = event.globalPos()-self.pos() event.accept() def mouseMoveEvent(self, event): logger.debug("mouseMoveEvent:") try: if event.buttons() and Qt.LeftButton: self.move(event.globalPos()-self.m_DragPosition) event.accept() except AttributeError: pass def mouseReleaseEvent(self, event): logger.debug("mouseReleaseEvent:") self.m_drag = False """按键绑定。。""" def keyPressEvent(self, event): logger.debug("keyPressEvent:") if event.key() == Qt.Key_Enter or event.key() == Qt.Key_Enter-1: self.song_search() """退出窗口时做的一些事。""" def closeEvent(self, event): # 退出时保存歌曲列表缓存。 logger.debug("showEvent:") """界面开始前的一些事。""" def showEvent(self, event): logger.debug("showEvent:") #查询按钮关联的槽函数 def qryStockFunc(self): #self.db.execSQL("select * from t1") logger.debug("qryStockFunc:") #插入按钮关联的槽函数 def addStockFunc(self): logger.debug("addStockFunc:begin") f1=random.randint(1, 99) self.myTableModel.insertRows(0, 1) self.myTableModel.setData(self.myTableModel.index(0, 0), f1) self.myTableModel.setData(self.myTableModel.index(0, 1), "test") self.myTableModel.submitAll() logger.debug("addStockFunc:end") def delStockFunc(self): logger.debug("delStockFunc:begin") rs=list(map(lambda x:x.row(),self.myTableView.selectedIndexes())) if len(rs)==0: QMessageBox.information(self,'提醒','请先选中至少一行,再点击此按钮!') return for i in reversed(rs): self.myTableModel.removeRows(i,1) self.myTableModel.submitAll() logger.debug("delStockFunc:end")
def __init__(self, parent=None): logger.debug("_init__:begin") super(WinsWidget, self).__init__(parent) self.setObjectName('winsWidget') self.setWindowFlags(Qt.FramelessWindowHint) self.setWindowTitle('wins的小工具') self.setWindowIcon(QIcon('icons/titleIcon.png')) self.resize(1000, 650) # 按钮start. self.btn_exit = QPushButton(self) self.btn_min = QPushButton(self) self.btn_max = QPushButton(self) self.btn_login = QPushButton("Unlogin", self) self.btn_search = QPushButton(self) self.btn_qry_stock = QPushButton(self) self.btn_add_stock = QPushButton(self) self.btn_del_stock = QPushButton(self) # 按钮end. # 标签start. self.lbe_pic = QLabel(self) self.header_hr = QLabel(self) self.header_icon = QLabel(self) self.header_text = QLabel(self) self.spacing = QLabel(self) self.spacing2 = QLabel(self) self.spacing3 = QFrame() self.spacing4 = QFrame() # ------- # 输入框start. self.search_line = QLineEdit(self) # 输入框end. # ------- # 列表框start. self.stockTableView = QtWidgets.QTableView(self) self.stockTableModel=QSqlTableModel(self) # ------- # 布局与属性设置。 self.mainLayout = QGridLayout() self.topLayout = QHBoxLayout() self.leftLayout = QVBoxLayout() self.centerLayout = QHBoxLayout() self.rightLayout = QVBoxLayout() self.rightLayout1 = QHBoxLayout() self.rightLayout2 = QVBoxLayout() self.rightLayout21 = QHBoxLayout() self.bottomLayout = QHBoxLayout() self.bottomLayout1 = QVBoxLayout() self.playLayout = QHBoxLayout() self.set_buttons() self.set_labels() self.set_lines() self.load_stock_tableview() # ------- # 其他功能。 self.load_login() self.setLayout(self.set_layouts()) logger.debug("_init__:end")
def merge(self, fileName): db = QSqlDatabase.addDatabase('QSQLITE', 'merge') db.setDatabaseName(fileName) if not db.open(): print(db.lastError().text()) QMessageBox.critical(self.parent(), self.tr("Merge collections"), self.tr("Can't open collection")) return settings = CollectionSettings(db) if self.settings['Type'] != version.AppName: QMessageBox.critical(self.parent(), self.tr("Merge collections"), self.tr("Collection %s in wrong format %s") % (fileName, version.AppName)) if int(settings['Version']) != CollectionSettings.Default['Version']: QMessageBox.critical(self.parent(), self.tr("Merge collections"), self.tr("Source collection %s in old format %d.\n(Try to open it before merging.)") % (fileName, int(settings['Version']))) return if settings['Password'] != cryptPassword(): dialog = PasswordDialog(settings, self.parent()) result = dialog.exec_() if result == QDialog.Rejected: return False query = QSqlQuery("SELECT COUNT(id) FROM coins", db) query.first() count = query.record().value(0) progressDlg = Gui.ProgressDialog(self.tr("Inserting records"), self.tr("Cancel"), count, self.parent()) big_query = QSqlQuery("""SELECT coins.title AS title, "value", "unit", "country", "year", "period", "mint", "mintmark", "issuedate", "type", "series", "subjectshort", "status", "material", "fineness", "shape", "diameter", "thickness", "weight", "grade", "edge", "edgelabel", "obvrev", "quality", "mintage", "dateemis", "catalognum1", "catalognum2", "catalognum3", "catalognum4", "rarity", "price1", "price2", "price3", "price4", "variety", "obversevar", "reversevar", "edgevar", "paydate", "payprice", "totalpayprice", "saller", "payplace", "payinfo", "saledate", "saleprice", "totalsaleprice", "buyer", "saleplace", "saleinfo", "note", "obversedesign", "obversedesigner", "reversedesign", "reversedesigner", "subject", "defect", "storage", "features", "createdat", "updatedat", "quantity", "url", "barcode", coins.image AS image, images.image AS images_image, obverseimg, obverseimg.image AS obverseimg_image, obverseimg.title AS obverseimg_title, reverseimg, reverseimg.image AS reverseimg_image, reverseimg.title AS reverseimg_title, edgeimg, edgeimg.image AS edgeimg_image, edgeimg.title AS edgeimg_title, photo1, photo1.image AS photo1_image, photo1.title AS photo1_title, photo2, photo2.image AS photo2_image, photo2.title AS photo2_title, photo3, photo3.image AS photo3_image, photo3.title AS photo3_title, photo4, photo4.image AS photo4_image, photo4.title AS photo4_title FROM coins LEFT OUTER JOIN images ON coins.image=images.id LEFT OUTER JOIN photos AS obverseimg ON coins.obverseimg=obverseimg.id LEFT OUTER JOIN photos AS reverseimg ON coins.reverseimg=reverseimg.id LEFT OUTER JOIN photos AS edgeimg ON coins.edgeimg=edgeimg.id LEFT OUTER JOIN photos AS photo1 ON coins.photo1=photo1.id LEFT OUTER JOIN photos AS photo2 ON coins.photo2=photo2.id LEFT OUTER JOIN photos AS photo3 ON coins.photo3=photo3.id LEFT OUTER JOIN photos AS photo4 ON coins.photo4=photo4.id""", db) _model = QSqlTableModel(db=self.db) _model.setTable('coins') _model.select() while big_query.next(): progressDlg.step() if progressDlg.wasCanceled(): break record = big_query.record() record.setNull('id') # remove ID value from record for field in ['obverseimg', 'reverseimg', 'edgeimg', 'photo1', 'photo2', 'photo3', 'photo4']: value = record.value(field + '_image') if value: query = QSqlQuery(self.db) query.prepare("INSERT INTO photos (title, image) VALUES (?, ?)") query.addBindValue(record.value(field + '_title')) query.addBindValue(value) query.exec_() img_id = query.lastInsertId() else: img_id = None record.setValue(field, img_id) record.remove(record.indexOf(field + '_image')) record.remove(record.indexOf(field + '_title')) value = record.value('images_image') if value: query = QSqlQuery(self.db) query.prepare("INSERT INTO images (image) VALUES (?)") query.addBindValue(value) query.exec_() img_id = query.lastInsertId() else: img_id = None record.setValue('image', img_id) record.remove(record.indexOf('images_image')) _model.insertRecord(-1, record) _model.submitAll() progressDlg.reset() db.close() QMessageBox.warning(self.parent(), self.tr("Merge collections"), self.tr("The application will need to restart now")) self.parent().restart()
class WinsWidgetView(QWidget, Ui_Wins_Widget): def __init__(self,parent=None): logger.debug("_init__:begin") super(WinsWidgetView, self).__init__(parent) self.setupUi(self) self.dbPath="test.db" self.curTable="test2" self.setObjectName('winsWidget') self.setWindowFlags(Qt.FramelessWindowHint) self.setWindowTitle('wins的小工具') self.setWindowIcon(QIcon('icons/titleIcon.png')) self.tableModel=QSqlTableModel(self,QSqlDatabase.addDatabase('QSQLITE')) self.initThread() self.set_buttons() self.set_labels() self.set_lines() self.load_tableview() self.init_bottom() logger.debug("_init__:end") def init_bottom(self): self.progressBar.hide() self.progresslable.hide() self.statusBar= QStatusBar(self); self.rightBottom.addWidget(self.statusBar) #self.statusBar.setGeometry(30,40,200,25); def initThread(self): logger.debug("_init__:thread") self.thread=QThread() self.tsWork=TushareWorkObject() self.tsWork.moveToThread(self.thread) ##另起子线程,防止ui主线程卡死 self.thread.start() #槽函数不要加(),否则会报参数异常 self.tsWork.procegressBarSignal.connect(self.setProcegressBar) logger.debug("_init end__:thread") def setProcegressBar(self,i): print("setProcegressBar:") print(i) self.progressBar.show() self.progressBar.setRange(0, i) pass """重写鼠标事件,实现窗口拖动。""" def mousePressEvent(self, event): #logger.debug("mousePressEvent:") if event.buttons() == Qt.LeftButton: self.m_drag = True self.m_DragPosition = event.globalPos()-self.pos() event.accept() def mouseMoveEvent(self, event): #logger.debug("mouseMoveEvent:") try: if event.buttons() and Qt.LeftButton: self.move(event.globalPos()-self.m_DragPosition) event.accept() except AttributeError: pass def mouseReleaseEvent(self, event): #logger.debug("mouseReleaseEvent:") self.m_drag = False # 设置布局。 def set_layouts(self): logger.debug("set_layouts:begin") self.page1group.setAlignment(Qt.AlignCenter) self.page1layout.setAlignment(Qt.AlignCenter) logger.debug("set_layouts:end") # 设置按钮 def set_buttons(self): logger.debug("set_buttons:begin") self.closeBtn.setText('×') self.closeBtn.clicked.connect(self.close) self.closeBtn.setToolTip('退出') # 最小化。 self.minBtn.setText('-') self.minBtn.clicked.connect(self.showMinimized) self.minBtn.setToolTip('最小化') # 最大化。 self.maxBtn.setText('□') self.maxBtn.setToolTip('^_^此功能已上火星') # 登陆。 self.loginBtn.setText('') self.loginBtn.setToolTip('登陆') # 搜索输入框。 self.searchInput.resize(48, 48) # 搜索按钮 self.searchBtn.setText('') self.searchBtn.setToolTip('点击搜索') # 查询。 self.qryBtn.setIcon(QIcon('icons/qryBtn.png')) self.qryBtn.setText("查询") self.qryBtn.clicked.connect(self.qryFunc) self.qryBtn.setAutoRaise(True) self.qryBtn.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) # 增加。 self.addBtn.setIcon(QIcon('icons/addBtn.png')) self.addBtn.setText("增加") self.addBtn.clicked.connect(self.addFunc) self.addBtn.setAutoRaise(True) self.addBtn.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) # 删除。 self.delBtn.setIcon(QIcon('icons/delBtn.png')) self.delBtn.setText("删除") self.delBtn.clicked.connect(self.delFunc) self.delBtn.setAutoRaise(True) self.delBtn.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) logger.debug("set_buttons:end") self.toolBox.setCurrentIndex(1) self.toolBox.setItemIcon(0,QIcon("icons/homeIcon.png")) self.toolBox.setItemIcon(1,QIcon("icons/homeIcon.png")) self.page1btn1.setIcon(QIcon("icons/homeIcon.png")) self.page1btn1.setText(self.tr("首页")) self.page1btn1.setIconSize(QSize(40,40)) self.page1btn1.setAutoRaise(True) self.page1btn1.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) self.page1btn2.setIcon(QIcon("icons/graphIcon.png")) self.page1btn2.setText(self.tr("图表")) self.page1btn2.setIconSize(QSize(40,40)) self.page1btn2.setAutoRaise(True) self.page1btn2.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) self.page1btn3.setIcon(QIcon("icons/taskIcon.png")) self.page1btn3.setText(self.tr("任务")) self.page1btn3.setIconSize(QSize(40,40)) self.page1btn3.setAutoRaise(True) self.page1btn3.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) self.page1btn4.setIcon(QIcon("icons/clockIcon.png")) self.page1btn4.setText(self.tr("提醒")) self.page1btn4.setIconSize(QSize(40,40)) self.page1btn4.setAutoRaise(True) self.page1btn4.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) self.page1btn5.setIcon(QIcon("icons/favIcon.png")) self.page1btn5.setText(self.tr("收藏")) self.page1btn5.setIconSize(QSize(40,40)) self.page1btn5.setAutoRaise(True) self.page1btn5.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) self.page1btn6.setIcon(QIcon("icons/kxianIcon.png")) self.page1btn6.setText(self.tr("k线")) self.page1btn6.setIconSize(QSize(40,40)) self.page1btn6.setAutoRaise(True) self.page1btn6.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) self.page2btn1.setIcon(QIcon("icons/marketIcon.png")) self.page2btn1.setText(self.tr("行情")) self.page2btn1.setIconSize(QSize(40,40)) self.page2btn1.setAutoRaise(True) self.page2btn1.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) logging.debug("self.page2btn1.clicked.connect(self.tsWork.findLimitupStocks)") self.page2btn1.clicked.connect(self.tsWork.findLimitupStocks) self.page2btn2.setIcon(QIcon("icons/stockIcon.png")) self.page2btn2.setText(self.tr("通联")) self.page2btn2.setIconSize(QSize(40,40)) self.page2btn2.setAutoRaise(True) self.page2btn2.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) self.page2btn3.setIcon(QIcon("icons/contactIcon.png")) self.page2btn3.setText(self.tr("货币供应")) self.page2btn3.setIconSize(QSize(40,40)) self.page2btn3.setAutoRaise(True) self.page2btn3.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) logging.debug("self.page2btn1.clicked.connect(self.tsWork.findLimitupStocks)") self.page2btn3.clicked.connect(self.tsWork.getMoneySupply) self.page2btn4.setIcon(QIcon("icons/calIcon.png")) self.page2btn4.setText(self.tr("绩效")) self.page2btn4.setIconSize(QSize(40,40)) self.page2btn4.setAutoRaise(True) self.page2btn4.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) def getLimitupStock_work(self): logging.debug("winview:begin getLimitupStock_work") tsWork=TushareWorkObject() tsWork.moveToThread(self.thread) ##另起子线程,防止ui主线程卡死 self.limupStockThread.setRun(6) logging.debug("winview:begin beginRun") self.limupStockThread.outSignal.connect(self.limupStockThread_outfunc) def limupStockThread_outfunc(self,text): QMessageBox.about( self, "涨停板股票收集",text) print("limupStockThread_outfunc"+text) def set_labels(self): logger.debug("set_labels:begin") titlePix = QPixmap() titlePix.load('icons/titleIcon.png') self.headIcon.setPixmap(titlePix.scaled(40, 40)) self.headTitle.setText("Wins百宝箱") self.topSpace.setText("") logger.debug("set_labels:end") def set_lines(self): logger.debug("set_lines:begin") self.searchInput.setPlaceholderText('搜索') logger.debug("set_lines:end") def load_tableview(self): logger.debug("load_tableview:begin") ###self.model数据初始化 self.tableModel.database().setDatabaseName(self.dbPath) self.tableModel.database().open() self.tableModel.setTable(self.curTable) self.tableModel.select() self.tableModel.setEditStrategy(QSqlTableModel.OnManualSubmit) # 数据更新的策略,详细可以查看Qt文档 self.tableView.setModel(self.tableModel) self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows) self.tableView.setSelectionMode(QAbstractItemView.ExtendedSelection) logger.debug("load_tableview:end") #查询按钮关联的槽函数 def qryFunc(self): #self.db.execSQL("select * from t1") QMessageBox.about( self, 'qryFuncCall', "qryFunc") #插入按钮关联的槽函数 def addFunc(self): f1=random.randint(1, 99) self.tableModel.insertRows(0, 1) self.tableModel.setData(self.tableModel.index(0, 0), f1) self.tableModel.setData(self.tableModel.index(0, 1), "test") self.tableModel.submitAll() QMessageBox.about( self, 'addFuncCall', "addFunc") def delFunc(self): rs=list(map(lambda x:x.row(),self.tableView.selectedIndexes())) if len(rs)==0: QMessageBox.information(self,'提醒','请先选中至少一行,再点击此按钮!') return for i in reversed(rs): self.tableModel.removeRows(i,1) self.tableModel.submitAll()
def __init__(self): QSqlTableModel.__init__(self) self.roles = {} self.setEditStrategy(QSqlTableModel.OnManualSubmit) self.lastAddedHash = ""
def open_alltable(self): ## tableView显示属性设置 self.ui.current_tableView.setSelectionBehavior( QAbstractItemView.SelectItems) self.ui.current_tableView.setSelectionMode( QAbstractItemView.SingleSelection) self.ui.current_tableView.setAlternatingRowColors(True) # 设置相邻记录的不同颜色 self.ui.current_tableView.verticalHeader().setDefaultSectionSize( 22) # 单元格高度 self.ui.current_tableView.horizontalHeader().setDefaultSectionSize( 160) # 单元格宽度 self.ui.enter_tableView.setSelectionBehavior( QAbstractItemView.SelectItems) self.ui.enter_tableView.setSelectionMode( QAbstractItemView.SingleSelection) self.ui.enter_tableView.setAlternatingRowColors(True) # 设置相邻记录的不同颜色 self.ui.enter_tableView.verticalHeader().setDefaultSectionSize( 22) # 单元格高度 self.ui.enter_tableView.horizontalHeader().setDefaultSectionSize( 160) # 单元格宽度 self.ui.out_tableView.setSelectionBehavior( QAbstractItemView.SelectItems) self.ui.out_tableView.setSelectionMode( QAbstractItemView.SingleSelection) self.ui.out_tableView.setAlternatingRowColors(True) # 设置相邻记录的不同颜色 self.ui.out_tableView.verticalHeader().setDefaultSectionSize( 22) # 单元格高度 self.ui.out_tableView.horizontalHeader().setDefaultSectionSize( 160) # 单元格宽度 self.ui.VICEtableView.setSelectionBehavior( QAbstractItemView.SelectItems) self.ui.VICEtableView.setSelectionMode( QAbstractItemView.SingleSelection) self.ui.VICEtableView.setAlternatingRowColors(True) # 设置相邻记录的不同颜色 self.ui.VICEtableView.verticalHeader().setDefaultSectionSize( 22) # 单元格高度 self.ui.VICEtableView.horizontalHeader().setDefaultSectionSize( 240) # 单元格宽度 # 连接到数据库并打开 self.DB = QSqlDatabase.addDatabase( 'QSQLITE') # 建立与数据库的连接,即QSqlDatabase对象 self.DB.setDatabaseName('MES5.db') # 设置数据库名称 self.DB.open() # 打开数据库 print('数据库打开成功') ## 打开现有库存数据表 self.current_tabModel = QSqlTableModel(self, self.DB) # 创建数据表的模型 self.current_tabModel.setTable('工件信息表') # 设置需要连接的数据表 self.current_tabModel.setEditStrategy(QSqlTableModel.OnManualSubmit) ## 打开入库记录表 self.enter_tabModel = QSqlTableModel(self, self.DB) # 创建数据表的模型 self.enter_tabModel.setTable('入库记录表') # 设置需要连接的数据表 self.enter_tabModel.setEditStrategy(QSqlTableModel.OnManualSubmit) ## 打开出库记录表 self.out_tabModel = QSqlTableModel(self, self.DB) # 创建数据表的模型 self.out_tabModel.setTable('出库记录表') # 设置需要连接的数据表 self.out_tabModel.setEditStrategy(QSqlTableModel.OnManualSubmit) ## 打开固定批RFID表======================================================== self.vice_tabModel = QSqlTableModel(self, self.DB) # 创建数据表的模型 self.vice_tabModel.setTable('新建表') # 设置需要连接的数据表 self.vice_tabModel.setEditStrategy(QSqlTableModel.OnManualSubmit) self.ui.VICEtableView.setModel( self.vice_tabModel) # 为一个QTableView组件设置一个QSqlTabelModel模型 self.vice_tabModel.select() # 建立RFID与组件的映射关系 self.mapper = QDataWidgetMapper() self.mapper.setModel(self.vice_tabModel) self.mapper.setSubmitPolicy(QDataWidgetMapper.AutoSubmit) ##界面组件与tabelmodel的具体字段之间的联系 self.mapper.addMapping(self.ui.RFIDlineEdit, 0) self.mapper.toFirst() # 移动到首记录 # 选中数据时信号的发射 self.selModel = QItemSelectionModel(self.vice_tabModel) self.selModel.currentRowChanged.connect(self.do_currentRowChanged) self.ui.VICEtableView.setSelectionModel(self.selModel) # 设置选择模型 # =============================================================================== self.refresh() print('数据表打开成功') ##获取字段名和序号的字典数据 empty = self.current_tabModel.record() # 得到的是一个空的记录,获取表的字段定义 self.fldNum = {} for i in range(empty.count()): filedname = empty.fieldName(i) empty.field(filedname).setReadOnly(True) # 每个字段设置为只读 self.fldNum.setdefault( filedname, i) # 如果字典中包含有给定键,则返回该键对应的值,否则将键添加到字典中,默认值为None print(self.fldNum) print(self.current_tabModel.record().count())
class TableToTreeModel2 (QAbstractItemModel): """ Более новый вариант - используем композицию, то есть абстрактная модель включает в себя sql табличную модель только для работы с базой данных """ def __init__(self, m, connection): QAbstractItemModel.__init__(self, m) # попробуем сделать композицию self.dbmodel = QSqlTableModel(self, connection) self.dbmodel.setEditStrategy(0) # при каждом изменении поля #print (self.dbmodel.hasIndex(1,12)) self.headers=['id', '_buy', 'deadline', 'made', 'significance', 'urgency', '_children', '_next', '_parents', '_prev', 'season', 'short text', 'tags', 'text'] self.rootItem = TreeItem (self.headers) def setTable(self, tname): self.dbmodel.setTable(tname) def select(self): self.dbmodel.select() #здесь должны грузиться данные dct = dict () #словарь айди - список строк с данными for ind in range (self.dbmodel.rowCount()): #dct[int(self.dbmodel.data(self.dbmodel.index(ind,0)))] = [self.dbmodel.data(self.dbmodel.index(ind,j)) for j in range(self.dbmodel.columnCount())] dct[int(self.dbmodel.data(self.dbmodel.index(ind,0)))] = [self.dbmodel.data(self.dbmodel.index(ind,j)) for j in range(self.dbmodel.columnCount())] def find_children_and_append (item:TreeItem, dct): chlist = eval(item.data(6)) for ch in chlist: tri = TreeItem(dct[ch], item) if tri.data(6) != '[]': find_children_and_append(tri,dct) item.appendChild(tri) for i in [j for j in dct.values() if j[8]=='[]']: tri = TreeItem(i, self.rootItem) find_children_and_append(tri,dct) self.rootItem.appendChild(tri) def columnCount(self, QModelIndex_parent=None, *args, **kwargs): return self.dbmodel.columnCount() def data(self, index, role): if not index.isValid(): return None if role != Qt.DisplayRole: return None item = index.internalPointer() return item.data(index.column()) def flags(self, index): if not index.isValid(): return Qt.NoItemFlags return Qt.ItemIsEnabled | Qt.ItemIsSelectable |Qt.ItemIsEditable def headerData(self, section, orientation, role): if orientation == Qt.Horizontal and role == Qt.DisplayRole: return self.headers[section] #return self.dbmodel.headerData(section,orientation,role) def index(self, row, column, parent): if not self.hasIndex(row, column, parent): return QModelIndex() if not parent.isValid(): parentItem = self.rootItem else: parentItem = parent.internalPointer() childItem = parentItem.child(row) if childItem: return self.createIndex(row, column, childItem) else: return QModelIndex() def rowCount(self, parent): if parent.column() > 0: return 0 if not parent.isValid(): parentItem = self.rootItem else: parentItem = parent.internalPointer() return parentItem.childCount() def parent(self, index): if not index.isValid(): return QModelIndex() childItem = index.internalPointer() parentItem = childItem.parent() if parentItem == self.rootItem: return QModelIndex() return self.createIndex(parentItem.row(), 0, parentItem) def getIndexById(self, _id): for i in range (self.dbmodel.rowCount()): if int (self.dbmodel.data(self.dbmodel.index(i,0)))==_id: return self.dbmodel.index(i,0) return QModelIndex() def setData(self, modelIndex, value, int_role=Qt.EditRole): """ Функция вызывается при установке данных :param QModelIndex: :param QVariant: :param int_role: :return: """ print (self.dbmodel.record(0).setValue(12, 'sdfsfsdf')) r = self.dbmodel.record(1) r.setValue(12, 'Krevedko') print (self.dbmodel.setRecord(0,r)) print (r) return 1
class mainUi(QWidget): def __init__(self,sch): filename = os.getcwd() + '\\db.db' db = QSqlDatabase.addDatabase("QSQLITE") db.setDatabaseName(filename) super().__init__() self.addpcModel = QSqlTableModel(self) self.addpcModel.setTable(sch) #self.addpcModel.setSort(NAME, Qt.AscendingOrder) self.addpcModel.setHeaderData(0, Qt.Horizontal,"ID") self.addpcModel.setHeaderData(1, Qt.Horizontal, "电脑名称") self.addpcModel.setHeaderData(2, Qt.Horizontal,"仪器名称") self.addpcModel.setHeaderData(6, Qt.Horizontal, '最近成功爬取时间') self.addpcModel.setHeaderData(3,Qt.Horizontal,'抓取路径') self.addpcModel.setHeaderData(4,Qt.Horizontal,'保存路径') self.addpcModel.setHeaderData(5,Qt.Horizontal,'最近爬取时间') # self.addpcModel.setData(1,'ok') self.addpcModel.removeColumn(8) self.addpcModel.removeColumn(7) self.addpcModel.query() self.addpcModel.select() # self.addpcModel.select() self.setupUI() def setupUI(self): self.setWindowTitle('欣捷工作站数据文件自动爬取工具') self.resize(800,600) self.v = QHBoxLayout() #左右分栏 self.h1 = QVBoxLayout() self.h2 = QVBoxLayout() self.h1_1 = QHBoxLayout() self.h1_2 = QHBoxLayout() self.h1.addLayout(self.h1_1) self.h1.addLayout(self.h1_2) self.v.addLayout(self.h1) self.v.addLayout(self.h2) self.v.setStretchFactor(self.h1,6) self.v.setStretchFactor(self.h2,4) self.btn_start = QPushButton('马上运行',self) self.btn_viewlog = QPushButton('查看以前日志',self) self.h1_1.addWidget(self.btn_start) self.h1_1.addWidget(self.btn_viewlog) self.txt_log = QTextEdit('',self) self.h1_2.addWidget(self.txt_log) self.btn_addpc = QPushButton('添加需要爬取的电脑',self) self.sch_view = QTableView() self.sch_view.setModel(self.addpcModel) self.sch_view.setSelectionMode(QTableView.SingleSelection) self.sch_view.setSelectionBehavior(QTableView.SelectRows) self.sch_view.setColumnHidden(0, True) self.sch_view.resizeColumnsToContents() self.h2.addWidget(self.btn_addpc) self.h2.addWidget(self.sch_view) self.setLayout(self.v) self.setWindowOpacity(1) self.show()
class Window(QWidget): tbl_contacts: QTableView model: QSqlTableModel selectedIndex: QModelIndex = None __searching: str = None __selected_keywork: str = 'name' __dict_keyword: dict def __init__(self) -> None: super().__init__() print(f'connect to datase: {connection()}') print(f'create table contacts: {create_table_contacts()}') print( f'create anydesk_uniq_index: {add_uniq_constraint_col_anydesk()}') self.__init_ui() self.__initialize_model() def __initialize_model(self) -> None: self.model.setTable('contacts') self.model.setEditStrategy(QSqlTableModel.OnManualSubmit) # self.model.setQuery('SELECT * FROM contacts') self.model.setHeaderData(0, Qt.Horizontal, 'ID') self.model.setHeaderData(1, Qt.Horizontal, 'AÇÃO') self.model.setHeaderData(2, Qt.Horizontal, 'ANYDESK') self.model.setHeaderData(3, Qt.Horizontal, 'NOME') self.model.select() self.tbl_contacts.setColumnHidden(0, True) def __init_ui(self) -> None: qApp.setStyle('Fusion') self.setWindowIcon(QIcon(resource_path("logo.ico"))) self.setWindowTitle('Lista de Contatos') self.model = QSqlTableModel() self.setMinimumSize(800, 400) root_layout: QVBoxLayout = QVBoxLayout() # search hbox_search: QHBoxLayout = QHBoxLayout() search_lbl: QLabel = QLabel('Buscar') self.__dict_keyword = {'nome': 'name', 'anydesk': 'anydesk'} keyword_cmb: QComboBox = QComboBox() keyword_cmb.addItems(self.__dict_keyword.keys()) keyword_cmb.currentTextChanged.connect(self.__set_selected_keyword) search_txt: QLineEdit = QLineEdit() search_txt.setValidator(UpperCaseValidator(self)) search_txt.textChanged.connect(self.__update_searching) search_txt.returnPressed.connect(self.__search) search_btn: QPushButton = QPushButton('Buscar') search_btn.clicked.connect(self.__search) hbox_search.addWidget(search_lbl) hbox_search.addWidget(keyword_cmb) hbox_search.addWidget(search_txt) hbox_search.addWidget(search_btn) root_layout.addLayout(hbox_search) # ./search hbox_container: QHBoxLayout = QHBoxLayout() self.tbl_contacts = QTableView() button_delegate = ButtonDelegate() button_delegate.clicked[int, int].connect(self.__on_click_button_delegate) self.tbl_contacts.setEditTriggers(QTableView.NoEditTriggers) # Type Selection self.tbl_contacts.setAlternatingRowColors(True) self.tbl_contacts.setSelectionMode(QTableView.SingleSelection) self.tbl_contacts.setSelectionBehavior(QTableView.SelectRows) self.tbl_contacts.setModel(self.model) self.tbl_contacts.setItemDelegateForColumn(1, button_delegate) # Enable sorting self.tbl_contacts.setSortingEnabled(True) # Adjust Header horizontal_header: QHeaderView = self.tbl_contacts.horizontalHeader() horizontal_header.setSectionResizeMode(QHeaderView.ResizeToContents) horizontal_header.setStretchLastSection(True) size = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) size.setHorizontalStretch(1) self.tbl_contacts.setSizePolicy(size) # events self.tbl_contacts.clicked.connect(self.__set_selected_row) hbox_container.addWidget(self.tbl_contacts) vbox: QVBoxLayout = QVBoxLayout() self.new_btn: QPushButton = QPushButton('Novo') self.new_btn.clicked.connect(self.__new) self.edit_btn: QPushButton = QPushButton('Editar') self.edit_btn.clicked.connect(self.__edit) self.destroy_btn: QPushButton = QPushButton('Excluir') self.destroy_btn.clicked.connect(self.__destroy) vbox.addWidget(self.new_btn) vbox.addWidget(self.edit_btn) vbox.addWidget(self.destroy_btn) vbox.addStretch(1) hbox_container.addLayout(vbox) root_layout.addLayout(hbox_container) self.setLayout(root_layout) self.show() def __new(self): dlg = NewContact(self, model=self.model) dlg.exec_() def __edit(self): if not self.selectedIndex: QMessageBox.warning( self, 'Atenção', 'É necessário selecionar um item para alterar!') return record: QSqlRecord = self.model.record(self.selectedIndex.row()) dlg = NewContact(self, model=self.model, record=record, row=self.selectedIndex.row()) dlg.exec_() def __destroy(self): if self.selectedIndex: r = QMessageBox.question( self, 'Atenção', f'Tem certeza que deseja excluir o <b>{self.selectedIndex.data()}</b>', QMessageBox.Yes | QMessageBox.No, defaultButton=QMessageBox.No) if r == QMessageBox.Yes: self.model.deleteRowFromTable(self.selectedIndex.row()) self.model.submitAll() def __access(self, row: int): record: QSqlRecord = self.model.record(row) process = QProcess(self) process.setProcessChannelMode(QProcess.MergedChannels) process.start('anydesk', [record.value('anydesk')]) process.stateChanged.connect( lambda state: self.__state_process(row, state)) def __set_selected_row(self, index: QModelIndex): self.selectedIndex = index def __state_process(self, row: int, state): status = { QProcess.NotRunning: 'ACESSAR', QProcess.Starting: 'ABRINDO', QProcess.Running: 'ACESSANDO' } self.__update_action(row, status[state]) def __on_click_button_delegate(self, row: int, column: int): self.__access(row) def __update_action(self, row: int, message: str): record: QSqlRecord = self.model.record(row) record.setValue('action', message) if self.model.updateRowInTable(row, record): if not self.model.submitAll(): self.model.revertAll() QMessageBox.critical( self, 'Erro', f'Ocorreu um erro ao salvar!\nErro: {self.model.lastError().text()}' ) return else: self.model.revertAll() QMessageBox.critical( self, 'Erro', f'Ocorreu um erro ao salvar!\nErro: {self.model.lastError().text()}' ) def __update_searching(self, text: str): self.__searching = text def __set_selected_keyword(self, keyword: str): self.__selected_keywork = self.__dict_keyword[keyword] def __search(self): if not self.__searching or self.__searching.strip() == '': self.model.setFilter('') # self.model.select() else: self.model.setFilter( f"{self.__selected_keywork} like '{self.__searching}'")
class TableEditor(QDialog): def __init__(self, tableName, parent=None): super(TableEditor, self).__init__(parent) self.model = QSqlTableModel(self) self.model.setTable(tableName) self.model.setEditStrategy(QSqlTableModel.OnManualSubmit) self.model.select() self.model.setHeaderData(0, Qt.Horizontal, "ID") self.model.setHeaderData(1, Qt.Horizontal, "First name") self.model.setHeaderData(2, Qt.Horizontal, "Last name") view = QTableView() view.setModel(self.model) submitButton = QPushButton("Submit") submitButton.setDefault(True) revertButton = QPushButton("&Revert") quitButton = QPushButton("Quit") buttonBox = QDialogButtonBox(Qt.Vertical) buttonBox.addButton(submitButton, QDialogButtonBox.ActionRole) buttonBox.addButton(revertButton, QDialogButtonBox.ActionRole) buttonBox.addButton(quitButton, QDialogButtonBox.RejectRole) submitButton.clicked.connect(self.submit) revertButton.clicked.connect(self.model.revertAll) quitButton.clicked.connect(self.close) mainLayout = QHBoxLayout() mainLayout.addWidget(view) mainLayout.addWidget(buttonBox) self.setLayout(mainLayout) self.setWindowTitle("Cached Table") def submit(self): self.model.database().transaction() if self.model.submitAll(): self.model.database().commit() QMessageBox.information(self, "Record", "Jumlah record= %s" % self.model.rowCount()) else: self.model.database().rollback() QMessageBox.warning(self, "Cached Table", "The database reported an error: %s" % self.model.lastError().text())
class Reservations(QWidget): """ Klasa odpowiedzialna za widget klienci """ def __init__(self, parent, db): super(QWidget, self).__init__(parent) self.parent = parent self.btn_mod = QPushButton('Zmiana statusu') self.btn_usun = QPushButton('Usuń') self.btn_dodaj = QPushButton('Dodaj') self.lbl_klient_ = QLabel('') self.lbl_usluga_ = QLabel('') self.lbl_termin_ = QDateTimeEdit() self.gb_layout = QVBoxLayout() self.kalendarz = QCalendarWidget() self.view_u = QTableView() self.view_k = QTableView() self.view_p = QTableView() self.view = QTableView() self.proxy_u = QSortFilterProxyModel(self) self.proxy_k = QSortFilterProxyModel(self) self.proxy_p = QSortFilterProxyModel(self) self.proxy = QSortFilterProxyModel(self) self.id_klient = -1 self.id_usluga = -1 self.id_pracownik = -1 self.id_rezerwacje = -1 self.data = None self.data_do = None self.dzien_tyg = 0 self.czas = [] # Lista składana przycisków godzin self.btn_godz = [QPushButton(str(i + 1)) for i in range(16)] # Parametry połączenia z bazą self.model_u = QSqlTableModel(self, db) self.model_k = QSqlTableModel(self, db) self.model_p = QSqlTableModel(self, db) self.model = QSqlTableModel(self, db) self.initUI() def initUI(self): """ Inicjuje UI """ self.view_u.setObjectName('Usługi') self.view_k.setObjectName('Klienci') self.view_p.setObjectName('Pracownicy') self.view.setObjectName('Rezerwacje') self.table_init_u() self.table_init_k() self.table_init_p() self.table_init() self.btn_mod.setDisabled(True) self.btn_usun.setDisabled(True) self.btn_dodaj.setDisabled(True) # Tworzenie kontrolek lbl_wysz_u = QLabel('Wyszukaj usługę:') lbl_wysz_k = QLabel('Wyszukaj klienta:') lbl_wysz_p = QLabel('Wyszukaj pracownika:') txt_wysz_u = QLineEdit(self) txt_wysz_k = QLineEdit(self) txt_wysz_p = QLineEdit(self) lbl_klient = QLabel('Klient:') lbl_usluga = QLabel('Usługa:') lbl_termin = QLabel('Termin:') sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.kalendarz.sizePolicy().hasHeightForWidth()) self.kalendarz.setSizePolicy(sizePolicy) # Tworzenie widoków centralbox = QHBoxLayout() hbox_wysz_u = QHBoxLayout() hbox_wysz_k = QHBoxLayout() hbox_wysz_p = QHBoxLayout() vbox_u = QVBoxLayout() vbox_k = QVBoxLayout() vbox_p = QVBoxLayout() vbox_right = QVBoxLayout() hbox_btn = QHBoxLayout() hbox_k = QHBoxLayout() hbox_u = QHBoxLayout() hbox_t = QHBoxLayout() vbox_cal = QVBoxLayout() groupbox = QGroupBox('Godziny:') groupbox.setLayout(self.gb_layout) hbox_left = QHBoxLayout() # Metody self.lbl_termin_.setCalendarWidget(self.kalendarz) self.lbl_termin_.setDate(self.kalendarz.selectedDate()) self.dzien_tyg = self.kalendarz.selectedDate().dayOfWeek() txt_wysz_u.textChanged.connect(self.searching_u) txt_wysz_k.textChanged.connect(self.searching_k) txt_wysz_p.textChanged.connect(self.searching_p) self.view_k.clicked.connect(lambda: self.clicked_table(self.view_k)) self.view_p.clicked.connect(lambda: self.clicked_table(self.view_p)) self.view_u.clicked.connect(lambda: self.clicked_table(self.view_u)) self.view.clicked.connect(lambda: self.clicked_table(self.view)) self.kalendarz.clicked.connect(self.show_data) self.btn_dodaj.clicked.connect(self.add) self.btn_mod.clicked.connect(self.modify) self.btn_usun.clicked.connect(self.remove) # Ustawianie widoków hbox_wysz_k.addWidget(lbl_wysz_k) hbox_wysz_k.addWidget(txt_wysz_k) hbox_wysz_p.addWidget(lbl_wysz_p) hbox_wysz_p.addWidget(txt_wysz_p) hbox_wysz_u.addWidget(lbl_wysz_u) hbox_wysz_u.addWidget(txt_wysz_u) vbox_u.addLayout(hbox_wysz_u) vbox_u.addWidget(self.view_u) vbox_k.addLayout(hbox_wysz_k) vbox_k.addWidget(self.view_k) vbox_p.addLayout(hbox_wysz_p) vbox_p.addWidget(self.view_p) vbox_right.addLayout(vbox_p) vbox_right.addLayout(vbox_u) vbox_right.addLayout(vbox_k) hbox_btn.addWidget(self.btn_usun) hbox_btn.addWidget(self.btn_mod) hbox_k.addWidget(lbl_klient) hbox_k.addWidget(self.lbl_klient_) hbox_u.addWidget(lbl_usluga) hbox_u.addWidget(self.lbl_usluga_) hbox_t.addWidget(lbl_termin) hbox_t.addWidget(self.lbl_termin_) vbox_cal.addWidget(self.kalendarz) vbox_cal.addLayout(hbox_u) vbox_cal.addLayout(hbox_t) vbox_cal.addLayout(hbox_k) self.view.setSizePolicy( QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)) vbox_cal.addWidget(self.view) vbox_cal.addLayout(hbox_btn) vbox_cal.addWidget(self.btn_dodaj) hbox_left.addLayout(vbox_cal) hbox_left.addWidget(groupbox) centralbox.addLayout(hbox_left) centralbox.addLayout(vbox_right) self.setLayout(centralbox) self.show() def show_data(self): self.lbl_termin_.setDate(self.kalendarz.selectedDate()) self.dzien_tyg = self.kalendarz.selectedDate().dayOfWeek() self.clicked_table(self.view_p) def table_init_u(self): """ Inicjuje wygląd tabeli usługi """ # self.model_u.setTable('uslugi') query = QSqlQuery( 'SELECT uslugi.uslugi_id, uslugi.nazwa, uslugi.cena, date_format(uslugi.czas, "%H:%i") AS czas FROM uslugi NATURAL JOIN uzytkownik_usluga WHERE uzytkownik_usluga.uzytkownik_id = ' + str(self.id_pracownik) + ';') self.model_u.setQuery(query) # self.model_u.select() self.proxy_u.setSourceModel(self.model_u) naglowki = { 'uslugi_id': 'ID', 'nazwa': 'Nazwa', 'cena': 'Cena', "czas": 'Czas', } # Ustawianie nagłówków ilosc_kolumn = self.model_u.columnCount() for i in range(ilosc_kolumn): nazwa_kolumn = self.model_u.headerData(i, Qt.Horizontal) self.model_u.setHeaderData(i, Qt.Horizontal, naglowki[nazwa_kolumn]) self.view_u.setSizeAdjustPolicy( QAbstractScrollArea.AdjustToContentsOnFirstShow) self.view_u.setSortingEnabled(True) self.view_u.setAlternatingRowColors(True) # Wczytanie danych self.view_u.setModel(self.proxy_u) self.view_u.hideColumn(0) self.view_u.sortByColumn(1, Qt.AscendingOrder) self.view_u.setEditTriggers(QAbstractItemView.NoEditTriggers) def table_init_k(self): """ Inicjuje wygląd tabeli klienta """ self.model_k.setTable('klienci') query = QSqlQuery( 'SELECT klienci_id, imie, nazwisko, email, telefon, ulica, numer_mieszkania, miejscowosc, poczta FROM ' 'klienci;') self.model_k.setQuery(query) # self.model_k.select() self.proxy_k.setSourceModel(self.model_k) naglowki = { 'klienci_id': 'ID', 'imie': 'Imię', 'nazwisko': 'Nazwisko', "email": 'Email', 'telefon': 'Telefon', 'ulica': 'Ulica', 'numer_mieszkania': 'Numer mieszkania', 'miejscowosc': 'Miejscowosc', 'poczta': 'Kod pocztowy', } # Ustawianie nagłówków ilosc_kolumn = self.model_k.columnCount() for i in range(ilosc_kolumn): nazwa_kolumn = self.model_k.headerData(i, Qt.Horizontal) self.model_k.setHeaderData(i, Qt.Horizontal, naglowki[nazwa_kolumn]) self.view_k.setSizeAdjustPolicy( QAbstractScrollArea.AdjustToContentsOnFirstShow) self.view_k.setSortingEnabled(True) self.view_k.setAlternatingRowColors(True) # Wczytanie danych self.view_k.setModel(self.proxy_k) self.view_k.hideColumn(0) self.view_k.sortByColumn(1, Qt.AscendingOrder) self.view_k.setEditTriggers(QAbstractItemView.NoEditTriggers) def table_init_p(self): """ Inicjuje wygląd tabeli pracownik """ self.model_p.setTable('uzytkownik') query = QSqlQuery( 'SELECT uzytkownik_id, imie, nazwisko FROM uzytkownik WHERE ' 'pracownik = 1;') self.model_p.setQuery(query) # self.model_p.select() self.proxy_p.setSourceModel(self.model_p) naglowki = { 'uzytkownik_id': 'ID', 'imie': 'Imię', "nazwisko": 'Nazwisko', } # Ustawianie nagłówków ilosc_kolumn = self.model_p.columnCount() for i in range(ilosc_kolumn): nazwa_kolumn = self.model_p.headerData(i, Qt.Horizontal) self.model_p.setHeaderData(i, Qt.Horizontal, naglowki[nazwa_kolumn]) self.view_p.setSizeAdjustPolicy( QAbstractScrollArea.AdjustToContentsOnFirstShow) self.view_p.setSortingEnabled(True) self.view_p.setAlternatingRowColors(True) # Wczytanie danych self.view_p.setModel(self.proxy_p) self.view_p.hideColumn(0) self.view_p.sortByColumn(1, Qt.AscendingOrder) self.view_p.setEditTriggers(QAbstractItemView.NoEditTriggers) def table_init(self): """ Inicjuje wygląd tabeli """ query = QSqlQuery( 'SELECT wizyty.wizyty_id, CONCAT(klienci.imie, " ", klienci.nazwisko) AS klient, uslugi.nazwa, ' 'wizyty.rezerwacja_od, wizyty.rezerwacja_do, wizyty.status FROM klienci, uslugi NATURAL JOIN wizyty WHERE wizyty.rezerwacja_od > CURRENT_TIMESTAMP AND wizyty.uzytkownik_id = ' + str(self.id_pracownik) + ';') self.model.setQuery(query) self.proxy.setSourceModel(self.model) naglowki = { 'wizyty_id': 'ID', 'klient': 'Klient', 'nazwa': 'Usługa', 'rezerwacja_od': 'Rezerwacja od', "rezerwacja_do": 'Rezerwacja do', 'status': 'Status rezerwacji' } # Ustawianie nagłówków ilosc_kolumn = self.model.columnCount() for i in range(ilosc_kolumn): nazwa_kolumn = self.model.headerData(i, Qt.Horizontal) self.model.setHeaderData(i, Qt.Horizontal, naglowki[nazwa_kolumn]) self.view.setSizeAdjustPolicy( QAbstractScrollArea.AdjustToContentsOnFirstShow) self.view.setSortingEnabled(True) self.view.setAlternatingRowColors(True) # Wczytanie danych self.view.setModel(self.proxy) self.view.hideColumn(0) self.view.sortByColumn(4, Qt.AscendingOrder) self.view.setEditTriggers(QAbstractItemView.NoEditTriggers) def clicked_table(self, view): """ Metoda edytująca zaznaczone wiersze - Wstawia wartości z wierszy w odpowiednie pola """ index = (view.selectionModel().currentIndex()) if view.objectName() == 'Klienci': self.id_klient = index.sibling(index.row(), 0).data() self.lbl_klient_.setText('<b>' + index.sibling(index.row(), 1).data() + ' ' + index.sibling(index.row(), 2).data() + '</b>') elif view.objectName() == 'Usługi': self.id_usluga = index.sibling(index.row(), 0).data() self.lbl_usluga_.setText('<b>' + index.sibling(index.row(), 1).data() + '</b>') self.data_do = index.sibling(index.row(), 3).data() elif view.objectName() == 'Rezerwacje': self.id_rezerwacje = index.sibling(index.row(), 0).data() if self.id_rezerwacje > 0: self.btn_mod.setEnabled(True) self.btn_usun.setEnabled(True) elif view.objectName() == 'Pracownicy': self.id_pracownik = index.sibling(index.row(), 0).data() self.czas = [] for i in reversed(range(self.gb_layout.count())): self.gb_layout.itemAt(i).widget().setParent(None) czas = datetime.datetime(2000, 1, 1, 8, 0) dzien = { 1: ('pon_od', 'pon_do'), 2: ('wt_od', 'wt_do'), 3: ('sr_od', 'sr_do'), 4: ('czw_od', 'czw_do'), 5: ('pt_od', 'pt_do'), 6: ('sob_od', 'sob_do'), 7: ('', '') } query = 'SELECT date_format({}, "%H") AS g_start, date_format({}, "%H") AS g_stop FROM godziny WHERE ' \ 'uzytkownik_id = {};'.format(dzien[self.dzien_tyg][0], dzien[self.dzien_tyg][1], self.id_pracownik) wynik = query_to_db(query) if wynik: godzina_stop = (int(wynik[1]) - int(wynik[0])) * 2 godzina = int(wynik[0]) for btn in self.btn_godz: btn.setEnabled(True) else: godzina_stop = 0 godzina = 1 for btn in self.btn_godz: btn.setDisabled(True) minuta = 0 czas = datetime.time(godzina, minuta) for i in range(godzina_stop): self.btn_godz[i].setText(czas.strftime("%H:%M")) self.czas.append(czas) self.btn_godz[i].setObjectName(str(i)) self.gb_layout.addWidget(self.btn_godz[i]) if i % 2 != 0: godzina += 1 minuta = 0 else: minuta = 30 czas = datetime.time(godzina, minuta) QMetaObject.connectSlotsByName(self) # Czyszczenie, odświeżanie self.refresh() query = QSqlQuery( 'SELECT uslugi.uslugi_id, uslugi.nazwa, uslugi.cena, date_format(uslugi.czas, "%H:%i") AS czas FROM uslugi NATURAL JOIN uzytkownik_usluga WHERE uzytkownik_usluga.uzytkownik_id = ' + str(self.id_pracownik) + ';') self.model_u.setQuery(query) self.lbl_klient_.setText('') self.lbl_usluga_.setText('') if self.id_klient > 0 and self.id_pracownik > 0 and self.id_usluga > 0: self.btn_dodaj.setEnabled(True) def if_checked(self, txt, q, val=None): """ Sprawdza poprawność wprowadzonych damych. :param val: wartości do zapytania :param q: zapytanie query MySql :param txt: komunikat """ if self.id_klient < 0 and self.id_pracownik < 0 and self.id_usluga < 0 and self.data is None: msg = QMessageBox(self) msg.setIcon(QMessageBox.Warning) msg.setText(txt) msg.setWindowTitle("Popraw dane") msg.exec_() return False else: print('Trwa zmiana w bazie danych') if val: print('Połączenie') query_to_db(q, val) else: print('Transakcja') return transaction_to_db(q) return True def refresh(self): """ Odświeża widok tabeli rezerwacji """ # Odświeżanie widoku tabeli query = QSqlQuery( 'SELECT wizyty.wizyty_id, CONCAT(klienci.imie, " ", klienci.nazwisko) AS klient, uslugi.nazwa, ' 'wizyty.rezerwacja_od, wizyty.rezerwacja_do, wizyty.status FROM wizyty,klienci,uslugi WHERE wizyty.klienci_id= klienci.klienci_id AND wizyty.uslugi_id = uslugi.uslugi_id AND wizyty.rezerwacja_od > CURRENT_TIMESTAMP AND wizyty.uzytkownik_id = ' + str(self.id_pracownik) + ';') self.model.setQuery(query) self.view.reset() def add(self): """ Dodaje rezerwację do bazy danych i odświeża widok. """ tekst = 'Nie wprowadzono wszystkich danych' self.data = self.lbl_termin_.dateTime().toString(Qt.ISODate) self.data_do = datetime.datetime.fromisoformat( self.data) + datetime.timedelta( hours=datetime.time.fromisoformat(self.data_do).hour, minutes=datetime.time.fromisoformat(self.data_do).minute) # Dodanie nowego użytkownika query = 'INSERT INTO wizyty (klienci_id, uslugi_id, uzytkownik_id, rezerwacja_od, rezerwacja_do, ' \ 'status) VALUES (%s, %s, %s, %s, %s, %s);' val = (self.id_klient, self.id_usluga, self.id_pracownik, self.data, str(self.data_do.isoformat()), 'oczekuje') print(val) if self.if_checked(tekst, query, val): msg = QMessageBox(self) msg.setIcon(QMessageBox.Information) msg.setText('Rezerwacja została dodana do bazy danych') msg.setWindowTitle("Dodano nową rezerwację") msg.exec_() self.refresh() def modify(self): """ Zmienia status rezerwacji i odświeża widok. """ tekst = 'Nie wprowadzono wszystkich danych' items = ('Oczekuje', 'Wykonana', 'Rezygnacja') item, ok = QInputDialog.getItem(self, "Wybierz status", "Wybierz nowy status rezerwacji", items, 0, False) if ok and item: # Zmodyfikowanie statusu query = 'UPDATE wizyty SET status = %s WHERE wizyty_id = %s;' val = (item.lower(), self.id_rezerwacje) if self.if_checked(tekst, query, val): msg = QMessageBox(self) msg.setIcon(QMessageBox.Information) msg.setText('Status rezerwacji został zmodyfikowany') msg.setWindowTitle("Zmodyfikowano status") msg.exec_() self.refresh() def remove(self): """ Usuwa rezerwację z bazy danych """ test = 'Błąd! Nie można usunąć danej rezerwacji!' query = 'DELETE FROM wizyty WHERE wizyty_id = %s' val = (self.id_rezerwacje, ) ret = QMessageBox.question( self, 'Usuwanie rezerwacji', "Czy na pewno chcesz usunąć daną rezerwację klienta?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if ret == QMessageBox.Yes: if self.if_checked(test, query, val): msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText('Rezerwacja została usunięta') msg.setWindowTitle("Usunięto") msg.exec_() self.refresh() @pyqtSlot() def on_0_clicked(self): self.lbl_termin_.setTime(self.czas[0]) @pyqtSlot() def on_1_clicked(self): self.lbl_termin_.setTime(self.czas[1]) @pyqtSlot() def on_2_clicked(self): self.lbl_termin_.setTime(self.czas[2]) @pyqtSlot() def on_3_clicked(self): self.lbl_termin_.setTime(self.czas[3]) @pyqtSlot() def on_4_clicked(self): self.lbl_termin_.setTime(self.czas[4]) @pyqtSlot() def on_5_clicked(self): self.lbl_termin_.setTime(self.czas[5]) @pyqtSlot() def on_6_clicked(self): self.lbl_termin_.setTime(self.czas[6]) @pyqtSlot() def on_7_clicked(self): self.lbl_termin_.setTime(self.czas[7]) @pyqtSlot() def on_8_clicked(self): self.lbl_termin_.setTime(self.czas[8]) @pyqtSlot() def on_9_clicked(self): self.lbl_termin_.setTime(self.czas[9]) @pyqtSlot() def on_10_clicked(self): self.lbl_termin_.setTime(self.czas[10]) @pyqtSlot() def on_11_clicked(self): self.lbl_termin_.setTime(self.czas[11]) @pyqtSlot() def on_12_clicked(self): self.lbl_termin_.setTime(self.czas[12]) @pyqtSlot() def on_13_clicked(self): self.lbl_termin_.setTime(self.czas[13]) @pyqtSlot() def on_14_clicked(self): self.lbl_termin_.setTime(self.czas[14]) @pyqtSlot() def on_15_clicked(self): self.lbl_termin_.setTime(self.czas[15]) @pyqtSlot(str) def searching_u(self, text): """ Wyszukuje po wszystkich kolumnach tabeli :param text: """ search = QRegExp(text, Qt.CaseInsensitive, QRegExp.RegExp) self.proxy_u.setFilterRegExp(search) # Odpowiedzialne za kolumnę, po której filtruje self.proxy_u.setFilterKeyColumn(-1) @pyqtSlot(str) def searching_k(self, text): """ Wyszukuje po wszystkich kolumnach tabeli :param text: """ search = QRegExp(text, Qt.CaseInsensitive, QRegExp.RegExp) self.proxy_k.setFilterRegExp(search) # Odpowiedzialne za kolumnę, po której filtruje self.proxy_k.setFilterKeyColumn(-1) @pyqtSlot(str) def searching_p(self, text): """ Wyszukuje po wszystkich kolumnach tabeli :param text: """ search = QRegExp(text, Qt.CaseInsensitive, QRegExp.RegExp) self.proxy_p.setFilterRegExp(search) # Odpowiedzialne za kolumnę, po której filtruje self.proxy_p.setFilterKeyColumn(-1)
view.setWindowTitle(title) return view def addrow(): ret = model.insertRows( model.rowCount(), 1 ) print( 'insertRows=%s' %str(ret) ) def findrow(i): delrow= i.row() print('del row=%s' % str(delrow) ) if __name__ == '__main__': app = QApplication(sys.argv) db = QSqlDatabase.addDatabase('QSQLITE') db.setDatabaseName('./db/database.db') model = QSqlTableModel() delrow = -1 initializeModel(model) view1 = createView("Table Model (View 1)", model) view1.clicked.connect(findrow) dlg = QDialog() layout = QVBoxLayout() layout.addWidget(view1) addBtn = QPushButton("添加一行") addBtn.clicked.connect(addrow) layout.addWidget(addBtn) delBtn = QPushButton("删除一行") delBtn.clicked.connect(lambda: model.removeRow(view1.currentIndex().row())) layout.addWidget(delBtn)
class Ui(QtWidgets.QMainWindow): def __init__(self): super(Ui, self).__init__() uic.loadUi('./desain/datamhs.ui', self) self.model = QSqlTableModel() self.show() self.openDB() self.model = QtSql.QSqlTableModel() self.displaytable("") self.tambah.clicked.connect(self.add) self.satpam.clicked.connect(self.stm) self.hapus.clicked.connect(self.padam) self.mencari.textChanged.connect(self.caridata) self.admin.clicked.connect(self.masukadmin) self.logout.clicked.connect(self.keluar) self.mahasiswa.clicked.connect(self.mhs) self.dosen.setStyleSheet('background-color : rgb(171, 208, 255);') def openDB(self): db = QtSql.QSqlDatabase.addDatabase('QSQLITE') db.setDatabaseName('parkir.db') if not db.open(): self.cek.setText("connect db error") return False else: self.cek.setText("connect db OK") return True def displaytable(self, p_filter): if p_filter is "": self.model.setTable('dosen') query = QtSql.QSqlQuery("select * from dosen") self.model.setQuery(query) self.model.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange) self.model.select() self.model.setHeaderData(0, QtCore.Qt.Horizontal, "nim") self.model.setHeaderData(1, QtCore.Qt.Horizontal, "nama") self.model.setHeaderData(2, QtCore.Qt.Horizontal, "no sepeda") self.model.setHeaderData(3, QtCore.Qt.Horizontal, "no mobil") self.tableView.setModel(self.model) else: query = QtSql.QSqlQuery("select * from dosen" " where nip like '%"+p_filter + "%' OR nama like '%"+p_filter + "%' ") self.model.setTable("") self.model.setQuery(query) self.model.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange) self.model.select() self.model.setHeaderData(0, QtCore.Qt.Horizontal, "nim") self.model.setHeaderData(1, QtCore.Qt.Horizontal, "nama") self.model.setHeaderData(2, QtCore.Qt.Horizontal, "no sepeda") self.model.setHeaderData(3, QtCore.Qt.Horizontal, "no mobil") self.tableView.setModel(self.model) def add(self): self.a = tambahmhs.Ui() self.a.show self.close() def stm(self): self.a = datastpm.Ui() self.a.show() self.close() def padam(self): self.model.removeRow(self.tableView.currentIndex().row()) self.displaytable("") def caridata(self): kata = self.sender().text() self.displaytable(kata) def masukadmin(self): self.b= admin.Ui() self.b.show() self.close() def keluar(self): self.b= login.Ui() self.b.show() self.close() def mhs(self): self.a = data.Ui() self.a.show() self.close()
class Demo(QWidget): def __init__(self, parent: typing.Optional[QWidget] = None) -> None: super().__init__(parent) db = QSqlDatabase.addDatabase('QSQLITE') db.setDatabaseName('student.db') db.open() # 创建view self.view = QTableView() # 将模型与数据库绑定 self.model = QSqlTableModel(None, db) # 设置模型对应数据库中的student表 self.model.setTable('student') # 获取数据 self.model.select() # 修改表格头 self.model.setHeaderData(0, Qt.Horizontal, '姓名') self.model.setHeaderData(1, Qt.Horizontal, '手机号') self.model.setHeaderData(2, Qt.Horizontal, '地址') self.view.setModel(self.model) vbox = QVBoxLayout() vbox.addWidget(self.view) self.btn_add = QPushButton("添加") self.btn_add.clicked.connect(self.slot_add) self.btn_del = QPushButton("删除") self.btn_del.clicked.connect(self.slot_del) vbox.addWidget(self.btn_add) vbox.addWidget(self.btn_del) self.setLayout(vbox) def slot_add(self): print(11) self.model.insertRows(self.model.rowCount(), 1) def slot_del(self): print(22) self.model.removeRow(self.view.currentIndex().row())
class QuoteExamine(QWidget, Ui_Quote_check): # 报价审核 """报价审核类""" def __init__(self, parent=None): super(QuoteExamine, self).__init__(parent) self.setupUi(self) self.quotelist() #连接槽 self.Quote_list.itemClicked.connect( self.querydetail) # 点击报价目录,显示选择的报价明细 self.Button_query.clicked.connect(self.querylist) # 点击查询查报价清单 def quotelist(self): # 默认显示报价清单 data = myMdb().fetchall(table='报价基本信息', where="状态!='已审核'") # col_lst = [tup[0] for tup in cur.description] # 数据列字段名 tup:数组 #description:种类 row = len(data) # 获得data的行数 vol = len(data[0]) # 获得data的列数.cur.description或len(data[0]) # 插入表格 # self.Quote_list = QTableWidget(row, vol) # 设置row行vol列的表格 self.Quote_list.setRowCount(row) font = QtGui.QFont('微软雅黑', 9) self.Quote_list.horizontalHeader().setFont(font) # 设置行表头字体 # self.Quote_list.setHorizontalHeaderLabels(col_lst) # 设置标题 self.Quote_list.verticalHeader().setVisible(False) # 左垂直表头不显示 # 加单元格下拉列表框 comBox = QComboBox() comBox.addItems(['审核通过', '退回重报']) # comBox.setStyleSheet('QComboBox{margin:3px}') self.Quote_list.setCellWidget(0, 6, comBox) # 设置表格颜色 self.Quote_list.horizontalHeader().setStyleSheet( 'QHeaderView::section{background:skyblue}') # self.Quote_list.setContextMenuPolicy(Qt.CustomContextMenu) # 允许右键产生菜单 # self.Quote_list.customContextMenuRequested.connect(self.generateMenu) # 将右键绑定到槽 self.Quote_list.setEditTriggers( QAbstractItemView.NoEditTriggers) # 设置表格禁止编辑 self.Quote_list.setSelectionBehavior( QAbstractItemView.SelectRows) # 设置整行选中 splitter = QtWidgets.QSplitter(QtCore.Qt.Vertical) # 设置分割条 self.Quote_list.setFrameStyle(QtWidgets.QFrame.Box | QtWidgets.QFrame.Plain) # 构建表格插入数据 for i in range(row): # i到row-1的数量 for j in range(vol): temp_data = data[i][j] # 临时记录,不能直接插入表格 data1 = QTableWidgetItem(str(temp_data)) # 转换后可插入表格 self.Quote_list.setItem(i, j, data1) # self.Quote_list.resizeColumnsToContents() # 自适应宽度 self.Quote_list.resizeRowsToContents() # 自适应行高,放最后可以等数据写入后自动适应表格数据宽度 self.Quote_list.horizontalHeader().setStretchLastSection( True) # 最后一列对齐边框 splitter.addWidget(self.Quote_list) self.verticalLayout.addWidget(splitter) self.QuoteDetail() def QuoteDetail(self): """审核报价明细区域""" db = connectDB() self.tablemodel = QSqlTableModel() self.Quote_detail.setModel(self.tablemodel) self.tablemodel.setEditStrategy(QSqlTableModel.OnFieldChange) self.tablemodel.setTable("quote") self.tablemodel.select() self.tablemodel.setHeaderData(0, Qt.Horizontal, "公司名称") self.tablemodel.setHeaderData(1, Qt.Horizontal, "报价单号") self.tablemodel.setHeaderData(2, Qt.Horizontal, "序号") self.tablemodel.setHeaderData(3, Qt.Horizontal, "作者") self.tablemodel.setHeaderData(4, Qt.Horizontal, "出版单位") self.tablemodel.setHeaderData(5, Qt.Horizontal, "图书分类") self.tablemodel.setHeaderData(6, Qt.Horizontal, "定价") # data_3 = myMdb().fetchall(table='报价基本信息') # # col_lst_3 = [tup[0] for tup in cur_3.description] # vol_3 = len(data_3[0]) # 获得data的列数.cur.description len(data[0]) # # self.Quote_detail = QTableWidget(0, vol_3) # 初始界面显示标题不用显示明细数据,所以QTableWidget(0,vol_3) # self.Quote_detail.setRowCount(500) # font = QtGui.QFont('微软雅黑', 9) # self.Quote_detail.horizontalHeader().setFont(font) # 设置行表头字体 # # self.Quote_detail.setHorizontalHeaderLabels(col_lst_3) # 设置标题 # self.Quote_detail.verticalHeader().setVisible(False) # 左垂直表头不显示 # self.Quote_detail.setObjectName("报价明细") # self.Quote_detail.horizontalHeader().setStyleSheet( # 'QHeaderView::section{background:skyblue}') # self.Quote_detail.setFrameStyle(QtWidgets.QFrame.Box | QtWidgets.QFrame.Plain) # self.Quote_detail.resizeColumnsToContents() # 自适应宽度 # self.Quote_list.resizeRowsToContents() # # self.Quote_detail.horizontalHeader().setStretchLastSection(True) # 最后一列对齐边框 # self.Quote_detail.setFrameStyle(QtWidgets.QFrame.Box | QtWidgets.QFrame.Plain) # splitter.addWidget(self.Quote_detail) # self.verticalLayout.addWidget(splitter) # # self.setLayout(self.verticalLayout) # 加这行后查询后可以更新,不用再addwidget,待搞明白? def querylist(self): # 查询报价清单 self.Quote_list.clearContents # clearContents清除内容,clear清空表格中所有内容(包含表头) lsearch = self.Line_search.text() # 搜索框 # sql = "SELECT * FROM 报价基本信息 WHERE 公司名称 LIKE '%"+lsearch+"%'" #'%"+bjdh+"%'" if lsearch == "": data_2 = myMdb().fetchall(table='报价基本信息', where="状态!='已审核'") else: data_2 = myMdb().fetchall(table='报价基本信息', where="公司名称=" + "'" + lsearch + "'" + "and 状态!='已审核'") # col_lst_2 = [tup[0] for tup in curr.description] # print(data_2) row_2 = len(data_2) #获得data的行数 vol_2 = len(data_2[0]) #获得data的列数.cur.description len(data[0]) self.Quote_list.setRowCount(row_2) #取查询到数据的行数,设表格行数 for i in range(row_2): #i到row-2的数量 for j in range(vol_2): temp_data = data_2[i][j] # 临时记录,不能直接插入表格 data2 = QTableWidgetItem(str(temp_data)) # 转换后可插入表格 self.Quote_list.setItem(i, j, data2) def querydetail(self): # 查询报价明细 h = self.Quote_list.currentIndex().row() # 找到所选行的行数h bjdh = self.Quote_list.item(h, 1).text() # 找到所选h行的第2列报价单号 # sql = "SELECT * FROM 报价明细 WHERE 报价单号 LIKE '%"+bjdh+"%'" #'%"+bjdh+"%'" self.Quote_detail.clearContents() # 清除报价明细表内数据 data_3 = myMdb().fetchall(table='quote', where="报价单号=" + bjdh) # col_lst_3 = [tup[0] for tup in cur_3.description] # print(data_3) row_3 = len(data_3) #获得data的行数 vol_3 = len(data_3[0]) #获得data的列数.cur.description len(data[0]) self.Quote_detail.setRowCount(row_3) # self.Quote_detail.setColumnCount(0) #构建表格插入数据 for i in range(row_3): #i到row-1的数量 for j in range(vol_3): temp_data = data_3[i][j] # 临时记录,不能直接插入表格 data3 = QTableWidgetItem(str(temp_data)) # 转换后可插入表格 self.Quote_detail.setItem(i, j, data3) # 适应列宽/行高/最后一列对齐边框 self.Quote_detail.resizeColumnsToContents() self.Quote_detail.resizeRowsToContents() self.Quote_detail.horizontalHeader().setStretchLastSection(True) @pyqtSlot() # 报价审核通过 def on_Button_pass_clicked(self): h = self.Quote_list.currentIndex().row() # 找到所选行的行数h bjdh = self.Quote_list.item(h, 1).text() # 找到所选h行的1位报价单号 # cur_4.execute("UPDATE 报价基本信息 SET 状态='通过' WHERE 报价单号 = '"+bjdh+"'") myMdb().update(table='报价基本信息', 状态='已审核', where="报价单号=" + bjdh) QMessageBox.information(QWidget(), "标题", "审核成功") self.Quote_list.clearContents() self.Quote_detail.clearContents() self.querylist()
class IBox(QWidget): def __init__(self): super().__init__() #====##====##====##====##====##====##====# # QSqlModel connecition #====##====##====##====##====##====##====# # self.db = QSqlDatabase.database("ibox") self.db = QSqlDatabase.addDatabase("QSQLITE") self.db.setDatabaseName("complete.db") self.db.open() self.inv_model = QSqlTableModel(self, self.db) self.inv_model.setTable("models") self.inv_model.setEditStrategy(QSqlTableModel.OnManualSubmit) self.inv_model.select() self.inv_view = QTableView() self.inv_view.setModel(self.inv_model) self.inv_view.hideColumn(0) self.inv_view.hideColumn(2) self.order_header = self.inv_view.horizontalHeader() self.order_header.setMinimumSectionSize(130) self.order_header.setSectionResizeMode(QHeaderView.Stretch) self.inv_view.setSelectionBehavior(QAbstractItemView.SelectRows) self.bargraph = PlotCanvas(self, width=4, height=3) #self.bargraph.move(0,0) #====##====##====##====##====# #Layout forming & finalization #====##====##====##====##====# iboxlayout = QHBoxLayout() iboxlayout.addWidget(self.inv_view) iboxlayout.addWidget(self.bargraph) self.setLayout(iboxlayout) # self.setStyleSheet('background-color: #444444') self.setWindowTitle('JPro') self.setGeometry(0, 0, 640, 440) self.show() def setData(self, data): row = 0 for record in data: self.table.setItem(row, 0, QTableWidgetItem(str(record.name))) self.table.setItem(row, 1, QTableWidgetItem(str(record.current_quantity))) # self.table.setItem(row, 2, QTableWidgetItem(record.parts)) row += 1 def buildTable(self): self.table = QTableWidget(len(self.all_stock), 2, self) self.table.setHorizontalHeaderItem(0, QTableWidgetItem('Models / 模型 ')) self.table.setHorizontalHeaderItem(1, QTableWidgetItem('Quantity / 数量 ')) # self.table.setHorizontalHeaderItem(2, QTableWidgetItem('Parts / 零件')) self.order_header = self.table.horizontalHeader() self.order_header.setMinimumSectionSize(130) self.order_header.setSectionResizeMode(QHeaderView.Stretch) self.table.setSelectionBehavior(QAbstractItemView.SelectRows) self.table.setCurrentCell(-1, -1)
def __init__(self, db, dbType, dbSchema, modelPeche, parent=None): ''' Constructeur, récupération de variable, connection des événements et remplissage des combobox :param db: définie dans le setupModel(), représente la connexion avec la base de données :type db: QSqlDatabase :param dbType: type de la base de données (postgre) :type dbType: str :param dbSchema: nom du schéma sous PostgreSQL contenant les données (data) :type dbSchema: unicode :param modelPeche: modèle pêche qui contient les données de la base de données :type modelPeche: QSqlRelationalTableModel :param parent: défini que cette fenêtre n'hérite pas d'autres widgets :type parent: NoneType ''' super(Filtrage_peche_dialog, self).__init__(parent) self.db = db self.dbType = dbType self.dbSchema = dbSchema self.modelPeche = modelPeche self.setupUi(self) self.btnAnnuler.clicked.connect(self.reject) self.btnExec.clicked.connect(self.execution) self.btnRaz.clicked.connect(self.raz) self.btnEt.clicked.connect(self.et) self.btnOu.clicked.connect(self.ou) self.btnPrevisualiser.clicked.connect(self.previSql) self.btnCode.clicked.connect(self.ajoutCode) self.btnId.clicked.connect(self.ajoutId) self.btnPdpg.clicked.connect(self.ajoutPdpg) self.btnDate.clicked.connect(self.ajoutDate) self.btnRiviere.clicked.connect(self.ajoutRiviere) self.btnAappma.clicked.connect(self.ajoutAappma) self.btnMeau.clicked.connect(self.ajoutMeau) self.btnMotif.clicked.connect(self.ajoutMotif) self.btnEt.setEnabled(False) self.btnOu.setEnabled(False) self.aappmaBool = False self.motifBool = False self.pdpgBool = False self.ceauBool = False self.meauBool = False self.anneeBool = False self.wwhere = "" self.modelPdpg = QSqlTableModel(self, self.db) wrelation = "contexte_pdpg" if self.dbType == "postgres": wrelation = self.dbSchema + "." + wrelation self.modelPdpg.setTable(wrelation) self.modelPdpg.setSort(2, Qt.AscendingOrder) if (not self.modelPdpg.select()): QMessageBox.critical(self, u"Remplissage du modèle PDPG", self.modelPdpg.lastError().text(), QMessageBox.Ok) self.cmbPdpg.setModel(self.modelPdpg) self.cmbPdpg.setModelColumn(self.modelPdpg.fieldIndex("pdpg_nom")) self.modelAappma = QSqlTableModel(self, self.db) wrelation = "aappma" if self.dbType == "postgres": wrelation = self.dbSchema + "." + wrelation self.modelAappma.setTable(wrelation) self.modelAappma.setSort(1, Qt.AscendingOrder) if (not self.modelAappma.select()): QMessageBox.critical(self, u"Remplissage du modèle AAPPMA", self.modelAappma.lastError().text(), QMessageBox.Ok) self.cmbAappma.setModel(self.modelAappma) self.cmbAappma.setModelColumn(self.modelAappma.fieldIndex("apma_nom")) self.modelRiviere = QSqlTableModel(self, self.db) wrelation = "cours_eau" if self.dbType == "postgres": wrelation = self.dbSchema + "." + wrelation self.modelRiviere.setTable(wrelation) self.modelRiviere.setFilter("ceau_nom <> 'NR'") self.modelRiviere.setSort(2, Qt.AscendingOrder) if (not self.modelRiviere.select()): QMessageBox.critical(self, u"Remplissage du modèle Rivière", self.modelRiviere.lastError().text(), QMessageBox.Ok) self.cmbRiviere.setModel(self.modelRiviere) self.cmbRiviere.setModelColumn( self.modelRiviere.fieldIndex("ceau_nom")) self.modelMeau = QSqlQueryModel(self) wrelation = "masse_eau" if self.dbType == "postgres": wrelation = self.dbSchema + "." + wrelation self.modelMeau.setQuery( "select meau_code, meau_code || ' ; ' || meau_nom from " + wrelation + " order by meau_code;", self.db) if self.modelMeau.lastError().isValid(): QMessageBox.critical(self, u"Remplissage du modèle Masse d'eau", self.modelMeau.lastError().text(), QMessageBox.Ok) self.cmbMeau.setModel(self.modelMeau) self.cmbMeau.setModelColumn(1) self.ModelMotif = QSqlTableModel(self, self.db) wrelation = "motif_peche" if self.dbType == "postgres": wrelation = self.dbSchema + "." + wrelation self.ModelMotif.setTable(wrelation) self.ModelMotif.setSort(1, Qt.AscendingOrder) if (not self.ModelMotif.select()): QMessageBox.critical(self, u"Remplissage du modèle Motif", self.ModelMotif.lastError().text(), QMessageBox.Ok) self.cmbMotif.setModel(self.ModelMotif) self.cmbMotif.setModelColumn(self.ModelMotif.fieldIndex("mope_motif"))
class MainWindowView(QMainWindow, Ui_MainWindow): def __init__(self,dbPath,tblName,parent=None): super(MainWindowView, self).__init__(parent) self.setupUi(self) self.addBtn.clicked.connect(self.addBtnFunc) self.updBtn.clicked.connect(self.updBtnFunc) self.delBtn.clicked.connect(self.delBtnFunc) self.dbPath="test.db" self.curTable="test2" ###tableView与model绑定 self.tableModel=QSqlTableModel(self,QSqlDatabase.addDatabase('QSQLITE')) self.tableModel.setEditStrategy(QSqlTableModel.OnManualSubmit) self.tableView.setModel(self.tableModel) ###self.model数据初始化 self.tableModel.database().setDatabaseName(self.dbPath) self.tableModel.database().open() self.tableModel.setTable(self.curTable) self.tableModel.select() #新增按钮关联的槽函数 def addBtnFunc(self,event): f1=random.randint(1, 99) self.tableModel.insertRows(0, 1) self.tableModel.setData(self.tableModel.index(0, 0), f1) self.tableModel.setData(self.tableModel.index(0, 1), "test") self.tableModel.submitAll() #修改按钮关联的槽函数 def updBtnFunc(self,event): QMessageBox.information( self, '提醒', "updBtnFunc Call!") #删除按钮关联的槽函数 def delBtnFunc(self,event): rs=list(map(lambda x:x.row(),self.tableView.selectedIndexes())) if len(rs)==0: QMessageBox.information(self,'提醒','请先选中至少一行,再点击此按钮!') return for i in reversed(rs): self.tableModel.removeRows(i,1) self.tableModel.submitAll()
def exportToMobile(self, params): SKIPPED_FIELDS = ('edgeimg', 'photo1', 'photo2', 'photo3', 'photo4', 'obversedesigner', 'reversedesigner', 'catalognum2', 'catalognum3', 'catalognum4', 'saledate', 'saleprice', 'totalsaleprice', 'buyer', 'saleplace', 'saleinfo', 'paydate', 'payprice', 'totalpayprice', 'seller', 'payplace', 'payinfo', 'url', 'obversedesigner', 'reversedesigner') if os.path.isfile(params['file']): os.remove(params['file']) db = QSqlDatabase.addDatabase('QSQLITE', 'mobile') db.setDatabaseName(params['file']) if not db.open(): print(db.lastError().text()) QMessageBox.critical(self.parent(), self.tr("Create mobile collection"), self.tr("Can't open collection")) return mobile_settings = {'Version': 5, 'Type': 'Mobile', 'Filter': params['filter']} sql = """CREATE TABLE settings ( title CHAR NOT NULL UNIQUE, value CHAR)""" QSqlQuery(sql, db) for key, value in mobile_settings.items(): query = QSqlQuery(db) query.prepare("""INSERT INTO settings (title, value) VALUES (?, ?)""") query.addBindValue(key) query.addBindValue(str(value)) query.exec_() sql = """CREATE TABLE updates ( title CHAR NOT NULL UNIQUE, value CHAR)""" QSqlQuery(sql, db) sql = """CREATE TABLE photos ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, image BLOB)""" QSqlQuery(sql, db) sqlFields = [] fields = CollectionFieldsBase() for field in fields: if field.name == 'id': sqlFields.append('id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT') elif field.name == 'image': sqlFields.append('image INTEGER') elif field.name in SKIPPED_FIELDS: continue else: sqlFields.append("%s %s" % (field.name, Type.toSql(field.type))) sql = "CREATE TABLE coins (" + ", ".join(sqlFields) + ")" QSqlQuery(sql, db) model = self.model() while model.canFetchMore(): model.fetchMore() dest_model = QSqlTableModel(self.parent(), db) dest_model.setEditStrategy(QSqlTableModel.OnManualSubmit) dest_model.setTable('coins') dest_model.select() height = 64 if params['density'] == 'HDPI': height *= 1.5 elif params['density'] == 'XHDPI': height *= 2 elif params['density'] == 'XXHDPI': height *= 3 elif params['density'] == 'XXXHDPI': height *= 4 is_obverse_enabled = params['image'] in (ExportDialog.IMAGE_OBVERSE, ExportDialog.IMAGE_BOTH) is_reverse_enabled = params['image'] in (ExportDialog.IMAGE_REVERSE, ExportDialog.IMAGE_BOTH) fields = CollectionFieldsBase() count = model.rowCount() progressDlg = Gui.ProgressDialog(self.tr("Exporting records"), self.tr("Cancel"), count, self.parent()) for i in range(count): progressDlg.step() if progressDlg.wasCanceled(): break coin = model.record(i) if coin.value('status') in ('pass', 'sold'): continue dest_record = dest_model.record() for field in fields: if field.name in ('id', 'image', 'obverseimg', 'reverseimg'): continue if field.name in SKIPPED_FIELDS: continue val = coin.value(field.name) if val is None or val == '': continue dest_record.setValue(field.name, val) # Process images is_obverse_present = not coin.isNull('obverseimg') is_reverse_present = not coin.isNull('reverseimg') if is_obverse_present or is_reverse_present: obverseImage = QImage() reverseImage = QImage() if is_obverse_present and is_obverse_enabled: if coin.value('obverseimg')[:7] == 'file://': obverseImage.load(coin.value('obverseimg')[7:]) else: obverseImage.loadFromData(coin.value('obverseimg')) query = QSqlQuery(db) query.prepare("""INSERT INTO photos (image) VALUES (?)""") query.addBindValue(coin.value('obverseimg')) query.exec_() img_id = query.lastInsertId() dest_record.setValue('obverseimg', img_id) if not obverseImage.isNull(): obverseImage = obverseImage.scaledToHeight(height, Qt.SmoothTransformation) if is_reverse_present and is_reverse_enabled: if coin.value('reverseimg')[:7] == 'file://': reverseImage.load(coin.value('reverseimg')[7:]) else: reverseImage.loadFromData(coin.value('reverseimg')) query = QSqlQuery(db) query.prepare("""INSERT INTO photos (image) VALUES (?)""") query.addBindValue(coin.value('reverseimg')) query.exec_() img_id = query.lastInsertId() dest_record.setValue('reverseimg', img_id) if not reverseImage.isNull(): reverseImage = reverseImage.scaledToHeight(height, Qt.SmoothTransformation) if not is_obverse_enabled: obverseImage = QImage() if not is_reverse_enabled: reverseImage = QImage() image = QImage(obverseImage.width() + reverseImage.width(), height, QImage.Format_RGB32) image.fill(QColor(Qt.white).rgb()) paint = QPainter(image) if is_obverse_present and is_obverse_enabled: paint.drawImage(QtCore.QRectF(0, 0, obverseImage.width(), height), obverseImage, QtCore.QRectF(0, 0, obverseImage.width(), height)) if is_reverse_present and is_reverse_enabled: paint.drawImage(QtCore.QRectF(obverseImage.width(), 0, reverseImage.width(), height), reverseImage, QtCore.QRectF(0, 0, reverseImage.width(), height)) paint.end() ba = QtCore.QByteArray() buffer = QtCore.QBuffer(ba) buffer.open(QtCore.QIODevice.WriteOnly) # Store as PNG for better view image.save(buffer, 'png') dest_record.setValue('image', ba) dest_model.insertRecord(-1, dest_record) progressDlg.setLabelText(self.tr("Saving...")) dest_model.submitAll() progressDlg.setLabelText(self.tr("Compact...")) QSqlQuery("""UPDATE coins SET reverseimg = (select t2.id from coins t3 join (select id, image from photos group by image having count(*) > 1) t2 on t1.image = t2.image join photos t1 on t3.reverseimg = t1.id where t1.id <> t2.id and t3.id = coins.id) WHERE coins.id in (select t3.id from coins t3 join (select id, image from photos group by image having count(*) > 1) t2 on t1.image = t2.image join photos t1 on t3.reverseimg = t1.id where t1.id <> t2.id) """, db) QSqlQuery("""UPDATE coins SET obverseimg = (select t2.id from coins t3 join (select id, image from photos group by image having count(*) > 1) t2 on t1.image = t2.image join photos t1 on t3.obverseimg = t1.id where t1.id <> t2.id and t3.id = coins.id) WHERE coins.id in (select t3.id from coins t3 join (select id, image from photos group by image having count(*) > 1) t2 on t1.image = t2.image join photos t1 on t3.obverseimg = t1.id where t1.id <> t2.id) """, db) QSqlQuery("""DELETE FROM photos WHERE id NOT IN (SELECT id FROM photos GROUP BY image)""", db) progressDlg.setLabelText(self.tr("Vacuum...")) QSqlQuery("VACUUM", db) db.close() progressDlg.reset()
class Ui(QtWidgets.QMainWindow): def __init__(self): super(Ui, self).__init__() uic.loadUi('./desain/datastpm.ui', self) self.model = QSqlTableModel() self.show() self.openDB() self.model = QtSql.QSqlTableModel() self.displaytable("") self.hapus.clicked.connect(self.padam) self.satpam.setStyleSheet('background-color : rgb(171, 208, 255);') self.mahasiswa.clicked.connect(self.mhs) self.admin.clicked.connect(self.bukaadmin) self.logout.clicked.connect(self.keluar) self.tambah.clicked.connect(self.tmb) self.dosen.clicked.connect(self.dtdosen) def openDB(self): db = QtSql.QSqlDatabase.addDatabase('QSQLITE') db.setDatabaseName('parkir.db') if not db.open(): self.cek.setText("connect db error") return False else: self.cek.setText("connect db OK") def displaytable(self, p_filter): if p_filter is "": self.model.setTable('satpam') query = QtSql.QSqlQuery("select * from satpam") self.model.setQuery(query) self.model.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange) self.model.select() self.model.setHeaderData(0, QtCore.Qt.Horizontal, "username") self.model.setHeaderData(1, QtCore.Qt.Horizontal, "password") self.tableView.setModel(self.model) def padam(self): self.model.removeRow(self.tableView.currentIndex().row()) self.displaytable("") def mhs(self): self.a = data.Ui() self.a.show() self.close() def bukaadmin(self): self.b = admin.Ui() self.b.show() self.close() def tmb(self): self.c = tambahsatpam.Ui() self.c.show() self.close() def keluar(self): self.b = login.Ui() self.b.show() self.close() def dtdosen(self): self.c = datadosen.Ui() self.c.show() self.close()
class ProjectInfoTable(InvertedTable): """a table displaying general info about a Project """ def __init__(self, log, mydb): super().__init__(log, mydb) self.create_model() self.add_headers() self.invert_model() self.header_lbl.setText("General Information:") def create_model(self): self.model = QSqlTableModel() self.model.setTable("projects") self.model.select() self.table.setEditTriggers(QAbstractItemView.NoEditTriggers) def add_headers(self): self.model.setHeaderData(1, Qt.Horizontal, "Project Status", Qt.DisplayRole) self.model.setHeaderData(2, Qt.Horizontal, "Created on", Qt.DisplayRole) self.model.setHeaderData(3, Qt.Horizontal, "Created by", Qt.DisplayRole) self.model.setHeaderData(4, Qt.Horizontal, "Gene", Qt.DisplayRole) self.model.setHeaderData(5, Qt.Horizontal, "Pool", Qt.DisplayRole) self.model.setHeaderData(6, Qt.Horizontal, "Title", Qt.DisplayRole) self.model.setHeaderData(7, Qt.Horizontal, "Description", Qt.DisplayRole) self.model.setHeaderData(8, Qt.Horizontal, "ENA Project ID", Qt.DisplayRole) self.model.setHeaderData(9, Qt.Horizontal, "ENA Project Submission ID", Qt.DisplayRole) def filter(self, project): self.model.layoutAboutToBeChanged.emit() self.model.setFilter("projects.project_name = '{}'".format(project)) self.model.layoutChanged.emit() self.table.hideRow(0)
def __init_ui(self) -> None: qApp.setStyle('Fusion') self.setWindowIcon(QIcon(resource_path("logo.ico"))) self.setWindowTitle('Lista de Contatos') self.model = QSqlTableModel() self.setMinimumSize(800, 400) root_layout: QVBoxLayout = QVBoxLayout() # search hbox_search: QHBoxLayout = QHBoxLayout() search_lbl: QLabel = QLabel('Buscar') self.__dict_keyword = {'nome': 'name', 'anydesk': 'anydesk'} keyword_cmb: QComboBox = QComboBox() keyword_cmb.addItems(self.__dict_keyword.keys()) keyword_cmb.currentTextChanged.connect(self.__set_selected_keyword) search_txt: QLineEdit = QLineEdit() search_txt.setValidator(UpperCaseValidator(self)) search_txt.textChanged.connect(self.__update_searching) search_txt.returnPressed.connect(self.__search) search_btn: QPushButton = QPushButton('Buscar') search_btn.clicked.connect(self.__search) hbox_search.addWidget(search_lbl) hbox_search.addWidget(keyword_cmb) hbox_search.addWidget(search_txt) hbox_search.addWidget(search_btn) root_layout.addLayout(hbox_search) # ./search hbox_container: QHBoxLayout = QHBoxLayout() self.tbl_contacts = QTableView() button_delegate = ButtonDelegate() button_delegate.clicked[int, int].connect(self.__on_click_button_delegate) self.tbl_contacts.setEditTriggers(QTableView.NoEditTriggers) # Type Selection self.tbl_contacts.setAlternatingRowColors(True) self.tbl_contacts.setSelectionMode(QTableView.SingleSelection) self.tbl_contacts.setSelectionBehavior(QTableView.SelectRows) self.tbl_contacts.setModel(self.model) self.tbl_contacts.setItemDelegateForColumn(1, button_delegate) # Enable sorting self.tbl_contacts.setSortingEnabled(True) # Adjust Header horizontal_header: QHeaderView = self.tbl_contacts.horizontalHeader() horizontal_header.setSectionResizeMode(QHeaderView.ResizeToContents) horizontal_header.setStretchLastSection(True) size = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) size.setHorizontalStretch(1) self.tbl_contacts.setSizePolicy(size) # events self.tbl_contacts.clicked.connect(self.__set_selected_row) hbox_container.addWidget(self.tbl_contacts) vbox: QVBoxLayout = QVBoxLayout() self.new_btn: QPushButton = QPushButton('Novo') self.new_btn.clicked.connect(self.__new) self.edit_btn: QPushButton = QPushButton('Editar') self.edit_btn.clicked.connect(self.__edit) self.destroy_btn: QPushButton = QPushButton('Excluir') self.destroy_btn.clicked.connect(self.__destroy) vbox.addWidget(self.new_btn) vbox.addWidget(self.edit_btn) vbox.addWidget(self.destroy_btn) vbox.addStretch(1) hbox_container.addLayout(vbox) root_layout.addLayout(hbox_container) self.setLayout(root_layout) self.show()
def create_model(self): self.model = QSqlTableModel() self.model.setTable("projects") self.model.select() self.table.setEditTriggers(QAbstractItemView.NoEditTriggers)
model.setHeaderData(2, Qt.Horizontal, "Last name") def createView(title, model): view = QTableView() view.setModel(model) view.setWindowTitle(title) return view if __name__ == '__main__': import sys app = QApplication(sys.argv) if not connection.createConnection(): sys.exit(1) model = QSqlTableModel() initializeModel(model) view1 = createView("Table Model (View 1)", model) view2 = createView("Table Model (View 2)", model) view1.show() view2.move(view1.x() + view1.width() + 20, view1.y()) view2.show() sys.exit(app.exec_())
class Ui(Ui_Form): def function(self): self.OutExcelButton.clicked.connect(self.OutExcel) # 导出表格按钮 self.InSQLButton.clicked.connect(self.InSQL) # Excel导入信息按钮 self.OutPutSQLButton.clicked.connect(self.OutSQL) # 基本信息导出按钮 self.CementDateButton.clicked.connect(self.CementDate) # 水泥一览表信息按钮 self.MixpushButton.clicked.connect(self.MixDate) # 配合比表信息按钮 self.ChangePrarmerButton.clicked.connect( self.ChangePrarmer) # 确认修改参数按钮 self.CementrefreshButton.clicked.connect(self.cement_refresh) # 刷新 self.CementsubmitButton.clicked.connect(self.cement_submit) # 提交 self.CementdelButton.clicked.connect(self.cement_del) # 删除 self.CementQueryButton.clicked.connect(self.query_cement) # 查询 self.mixrefreshButton.clicked.connect(self.mix_refresh) # 刷新 self.mixsubmitButton.clicked.connect(self.mix_submit) # 提交 self.MixDelButton.clicked.connect(self.mix_del) # 删除 self.MixqueryButton.clicked.connect(self.query_mix) # 查询 self.deletArtButton.clicked.connect(self.empty_Art) # 水泥一览表数据清空 self.deleMIXButton.clicked.connect(self.empty_Mix) # 配合比表数据清空 self.CementAddButton.clicked.connect(self.addArt) # 添加水泥按钮 self.mixAddButton.clicked.connect(self.addMix) # 添加配合比按钮 self.CementInfoButton.clicked.connect(self.CementInfo) # 选择水泥一览表记录 self.MixPoportionButton.clicked.connect(self.ConMixInsert) # 选择配合比表记录 self.ChoicConcreteUsageRecordButton.clicked.connect( self.ChoicConcreteUsageRecord) # 选择使用记录表 self.OutSQLButton_2.clicked.connect(self.ChoicSQLPath) # 选择OutPutSQL路径 self.OutSQLButton_3.clicked.connect(self.OutPutSQL) # 导出SQL self.OutPutButton.clicked.connect(self.ouputexcel) # 确认导出按钮 self.OutPutVoidButton.clicked.connect(self.outputvoidexcel) # 确认导出按钮 # 查看数据库是否存在 try: parm = get_parm() print('已获取SQL') except BaseException: print('创建SQL') from DateBase.creat import creat_table from DateBase.insert_value import parm_init creat_table() parm_init() # 填充信息 parm = get_parm() self.MinC_StrengthEdit.setText(str(parm.MinC_Strength)) self.MaxC_StrengthEdit.setText(str(parm.MaxC_Strength)) self.MinS_FinenessDensityEdit.setText(str(parm.MinS_FinenessDensity)) self.MaxS_FinenessDensityEdit.setText(str(parm.MaxS_FinenessDensity)) self.MinS_SurfaceDensityEdit.setText(str(parm.MinS_SurfaceDensity)) self.MaxS_SurfaceDensityEdit.setText(str(parm.MaxS_SurfaceDensity)) self.MinS_DensityEdit.setText(str(parm.MinS_Density)) self.MaxS_DensityEdit.setText(str(parm.MaxS_Density)) self.MinS_SlitContentEdit.setText(str(parm.MinS_SlitContent)) self.MaxS_SlitContentEdit.setText(str(parm.MaxS_SlitContent)) self.MinS_WaterContentEdit.setText(str(parm.MinS_WaterContent)) self.MaxS_WaterContentEdit.setText(str(parm.MaxS_WaterContent)) self.MinG_GrainContentEdit.setText(str(parm.MinG_GrainContent)) self.MaxG_GrainContentEdit.setText(str(parm.MaxG_GrainContent)) self.MinG_CrushLevelEdit.setText(str(parm.MinG_CrushLevel)) self.MaxG_CrushLevelEdit.setText(str(parm.MaxG_CrushLevel)) self.MinG_DensityEdit.setText(str(parm.MinG_Density)) self.MaxG_DensityEdit.setText(str(parm.MaxG_Density)) self.MinG_SlitContentEdit.setText(str(parm.MinG_SlitContent)) self.MaxG_SlitContentEdit.setText(str(parm.MaxG_SlitContent)) self.MinG_WaterContentEdit.setText(str(parm.MinG_WaterContent)) self.MaxG_WaterContentEdit.setText(str(parm.MaxG_WaterContent)) self.MinA_DensityEdit.setText(str(parm.MinA_Density)) self.MaxA_DensityEdit.setText(str(parm.MaxA_Density)) self.MinR7_CompressionEdit.setText(str(parm.MinR7_Compression)) self.MaxR7_CompressionEdit.setText(str(parm.MaxR7_Compression)) self.MinR28_CompressionEdit.setText(str(parm.MinR28_Compression)) self.MaxR28_CompressionEdit.setText(str(parm.MaxR28_Compression)) _translate = QtCore.QCoreApplication.translate PicName = getpiname() for i in range(len(PicName)): self.Project1Manager.addItem("") self.Project1Manager.setItemText(i, _translate("Form", PicName[i])) self.Project1FillSheeter.addItem("") self.Project1FillSheeter.setItemText( i, _translate("Form", PicName[i])) self.Project2Manager.addItem("") self.Project2Manager.setItemText(i, _translate("Form", PicName[i])) self.Project2Checker.addItem("") self.Project2Checker.setItemText(i, _translate("Form", PicName[i])) self.Project2Try.addItem("") self.Project2Try.setItemText(i, _translate("Form", PicName[i])) self.Project3MakeSheet.addItem("") self.Project3MakeSheet.setItemText(i, _translate("Form", PicName[i])) self.Project4Manager.addItem("") self.Project4Manager.setItemText(i, _translate("Form", PicName[i])) self.Project4Checker.addItem("") self.Project4Checker.setItemText(i, _translate("Form", PicName[i])) self.Project4Calculate.addItem("") self.Project4Calculate.setItemText(i, _translate("Form", PicName[i])) self.Project5Manager.addItem("") self.Project5Manager.setItemText(i, _translate("Form", PicName[i])) self.Project5Filler.addItem("") self.Project5Filler.setItemText(i, _translate("Form", PicName[i])) self.Project7Manager.addItem("") self.Project7Manager.setItemText(i, _translate("Form", PicName[i])) self.Project7Checker.addItem("") self.Project7Checker.setItemText(i, _translate("Form", PicName[i])) self.Project7try.addItem("") self.Project7try.setItemText(i, _translate("Form", PicName[i])) self.Project9Manager.addItem("") self.Project9Manager.setItemText(i, _translate("Form", PicName[i])) self.Project9Checker.addItem("") self.Project9Checker.setItemText(i, _translate("Form", PicName[i])) self.Project9Record.addItem("") self.Project9Record.setItemText(i, _translate("Form", PicName[i])) self.Project10Manager.addItem("") self.Project10Manager.setItemText(i, _translate("Form", PicName[i])) self.Project10Examine.addItem("") self.Project10Examine.setItemText(i, _translate("Form", PicName[i])) self.Project10Checker.addItem("") self.Project10Checker.setItemText(i, _translate("Form", PicName[i])) self.Project11Manager.addItem("") self.Project11Manager.setItemText(i, _translate("Form", PicName[i])) self.Project11Checker.addItem("") self.Project11Checker.setItemText(i, _translate("Form", PicName[i])) self.Project1Manager.setCurrentText(str(parm.Project1Manager)) self.Project1FillSheeter.setCurrentText(str(parm.Project1FillSheeter)) self.Project2InspectCodeEdit.setText(str(parm.Project2InspectCodeEdit)) self.Project2Manager.setCurrentText(str(parm.Project2Manager)) self.Project2Checker.setCurrentText(str(parm.Project2Checker)) self.Project2Try.setCurrentText(str(parm.Project2Try)) self.Project3MakeSheet.setCurrentText(str(parm.Project3MakeSheet)) self.Project3InspectCodeEdit.setText(str(parm.Project3InspectCodeEdit)) self.Project4Manager.setCurrentText(str(parm.Project4Manager)) self.Project4Checker.setCurrentText(str(parm.Project4Checker)) self.Project4Calculate.setCurrentText(str(parm.Project4Calculate)) self.Project4InspectCodeEdit.setText(str(parm.Project4InspectCodeEdit)) self.Project5Manager.setCurrentText(str(parm.Project5Manager)) self.Project5Filler.setCurrentText(str(parm.Project5Filler)) self.Project7ConDesignSpeciEdit.setText( str(parm.Project7ConDesignSpeciEdit)) self.Project7CodeEdit.setText(str(parm.Project7CodeEdit)) self.Project7Manager.setCurrentText(str(parm.Project7Manager)) self.Project7Checker.setCurrentText(str(parm.Project7Checker)) self.Project7try.setCurrentText(str(parm.Project7try)) self.Project9Manager.setCurrentText(str(parm.Project9Manager)) self.Project9Checker.setCurrentText(str(parm.Project9Checker)) self.Project9Record.setCurrentText(str(parm.Project9Record)) self.Project10ConTestReportTestBasisEdit.setText( str(parm.Project10ConTestReportTestBasisEdit)) self.Project10InspectCodeEdit.setText( str(parm.Project10InspectCodeEdit)) from PyQt5.QtCore import QTime time = str(parm.Project10TimeEdit).split(':') time = QTime(int(time[0]), int(time[1])) self.Project10TimeEdit.setTime(time) self.Project10MaxCreepEdit.setText(str(parm.Project10MaxCreepEdit)) self.Project10MinCreepEdit.setText(str(parm.Project10MinCreepEdit)) self.Project10Manager.setCurrentText(str(parm.Project10Manager)) self.Project10Examine.setCurrentText(str(parm.Project10Examine)) self.Project10Checker.setCurrentText(str(parm.Project10Checker)) self.Project11Manager.setCurrentText(str(parm.Project11Manager)) self.Project11Checker.setCurrentText(str(parm.Project11Checker)) # 插入水泥一览表 self.con2 = QSqlDatabase.addDatabase('QSQLITE') self.con2.setDatabaseName(db_path) # con2.exec_("PRAGMA foreign_keys = ON;") self.CementMode = QSqlTableModel() self.CementMode.setTable("cement_attribute_data") self.CementMode.setSort(0, Qt.AscendingOrder) self.CementMode.setEditStrategy(self.CementMode.OnManualSubmit) self.CementMode.setHeaderData(0, Qt.Horizontal, "id") self.CementMode.setHeaderData(1, Qt.Horizontal, "进场日期") self.CementMode.setHeaderData(2, Qt.Horizontal, "水泥品种") self.CementMode.setHeaderData(3, Qt.Horizontal, "生产厂家") self.CementMode.setHeaderData(4, Qt.Horizontal, "生产日期") self.CementMode.setHeaderData(5, Qt.Horizontal, "编号") self.CementMode.setHeaderData(6, Qt.Horizontal, "数量(T)") self.CementMode.setHeaderData(7, Qt.Horizontal, "安定性") self.CementMode.setHeaderData(8, Qt.Horizontal, "初凝") self.CementMode.setHeaderData(9, Qt.Horizontal, "终凝") self.CementMode.setHeaderData(10, Qt.Horizontal, "R3抗压") self.CementMode.setHeaderData(11, Qt.Horizontal, "R28抗压") self.CementMode.setHeaderData(12, Qt.Horizontal, "R3抗折") self.CementMode.setHeaderData(13, Qt.Horizontal, "R28抗折") self.CementMode.setHeaderData(14, Qt.Horizontal, "是否优先") self.CementMode.select() self.CementtableView.setModel(self.CementMode) self.CementtableView.setSelectionMode(QTableView.SingleSelection) self.CementtableView.setSelectionBehavior(QTableView.SelectRows) self.CementtableView.resizeColumnsToContents() # 配合比表 self.MixMode = QSqlTableModel() self.MixMode.setTable("concrete_mix") self.MixMode.setSort(0, Qt.AscendingOrder) self.MixMode.setEditStrategy(QSqlTableModel.OnManualSubmit) self.MixMode.setHeaderData(1 - 1, Qt.Horizontal, "名称") self.MixMode.setHeaderData(2 - 1, Qt.Horizontal, "配合比编号") self.MixMode.setHeaderData(3 - 1, Qt.Horizontal, "强度等级 ") self.MixMode.setHeaderData(4 - 1, Qt.Horizontal, "抗渗等级") self.MixMode.setHeaderData(5 - 1, Qt.Horizontal, "膨胀") self.MixMode.setHeaderData(6 - 1, Qt.Horizontal, "配合比编号2") self.MixMode.setHeaderData(7 - 1, Qt.Horizontal, "坍落度") self.MixMode.setHeaderData(8 - 1, Qt.Horizontal, "标准差(MPa)") self.MixMode.setHeaderData(9 - 1, Qt.Horizontal, "配制强度(MPa)") self.MixMode.setHeaderData(10 - 1, Qt.Horizontal, "水W") self.MixMode.setHeaderData(11 - 1, Qt.Horizontal, "水泥C") self.MixMode.setHeaderData(12 - 1, Qt.Horizontal, "粉煤灰F") self.MixMode.setHeaderData(13 - 1, Qt.Horizontal, "砂S") self.MixMode.setHeaderData(14 - 1, Qt.Horizontal, "石G") self.MixMode.setHeaderData(15 - 1, Qt.Horizontal, "水胶比A/P") self.MixMode.setHeaderData(16 - 1, Qt.Horizontal, "砂率 BS") self.MixMode.setHeaderData(17 - 1, Qt.Horizontal, "外加剂掺量A%") self.MixMode.setHeaderData(18 - 1, Qt.Horizontal, "外加剂用量LS-JS(B)") self.MixMode.setHeaderData(19 - 1, Qt.Horizontal, "膨胀剂用量") self.MixMode.setHeaderData(20 - 1, Qt.Horizontal, "质量密度 (容重)Mcp") self.MixMode.setHeaderData(21 - 1, Qt.Horizontal, "初凝时间") self.MixMode.setHeaderData(22 - 1, Qt.Horizontal, "终凝时间") self.MixMode.select() self.MixtableView.setModel(self.MixMode) self.MixtableView.setSelectionMode(QTableView.SingleSelection) self.MixtableView.setSelectionBehavior(QTableView.SelectRows) self.MixtableView.resizeColumnsToContents() if self.con2.isOpen(): self.con2.close() def OutExcel(self): if self.con2.isOpen(): self.con2.close() self.stackedWidget.setCurrentIndex(0) def InSQL(self): if self.con2.isOpen(): self.con2.close() self.stackedWidget.setCurrentIndex(1) def OutSQL(self): if self.con2.isOpen(): self.con2.close() self.stackedWidget.setCurrentIndex(2) def CementDate(self): self.stackedWidget.setCurrentIndex(3) self.cement_refresh() if not self.con2.isOpen(): self.con2.open() self.CementMode = QSqlTableModel() self.CementMode.setTable("cement_attribute_data") self.CementMode.setSort(0, Qt.AscendingOrder) self.CementMode.setEditStrategy(self.CementMode.OnManualSubmit) self.CementMode.setHeaderData(0, Qt.Horizontal, "id") self.CementMode.setHeaderData(1, Qt.Horizontal, "进场日期") self.CementMode.setHeaderData(2, Qt.Horizontal, "水泥品种") self.CementMode.setHeaderData(3, Qt.Horizontal, "生产厂家") self.CementMode.setHeaderData(4, Qt.Horizontal, "生产日期") self.CementMode.setHeaderData(5, Qt.Horizontal, "编号") self.CementMode.setHeaderData(6, Qt.Horizontal, "数量(T)") self.CementMode.setHeaderData(7, Qt.Horizontal, "安定性") self.CementMode.setHeaderData(8, Qt.Horizontal, "初凝") self.CementMode.setHeaderData(9, Qt.Horizontal, "终凝") self.CementMode.setHeaderData(10, Qt.Horizontal, "R3抗压") self.CementMode.setHeaderData(11, Qt.Horizontal, "R28抗压") self.CementMode.setHeaderData(12, Qt.Horizontal, "R3抗折") self.CementMode.setHeaderData(13, Qt.Horizontal, "R28抗折") self.CementMode.setHeaderData(14, Qt.Horizontal, "是否优先") self.CementMode.select() self.CementtableView.setModel(self.CementMode) self.CementtableView.setSelectionMode(QTableView.SingleSelection) self.CementtableView.setSelectionBehavior(QTableView.SelectRows) self.CementtableView.resizeColumnsToContents() def MixDate(self): self.stackedWidget.setCurrentIndex(4) self.mix_refresh() if not self.con2.isOpen(): self.con2.open() self.MixMode = QSqlTableModel() self.MixMode.setTable("concrete_mix") self.MixMode.setSort(0, Qt.AscendingOrder) self.MixMode.setEditStrategy(QSqlTableModel.OnManualSubmit) self.MixMode.setHeaderData(1 - 1, Qt.Horizontal, "名称") self.MixMode.setHeaderData(2 - 1, Qt.Horizontal, "配合比编号") self.MixMode.setHeaderData(3 - 1, Qt.Horizontal, "强度等级 ") self.MixMode.setHeaderData(4 - 1, Qt.Horizontal, "抗渗等级") self.MixMode.setHeaderData(5 - 1, Qt.Horizontal, "膨胀") self.MixMode.setHeaderData(6 - 1, Qt.Horizontal, "配合比编号2") self.MixMode.setHeaderData(7 - 1, Qt.Horizontal, "坍落度") self.MixMode.setHeaderData(8 - 1, Qt.Horizontal, "标准差(MPa)") self.MixMode.setHeaderData(9 - 1, Qt.Horizontal, "配制强度(MPa)") self.MixMode.setHeaderData(10 - 1, Qt.Horizontal, "水W") self.MixMode.setHeaderData(11 - 1, Qt.Horizontal, "水泥C") self.MixMode.setHeaderData(12 - 1, Qt.Horizontal, "粉煤灰F") self.MixMode.setHeaderData(13 - 1, Qt.Horizontal, "砂S") self.MixMode.setHeaderData(14 - 1, Qt.Horizontal, "石G") self.MixMode.setHeaderData(15 - 1, Qt.Horizontal, "水胶比A/P") self.MixMode.setHeaderData(16 - 1, Qt.Horizontal, "砂率 BS") self.MixMode.setHeaderData(17 - 1, Qt.Horizontal, "外加剂掺量A%") self.MixMode.setHeaderData(18 - 1, Qt.Horizontal, "外加剂用量LS-JS(B)") self.MixMode.setHeaderData(19 - 1, Qt.Horizontal, "膨胀剂用量") self.MixMode.setHeaderData(20 - 1, Qt.Horizontal, "质量密度 (容重)Mcp") self.MixMode.setHeaderData(21 - 1, Qt.Horizontal, "初凝时间") self.MixMode.setHeaderData(22 - 1, Qt.Horizontal, "终凝时间") self.MixMode.select() self.MixtableView.setModel(self.MixMode) self.MixtableView.setSelectionMode(QTableView.SingleSelection) self.MixtableView.setSelectionBehavior(QTableView.SelectRows) self.MixtableView.resizeColumnsToContents() def ChangePrarmer(self): if QMessageBox.question(QWidget(), "Question", "是否确定修改参数?", QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Ok) == QMessageBox.Ok: try: parm = Parameter( MinC_Strength=float(self.MinC_StrengthEdit.text()), MaxC_Strength=float(self.MaxC_StrengthEdit.text()), MinS_FinenessDensity=float( self.MinS_FinenessDensityEdit.text()), MaxS_FinenessDensity=float( self.MaxS_FinenessDensityEdit.text()), MinS_SurfaceDensity=float( self.MinS_SurfaceDensityEdit.text()), MaxS_SurfaceDensity=float( self.MaxS_SurfaceDensityEdit.text()), MinS_Density=float(self.MinS_DensityEdit.text()), MaxS_Density=float(self.MaxS_DensityEdit.text()), MinS_SlitContent=float(self.MinS_SlitContentEdit.text()), MaxS_SlitContent=float(self.MaxS_SlitContentEdit.text()), MinS_WaterContent=float(self.MinS_WaterContentEdit.text()), MaxS_WaterContent=float(self.MaxS_WaterContentEdit.text()), MinG_GrainContent=float(self.MinG_GrainContentEdit.text()), MaxG_GrainContent=float(self.MaxG_GrainContentEdit.text()), MinG_CrushLevel=float(self.MinG_CrushLevelEdit.text()), MaxG_CrushLevel=float(self.MaxG_CrushLevelEdit.text()), MinG_Density=float(self.MinG_DensityEdit.text()), MaxG_Density=float(self.MaxG_DensityEdit.text()), MinG_SlitContent=float(self.MinG_SlitContentEdit.text()), MaxG_SlitContent=float(self.MaxG_SlitContentEdit.text()), MinG_WaterContent=float(self.MinG_WaterContentEdit.text()), MaxG_WaterContent=float(self.MaxG_WaterContentEdit.text()), MinA_Density=float(self.MinA_DensityEdit.text()), MaxA_Density=float(self.MaxA_DensityEdit.text()), MinR7_Compression=float(self.MinR7_CompressionEdit.text()), MaxR7_Compression=float(self.MaxR7_CompressionEdit.text()), MinR28_Compression=float( self.MinR28_CompressionEdit.text()), MaxR28_Compression=float( self.MaxR28_CompressionEdit.text()), Project1Manager=self.Project1Manager.currentText(), Project1FillSheeter=self.Project1FillSheeter.currentText(), Project2InspectCodeEdit=self.Project2InspectCodeEdit.text( ), Project2Manager=self.Project2Manager.currentText(), Project2Checker=self.Project2Checker.currentText(), Project2Try=self.Project2Try.currentText(), Project3MakeSheet=self.Project3MakeSheet.currentText(), Project3InspectCodeEdit=self.Project3InspectCodeEdit.text( ), Project4Manager=self.Project4Manager.currentText(), Project4Checker=self.Project4Checker.currentText(), Project4Calculate=self.Project4Calculate.currentText(), Project4InspectCodeEdit=self.Project4InspectCodeEdit.text( ), Project5Manager=self.Project5Manager.currentText(), Project5Filler=self.Project5Filler.currentText(), Project7ConDesignSpeciEdit=self.Project7ConDesignSpeciEdit. text(), Project7CodeEdit=self.Project7CodeEdit.text(), Project7Manager=self.Project7Manager.currentText(), Project7Checker=self.Project7Checker.currentText(), Project7try=self.Project7try.currentText(), Project9Manager=self.Project9Manager.currentText(), Project9Checker=self.Project9Checker.currentText(), Project9Record=self.Project9Record.currentText(), Project10ConTestReportTestBasisEdit=self. Project10ConTestReportTestBasisEdit.text(), Project10InspectCodeEdit=self.Project10InspectCodeEdit. text(), Project10TimeEdit=self.Project10TimeEdit.text(), Project10MaxCreepEdit=self.Project10MaxCreepEdit.text(), Project10MinCreepEdit=self.Project10MinCreepEdit.text(), Project10Manager=self.Project10Manager.currentText(), Project10Examine=self.Project10Examine.currentText(), Project10Checker=self.Project10Checker.currentText(), Project11Manager=self.Project11Manager.currentText(), Project11Checker=self.Project11Checker.currentText()) session.add(parm) session.commit() QMessageBox.information(QWidget(), "修改", "成功") except BaseException: QMessageBox.information(QWidget(), "错误", "修改失败!!!!\n请核对数据是否有误或留空白。") def cement_refresh(self): self.CementMode.setFilter("1=1") self.CementMode.select() def cement_submit(self): if (QMessageBox.question(QWidget(), "修改", "是否确定修改", QMessageBox.Yes | QMessageBox.No) == QMessageBox.Yes): try: self.CementMode.submitAll() QMessageBox.about(QWidget(), '修改', '修改成功') except BaseException: QMessageBox.about(QWidget(), '失败', '失败') def cement_del(self): try: index = self.CementtableView.currentIndex() self.CementMode.removeRow(index.row()) self.CementMode.submitAll() self.CementMode.select() except BaseException: QMessageBox.about(QWidget(), '失败', '失败') def query_cement(self): CementId = self.CementIdEdit_2.text() IsPriority = self.IsPriorityEdit.text() sql = "1=1 " if CementId != '': sql = sql + \ "and CementId like '%CementId_1%' ".replace('CementId_1', CementId) if IsPriority != '': sql = sql + \ "and PriorityLevel like '%PriorityLevel_1%' ".replace('PriorityLevel_1', IsPriority) print(sql) self.CementMode.setFilter(sql) self.CementMode.select() def mix_refresh(self): self.MixMode.setFilter("1=1") self.CementMode.select() def mix_submit(self): if (QMessageBox.question(QWidget(), "修改", "是否确定修改", QMessageBox.Yes | QMessageBox.No) == QMessageBox.Yes): try: self.MixMode.submitAll() QMessageBox.about(QWidget(), '修改', '修改成功') except BaseException: QMessageBox.about(QWidget(), '失败', '失败') def mix_del(self): try: index = self.MixtableView.currentIndex() self.MixMode.removeRow(index.row()) self.MixMode.submitAll() self.MixMode.select() except BaseException: QMessageBox.about(QWidget(), '失败', '失败') def query_mix(self): MixName = self.MixNameEdit.text() MixId = self.MixIdEdit.text() MixStrength = self.MixStrengthEdit.text() MixLevel = self.MixLevelEdit.text() sql = "1=1 " if MixName != '': sql = sql + \ "and ConcreteName like '%MixName_1%' ".replace('MixName_1', MixName) if MixId != '': sql = sql + \ "and MixRatioID like '%MixId_1%' ".replace('MixId_1', MixId) if MixStrength != '': sql = sql + \ "and StrengthLevel like '%MixStrength_1%' ".replace('MixStrength_1', MixStrength) if MixLevel != '': sql = sql + \ "and ImperLevel like '%MixLevel_1%' ".replace('MixLevel_1', MixLevel) print(sql) self.MixMode.setFilter(sql) self.MixMode.select() def empty_Art(self): if (QMessageBox.question(QWidget(), "删除", "是否确定删除所有数据", QMessageBox.Yes | QMessageBox.No) == QMessageBox.Yes): try: self.con2.exec_("delete from cement_attribute_data") self.CementMode.select() QMessageBox.about(QWidget(), '删除', '删除成功') except BaseException: QMessageBox.about(QWidget(), '失败', '失败') def empty_Mix(self): if (QMessageBox.question(QWidget(), "删除", "是否确定删除所有数据", QMessageBox.Yes | QMessageBox.No) == QMessageBox.Yes): try: self.con2.exec_("delete from concrete_mix") self.MixMode.select() QMessageBox.about(QWidget(), '删除', '删除成功') except BaseException: QMessageBox.about(QWidget(), '失败', '失败') def addArt(self): try: row = self.CementMode.rowCount() self.CementMode.insertRow(row) index = self.CementMode.index(row, 0) self.CementtableView.setCurrentIndex(index) self.CementtableView.edit(index) self.CementMode.submit() except BaseException: QMessageBox.about(QWidget(), '失败', '失败') def addMix(self): try: row = self.MixMode.rowCount() self.MixMode.insertRow(row) index = self.MixMode.index(row, 0) self.MixtableView.setCurrentIndex(index) self.MixtableView.edit(index) self.MixMode.submit() except BaseException: QMessageBox.about(QWidget(), '失败', '失败') def CementInfo(self): from DateBase.insert_value import insert_cement_attribute_data try: filePath, filetype = QFileDialog.getOpenFileName( QWidget(), "选取水泥资料一览表", "../", "Text Files (*.xlsx)") if filePath == '': raise Exception('请选择文件夹') self.CementInfoPath.setText(filePath) filename = self.CementInfoPath.text() print(filename) insert_cement_attribute_data(filename) QMessageBox.information(QWidget(), "成功", "水泥资料一览表导入成功") except BaseException: QMessageBox.information(QWidget(), "错误", "添加失败!!!!!\n请检查水泥资料一览表表格的数据格式。\n添加失败!!!!") def ConMixInsert(self): from DateBase.insert_value import insert_concrete_mix try: filePath, filetype = QFileDialog.getOpenFileName( QWidget(), "选取配合比选用汇总表", "../", "Text Files (*.xlsx)") if filePath == '': raise Exception('请选择文件夹') self.MixPoportionPath.setText(filePath) filename = self.MixPoportionPath.text() print('ss') insert_concrete_mix(filename) QMessageBox.information(QWidget(), "成功", "配合比选用汇总表导入成功") except BaseException: QMessageBox.information(QWidget(), "错误", "添加失败!!!!!\n请检查配合比选用汇总表格的数据格式。\n添加失败!!!!") def ChoicConcreteUsageRecord(self): try: filePath, filetype = QFileDialog.getOpenFileName( QWidget(), "选取水泥使用一览表", "../", "Text Files (*.xlsx)") if filePath == '': raise Exception('请选择文件夹') self.ConcreteUsageRecordPath.setText(filePath) self.OutPutButton.setEnabled(True) self.OutPutVoidButton.setEnabled(True) except BaseException: pass def ChoicSQLPath(self): try: filePath = QFileDialog.getExistingDirectory( QWidget(), "选取生成表格的文件夹", "../", ) print(filePath) if filePath == '': print('没有选中文件') raise Exception('请选择文件夹') self.OutSQLButton_3.setEnabled(True) self.OutSQLPath.setText(filePath) except BaseException: pass def OutPutSQL(self): try: art = session.query(CementAttributeDatum).all() mix = session.query(ConcreteMix).all() wb = Workbook() ws = wb.active ws['A1'] = '水泥资料一览表' ws.merge_cells('A1:N1') ws['A2'] = '进场日期' ws['B2'] = '水泥品种' ws['C2'] = '生产厂家' ws['D2'] = '生产日期' ws['E2'] = '编号' ws['F2'] = '数量(T)' ws['G2'] = '安定性' ws['H2'] = '初凝' ws['I2'] = '终凝' ws['J2'] = 'R3抗压' ws['K2'] = 'R28抗压' ws['L2'] = 'R3抗折' ws['M2'] = 'R28抗折' ws['N2'] = '是否优先' for i in range(len(art)): one_art = art[i] ws['A' + str(i + 3)] = one_art.ArrivalTime ws['B' + str(i + 3)] = one_art.CementVariety ws['C' + str(i + 3)] = one_art.Manufacturer ws['D' + str(i + 3)] = one_art.ProductionDate ws['E' + str(i + 3)] = one_art.CementId ws['F' + str(i + 3)] = one_art.CementNumber if one_art.IsStability == 1: ws['G' + str(i + 3)] = '合格' else: ws['G' + str(i + 3)] = '不合格' ws['H' + str(i + 3)] = one_art.InitialTime ws['I' + str(i + 3)] = one_art.FinalTime ws['J' + str(i + 3)] = one_art.R3_Compression ws['K' + str(i + 3)] = one_art.R28_Compression ws['L' + str(i + 3)] = one_art.R3_Bending ws['M' + str(i + 3)] = one_art.R28_Bending ws['N' + str(i + 3)] = one_art.PriorityLevel wb.save(self.OutSQLPath.text() + '/水泥一览表test.xlsx') # SQL配合比表 wb = Workbook() ws = wb.active ws['A1'] = '佛山市三水区建友混凝土有限公司' ws['A2'] = '配合比选用汇总表' ws.merge_cells('A1:W1') ws.merge_cells('A2:W2') ws['A4'] = '名称' ws['B4'] = '配合比编号' ws['C4'] = '强度等级 ' ws.merge_cells('C4:D4') ws['E4'] = '抗渗等级' ws['F4'] = '膨胀' ws['G4'] = '配合比编号' ws['H4'] = '坍落度' ws['I4'] = '标准差(MPa)' ws['J4'] = '配制强度(MPa)W' ws['K4'] = '水W' ws['L4'] = '水泥C' ws['M4'] = '粉煤灰F' ws['N4'] = '砂S' ws['O4'] = '石G' ws['P4'] = '水胶比A/P' ws['Q4'] = '砂率 BS' ws['R4'] = '外加剂掺量A%' ws['S4'] = '外加剂用量LS-JS(B)' ws['T4'] = '膨胀剂用量' ws['U4'] = '质量密度 (容重)Mcp' ws['V4'] = '初凝时间' ws['W4'] = '终凝时间' for i in range(len(mix)): ws['C' + str(i + 5)] = 'C' ws['A' + str(i + 5)] = mix[i].ConcreteName ws['B' + str(i + 5)] = mix[i].MixRatioID ws['D' + str(i + 5)] = mix[i].StrengthLevel ws['E' + str(i + 5)] = mix[i].ImperLevel if mix[i].ImperLevel is None: ws['E' + str(i + 5)] = '/' ws['F' + str(i + 5)] = mix[i].SwellLevel if mix[i].SwellLevel is None: ws['F' + str(i + 5)] = '/' ws['G' + str(i + 5)] = mix[i].MixRatioName ws['H' + str(i + 5)] = mix[i].SlumpNum ws['I' + str(i + 5)] = mix[i].StandardDeviation ws['J' + str(i + 5)] = mix[i].ConcreteStrengh ws['K' + str(i + 5)] = mix[i].WaterNum ws['L' + str(i + 5)] = mix[i].CementNum ws['N' + str(i + 5)] = mix[i].FlyashNum ws['M' + str(i + 5)] = mix[i].SandNum ws['O' + str(i + 5)] = mix[i].GravelNum ws['P' + str(i + 5)] = mix[i].CementRatio ws['Q' + str(i + 5)] = mix[i].SandRatio ws['R' + str(i + 5)] = mix[i].AdmixtureAmount ws['S' + str(i + 5)] = mix[i].AdmixtureNum ws['T' + str(i + 5)] = mix[i].SwellingNum ws['U' + str(i + 5)] = mix[i].MassDensity ws['V' + str(i + 5)] = mix[i].InitialTime ws['W' + str(i + 5)] = mix[i].FinalTime wb.save(self.OutSQLPath.text() + '/配合比表test.xlsx') QMessageBox.information(QWidget(), "成功", "请在刚刚选中的目录下查看文件") except BaseException: QMessageBox.information(QWidget(), "错误", "添加失败!!!!!\n请检查配合比选用汇总表格的数据格式。\n添加失败!!!!") def ouputexcel(self): try: books = [] book = load_workbook(self.ConcreteUsageRecordPath.text()) print('成功读取水泥使用记录表') # 生成12份表格 book1, book7 = ConUseBuyRecord(book) print("17") book2, book3, book4 = ConStrengReport(book) print("234") book5 = CreateConFacyoryCard(book, book1) print("5") book6 = CreateSlumpCard(book5) print("6") book8 = CreteConUseProve(book) print("8") book9 = ConQualityRecord(book, book3, book7) print("9") book10 = PermeabilityTestReport(book, book7) print("10") books.append(book1) books.append(book2) books.append(book3) books.append(book4) books.append(book5) books.append(book6) books.append(book7) books.append(book8) books.append(book9) books.append(book10) except BaseException: print("读取失败") try: # 文件名处理 fileNames = [ '1、水泥购进、使用一览表', '2、混凝土试件抗压强度检验报告', '3、混凝土试块强度试验结果汇总表', '4、标准养护混凝土抗压强度计算表', '5、建友商品混凝土出厂合格证', '6、混凝土坍落度验收表', '7、混凝土配合比设计报告', '8、工地使用预拌混凝土证明书', '9、混凝土搅拌质量记录表', '10、抗渗性能检测报告', '11、施工配合比' ] filePath = QFileDialog.getExistingDirectory( QWidget(), "选取生成表格的文件夹", "C:/", ) print(filePath) if filePath == '': print('没有选中文件') raise Exception('请选择文件夹') filePaths = [] # 存放文件路劲 for i in fileNames: filePaths.append(filePath + '/' + i + '.xlsx') for j in range(1, 11): books[j - 1].save(filePaths[j - 1]) # 记录 filePaths = [] filePath = his() for i in fileNames: filePaths.append(filePath + '/' + i + '.xlsx') print(filePaths) for j in range(1, 11): books[j - 1].save(filePaths[j - 1]) QMessageBox.information(QWidget(), "成功导出", "请在您刚刚选定的文件夹内查看生成的文件") except BaseException: QMessageBox.information(QWidget(), "错误", "添加失败!!!!!\n添加失败!!!!") def outputvoidexcel(self): from Excel.CreateMode.CreateConFactoryCardMode17 import ConUseBuyRecordMode from Excel.CreateMode.CreateConStrentReportMode234 import ConStrengReportMode from Excel.CreateMode.CreateConFactoryCardMode56 import CreateConFacyoryCardMode, CreateSlumpCardMode from Excel.CreateMode.ConUseProveMode8 import CreteConUseProveMode from Excel.CreateMode.ConQualityRecordMode9 import ConQualityRecordMode from Excel.CreateMode.PermeabilityTestReportMode10 import PermeabilityTestReportMode try: books = [] book = load_workbook(self.ConcreteUsageRecordPath.text()) print('成功读取水泥使用记录表') # 生成12份表格 book1, book7 = ConUseBuyRecordMode(book) print("17") book2, book3, book4 = ConStrengReportMode(book) print("234") book5 = CreateConFacyoryCardMode(book) print("5") book6 = CreateSlumpCardMode(book5) print("6") book8 = CreteConUseProveMode(book) print("8") book9 = ConQualityRecordMode(book) print("9") book10 = PermeabilityTestReportMode(book) print("10") books.append(book1) books.append(book2) books.append(book3) books.append(book4) books.append(book5) books.append(book6) books.append(book7) books.append(book8) books.append(book9) books.append(book10) except BaseException: print("读取失败") try: # 文件名处理 fileNames = [ '1、水泥购进、使用一览表', '2、混凝土试件抗压强度检验报告', '3、混凝土试块强度试验结果汇总表', '4、标准养护混凝土抗压强度计算表', '5、建友商品混凝土出厂合格证', '6、混凝土坍落度验收表', '7、混凝土配合比设计报告', '8、工地使用预拌混凝土证明书', '9、混凝土搅拌质量记录表', '10、抗渗性能检测报告', '11、施工配合比' ] filePath = QFileDialog.getExistingDirectory( QWidget(), "选取生成表格的文件夹", "C:/", ) print(filePath) if filePath == '': print('没有选中文件') raise Exception('请选择文件夹') filePaths = [] # 存放文件路劲 for i in fileNames: filePaths.append(filePath + '/' + i + '空白.xlsx') for j in range(1, 11): books[j - 1].save(filePaths[j - 1]) QMessageBox.information(QWidget(), "成功导出", "请在您刚刚选定的文件夹内查看生成的文件") except BaseException: QMessageBox.information(QWidget(), "错误", "添加失败!!!!!\n添加失败!!!!")
filename = ".\db\database.db" create = not QFile.exists(filename) print(create) if create: common.create_or_open_db(filename) db = QSqlDatabase.addDatabase("QSQLITE") db.setDatabaseName(filename) if not db.open(): QMessageBox.warning( None, "Reference Data", "Database Error: {0}".format(db.lastError().text())) sys.exit(1) model = QSqlTableModel() delrow = -1 initializeModel(model) view1 = createView("Table Model (View 1)", model) view1.clicked.connect(findrow) dlg = QDialog() layout = QVBoxLayout() layout.addWidget(view1) addBtn = QPushButton("添加一行") addBtn.clicked.connect(addrow) layout.addWidget(addBtn) delBtn = QPushButton("删除一行") delBtn.clicked.connect(lambda: model.removeRow(view1.currentIndex().row())) layout.addWidget(delBtn)
def function(self): self.OutExcelButton.clicked.connect(self.OutExcel) # 导出表格按钮 self.InSQLButton.clicked.connect(self.InSQL) # Excel导入信息按钮 self.OutPutSQLButton.clicked.connect(self.OutSQL) # 基本信息导出按钮 self.CementDateButton.clicked.connect(self.CementDate) # 水泥一览表信息按钮 self.MixpushButton.clicked.connect(self.MixDate) # 配合比表信息按钮 self.ChangePrarmerButton.clicked.connect( self.ChangePrarmer) # 确认修改参数按钮 self.CementrefreshButton.clicked.connect(self.cement_refresh) # 刷新 self.CementsubmitButton.clicked.connect(self.cement_submit) # 提交 self.CementdelButton.clicked.connect(self.cement_del) # 删除 self.CementQueryButton.clicked.connect(self.query_cement) # 查询 self.mixrefreshButton.clicked.connect(self.mix_refresh) # 刷新 self.mixsubmitButton.clicked.connect(self.mix_submit) # 提交 self.MixDelButton.clicked.connect(self.mix_del) # 删除 self.MixqueryButton.clicked.connect(self.query_mix) # 查询 self.deletArtButton.clicked.connect(self.empty_Art) # 水泥一览表数据清空 self.deleMIXButton.clicked.connect(self.empty_Mix) # 配合比表数据清空 self.CementAddButton.clicked.connect(self.addArt) # 添加水泥按钮 self.mixAddButton.clicked.connect(self.addMix) # 添加配合比按钮 self.CementInfoButton.clicked.connect(self.CementInfo) # 选择水泥一览表记录 self.MixPoportionButton.clicked.connect(self.ConMixInsert) # 选择配合比表记录 self.ChoicConcreteUsageRecordButton.clicked.connect( self.ChoicConcreteUsageRecord) # 选择使用记录表 self.OutSQLButton_2.clicked.connect(self.ChoicSQLPath) # 选择OutPutSQL路径 self.OutSQLButton_3.clicked.connect(self.OutPutSQL) # 导出SQL self.OutPutButton.clicked.connect(self.ouputexcel) # 确认导出按钮 self.OutPutVoidButton.clicked.connect(self.outputvoidexcel) # 确认导出按钮 # 查看数据库是否存在 try: parm = get_parm() print('已获取SQL') except BaseException: print('创建SQL') from DateBase.creat import creat_table from DateBase.insert_value import parm_init creat_table() parm_init() # 填充信息 parm = get_parm() self.MinC_StrengthEdit.setText(str(parm.MinC_Strength)) self.MaxC_StrengthEdit.setText(str(parm.MaxC_Strength)) self.MinS_FinenessDensityEdit.setText(str(parm.MinS_FinenessDensity)) self.MaxS_FinenessDensityEdit.setText(str(parm.MaxS_FinenessDensity)) self.MinS_SurfaceDensityEdit.setText(str(parm.MinS_SurfaceDensity)) self.MaxS_SurfaceDensityEdit.setText(str(parm.MaxS_SurfaceDensity)) self.MinS_DensityEdit.setText(str(parm.MinS_Density)) self.MaxS_DensityEdit.setText(str(parm.MaxS_Density)) self.MinS_SlitContentEdit.setText(str(parm.MinS_SlitContent)) self.MaxS_SlitContentEdit.setText(str(parm.MaxS_SlitContent)) self.MinS_WaterContentEdit.setText(str(parm.MinS_WaterContent)) self.MaxS_WaterContentEdit.setText(str(parm.MaxS_WaterContent)) self.MinG_GrainContentEdit.setText(str(parm.MinG_GrainContent)) self.MaxG_GrainContentEdit.setText(str(parm.MaxG_GrainContent)) self.MinG_CrushLevelEdit.setText(str(parm.MinG_CrushLevel)) self.MaxG_CrushLevelEdit.setText(str(parm.MaxG_CrushLevel)) self.MinG_DensityEdit.setText(str(parm.MinG_Density)) self.MaxG_DensityEdit.setText(str(parm.MaxG_Density)) self.MinG_SlitContentEdit.setText(str(parm.MinG_SlitContent)) self.MaxG_SlitContentEdit.setText(str(parm.MaxG_SlitContent)) self.MinG_WaterContentEdit.setText(str(parm.MinG_WaterContent)) self.MaxG_WaterContentEdit.setText(str(parm.MaxG_WaterContent)) self.MinA_DensityEdit.setText(str(parm.MinA_Density)) self.MaxA_DensityEdit.setText(str(parm.MaxA_Density)) self.MinR7_CompressionEdit.setText(str(parm.MinR7_Compression)) self.MaxR7_CompressionEdit.setText(str(parm.MaxR7_Compression)) self.MinR28_CompressionEdit.setText(str(parm.MinR28_Compression)) self.MaxR28_CompressionEdit.setText(str(parm.MaxR28_Compression)) _translate = QtCore.QCoreApplication.translate PicName = getpiname() for i in range(len(PicName)): self.Project1Manager.addItem("") self.Project1Manager.setItemText(i, _translate("Form", PicName[i])) self.Project1FillSheeter.addItem("") self.Project1FillSheeter.setItemText( i, _translate("Form", PicName[i])) self.Project2Manager.addItem("") self.Project2Manager.setItemText(i, _translate("Form", PicName[i])) self.Project2Checker.addItem("") self.Project2Checker.setItemText(i, _translate("Form", PicName[i])) self.Project2Try.addItem("") self.Project2Try.setItemText(i, _translate("Form", PicName[i])) self.Project3MakeSheet.addItem("") self.Project3MakeSheet.setItemText(i, _translate("Form", PicName[i])) self.Project4Manager.addItem("") self.Project4Manager.setItemText(i, _translate("Form", PicName[i])) self.Project4Checker.addItem("") self.Project4Checker.setItemText(i, _translate("Form", PicName[i])) self.Project4Calculate.addItem("") self.Project4Calculate.setItemText(i, _translate("Form", PicName[i])) self.Project5Manager.addItem("") self.Project5Manager.setItemText(i, _translate("Form", PicName[i])) self.Project5Filler.addItem("") self.Project5Filler.setItemText(i, _translate("Form", PicName[i])) self.Project7Manager.addItem("") self.Project7Manager.setItemText(i, _translate("Form", PicName[i])) self.Project7Checker.addItem("") self.Project7Checker.setItemText(i, _translate("Form", PicName[i])) self.Project7try.addItem("") self.Project7try.setItemText(i, _translate("Form", PicName[i])) self.Project9Manager.addItem("") self.Project9Manager.setItemText(i, _translate("Form", PicName[i])) self.Project9Checker.addItem("") self.Project9Checker.setItemText(i, _translate("Form", PicName[i])) self.Project9Record.addItem("") self.Project9Record.setItemText(i, _translate("Form", PicName[i])) self.Project10Manager.addItem("") self.Project10Manager.setItemText(i, _translate("Form", PicName[i])) self.Project10Examine.addItem("") self.Project10Examine.setItemText(i, _translate("Form", PicName[i])) self.Project10Checker.addItem("") self.Project10Checker.setItemText(i, _translate("Form", PicName[i])) self.Project11Manager.addItem("") self.Project11Manager.setItemText(i, _translate("Form", PicName[i])) self.Project11Checker.addItem("") self.Project11Checker.setItemText(i, _translate("Form", PicName[i])) self.Project1Manager.setCurrentText(str(parm.Project1Manager)) self.Project1FillSheeter.setCurrentText(str(parm.Project1FillSheeter)) self.Project2InspectCodeEdit.setText(str(parm.Project2InspectCodeEdit)) self.Project2Manager.setCurrentText(str(parm.Project2Manager)) self.Project2Checker.setCurrentText(str(parm.Project2Checker)) self.Project2Try.setCurrentText(str(parm.Project2Try)) self.Project3MakeSheet.setCurrentText(str(parm.Project3MakeSheet)) self.Project3InspectCodeEdit.setText(str(parm.Project3InspectCodeEdit)) self.Project4Manager.setCurrentText(str(parm.Project4Manager)) self.Project4Checker.setCurrentText(str(parm.Project4Checker)) self.Project4Calculate.setCurrentText(str(parm.Project4Calculate)) self.Project4InspectCodeEdit.setText(str(parm.Project4InspectCodeEdit)) self.Project5Manager.setCurrentText(str(parm.Project5Manager)) self.Project5Filler.setCurrentText(str(parm.Project5Filler)) self.Project7ConDesignSpeciEdit.setText( str(parm.Project7ConDesignSpeciEdit)) self.Project7CodeEdit.setText(str(parm.Project7CodeEdit)) self.Project7Manager.setCurrentText(str(parm.Project7Manager)) self.Project7Checker.setCurrentText(str(parm.Project7Checker)) self.Project7try.setCurrentText(str(parm.Project7try)) self.Project9Manager.setCurrentText(str(parm.Project9Manager)) self.Project9Checker.setCurrentText(str(parm.Project9Checker)) self.Project9Record.setCurrentText(str(parm.Project9Record)) self.Project10ConTestReportTestBasisEdit.setText( str(parm.Project10ConTestReportTestBasisEdit)) self.Project10InspectCodeEdit.setText( str(parm.Project10InspectCodeEdit)) from PyQt5.QtCore import QTime time = str(parm.Project10TimeEdit).split(':') time = QTime(int(time[0]), int(time[1])) self.Project10TimeEdit.setTime(time) self.Project10MaxCreepEdit.setText(str(parm.Project10MaxCreepEdit)) self.Project10MinCreepEdit.setText(str(parm.Project10MinCreepEdit)) self.Project10Manager.setCurrentText(str(parm.Project10Manager)) self.Project10Examine.setCurrentText(str(parm.Project10Examine)) self.Project10Checker.setCurrentText(str(parm.Project10Checker)) self.Project11Manager.setCurrentText(str(parm.Project11Manager)) self.Project11Checker.setCurrentText(str(parm.Project11Checker)) # 插入水泥一览表 self.con2 = QSqlDatabase.addDatabase('QSQLITE') self.con2.setDatabaseName(db_path) # con2.exec_("PRAGMA foreign_keys = ON;") self.CementMode = QSqlTableModel() self.CementMode.setTable("cement_attribute_data") self.CementMode.setSort(0, Qt.AscendingOrder) self.CementMode.setEditStrategy(self.CementMode.OnManualSubmit) self.CementMode.setHeaderData(0, Qt.Horizontal, "id") self.CementMode.setHeaderData(1, Qt.Horizontal, "进场日期") self.CementMode.setHeaderData(2, Qt.Horizontal, "水泥品种") self.CementMode.setHeaderData(3, Qt.Horizontal, "生产厂家") self.CementMode.setHeaderData(4, Qt.Horizontal, "生产日期") self.CementMode.setHeaderData(5, Qt.Horizontal, "编号") self.CementMode.setHeaderData(6, Qt.Horizontal, "数量(T)") self.CementMode.setHeaderData(7, Qt.Horizontal, "安定性") self.CementMode.setHeaderData(8, Qt.Horizontal, "初凝") self.CementMode.setHeaderData(9, Qt.Horizontal, "终凝") self.CementMode.setHeaderData(10, Qt.Horizontal, "R3抗压") self.CementMode.setHeaderData(11, Qt.Horizontal, "R28抗压") self.CementMode.setHeaderData(12, Qt.Horizontal, "R3抗折") self.CementMode.setHeaderData(13, Qt.Horizontal, "R28抗折") self.CementMode.setHeaderData(14, Qt.Horizontal, "是否优先") self.CementMode.select() self.CementtableView.setModel(self.CementMode) self.CementtableView.setSelectionMode(QTableView.SingleSelection) self.CementtableView.setSelectionBehavior(QTableView.SelectRows) self.CementtableView.resizeColumnsToContents() # 配合比表 self.MixMode = QSqlTableModel() self.MixMode.setTable("concrete_mix") self.MixMode.setSort(0, Qt.AscendingOrder) self.MixMode.setEditStrategy(QSqlTableModel.OnManualSubmit) self.MixMode.setHeaderData(1 - 1, Qt.Horizontal, "名称") self.MixMode.setHeaderData(2 - 1, Qt.Horizontal, "配合比编号") self.MixMode.setHeaderData(3 - 1, Qt.Horizontal, "强度等级 ") self.MixMode.setHeaderData(4 - 1, Qt.Horizontal, "抗渗等级") self.MixMode.setHeaderData(5 - 1, Qt.Horizontal, "膨胀") self.MixMode.setHeaderData(6 - 1, Qt.Horizontal, "配合比编号2") self.MixMode.setHeaderData(7 - 1, Qt.Horizontal, "坍落度") self.MixMode.setHeaderData(8 - 1, Qt.Horizontal, "标准差(MPa)") self.MixMode.setHeaderData(9 - 1, Qt.Horizontal, "配制强度(MPa)") self.MixMode.setHeaderData(10 - 1, Qt.Horizontal, "水W") self.MixMode.setHeaderData(11 - 1, Qt.Horizontal, "水泥C") self.MixMode.setHeaderData(12 - 1, Qt.Horizontal, "粉煤灰F") self.MixMode.setHeaderData(13 - 1, Qt.Horizontal, "砂S") self.MixMode.setHeaderData(14 - 1, Qt.Horizontal, "石G") self.MixMode.setHeaderData(15 - 1, Qt.Horizontal, "水胶比A/P") self.MixMode.setHeaderData(16 - 1, Qt.Horizontal, "砂率 BS") self.MixMode.setHeaderData(17 - 1, Qt.Horizontal, "外加剂掺量A%") self.MixMode.setHeaderData(18 - 1, Qt.Horizontal, "外加剂用量LS-JS(B)") self.MixMode.setHeaderData(19 - 1, Qt.Horizontal, "膨胀剂用量") self.MixMode.setHeaderData(20 - 1, Qt.Horizontal, "质量密度 (容重)Mcp") self.MixMode.setHeaderData(21 - 1, Qt.Horizontal, "初凝时间") self.MixMode.setHeaderData(22 - 1, Qt.Horizontal, "终凝时间") self.MixMode.select() self.MixtableView.setModel(self.MixMode) self.MixtableView.setSelectionMode(QTableView.SingleSelection) self.MixtableView.setSelectionBehavior(QTableView.SelectRows) self.MixtableView.resizeColumnsToContents() if self.con2.isOpen(): self.con2.close()
class Filtrage_peche_dialog(QDialog, Ui_dlgPecheRechercheForm): ''' Class de la fenêtre permettant le filtrage attributaire des inventaires de reproduction :param QDialog: Permet d'afficher l'interface graphique comme une fenêtre indépendante :type QDialog: QDialog :param Ui_dlgPecheRechercheForm: Class du script de l'interface graphique du formulaire, apporte les éléments de l'interface :type Ui_dlgPecheRechercheForm: class ''' def __init__(self, db, dbType, dbSchema, modelPeche, parent=None): ''' Constructeur, récupération de variable, connection des événements et remplissage des combobox :param db: définie dans le setupModel(), représente la connexion avec la base de données :type db: QSqlDatabase :param dbType: type de la base de données (postgre) :type dbType: str :param dbSchema: nom du schéma sous PostgreSQL contenant les données (data) :type dbSchema: unicode :param modelPeche: modèle pêche qui contient les données de la base de données :type modelPeche: QSqlRelationalTableModel :param parent: défini que cette fenêtre n'hérite pas d'autres widgets :type parent: NoneType ''' super(Filtrage_peche_dialog, self).__init__(parent) self.db = db self.dbType = dbType self.dbSchema = dbSchema self.modelPeche = modelPeche self.setupUi(self) self.btnAnnuler.clicked.connect(self.reject) self.btnExec.clicked.connect(self.execution) self.btnRaz.clicked.connect(self.raz) self.btnEt.clicked.connect(self.et) self.btnOu.clicked.connect(self.ou) self.btnPrevisualiser.clicked.connect(self.previSql) self.btnCode.clicked.connect(self.ajoutCode) self.btnId.clicked.connect(self.ajoutId) self.btnPdpg.clicked.connect(self.ajoutPdpg) self.btnDate.clicked.connect(self.ajoutDate) self.btnRiviere.clicked.connect(self.ajoutRiviere) self.btnAappma.clicked.connect(self.ajoutAappma) self.btnMeau.clicked.connect(self.ajoutMeau) self.btnMotif.clicked.connect(self.ajoutMotif) self.btnEt.setEnabled(False) self.btnOu.setEnabled(False) self.aappmaBool = False self.motifBool = False self.pdpgBool = False self.ceauBool = False self.meauBool = False self.anneeBool = False self.wwhere = "" self.modelPdpg = QSqlTableModel(self, self.db) wrelation = "contexte_pdpg" if self.dbType == "postgres": wrelation = self.dbSchema + "." + wrelation self.modelPdpg.setTable(wrelation) self.modelPdpg.setSort(2, Qt.AscendingOrder) if (not self.modelPdpg.select()): QMessageBox.critical(self, u"Remplissage du modèle PDPG", self.modelPdpg.lastError().text(), QMessageBox.Ok) self.cmbPdpg.setModel(self.modelPdpg) self.cmbPdpg.setModelColumn(self.modelPdpg.fieldIndex("pdpg_nom")) self.modelAappma = QSqlTableModel(self, self.db) wrelation = "aappma" if self.dbType == "postgres": wrelation = self.dbSchema + "." + wrelation self.modelAappma.setTable(wrelation) self.modelAappma.setSort(1, Qt.AscendingOrder) if (not self.modelAappma.select()): QMessageBox.critical(self, u"Remplissage du modèle AAPPMA", self.modelAappma.lastError().text(), QMessageBox.Ok) self.cmbAappma.setModel(self.modelAappma) self.cmbAappma.setModelColumn(self.modelAappma.fieldIndex("apma_nom")) self.modelRiviere = QSqlTableModel(self, self.db) wrelation = "cours_eau" if self.dbType == "postgres": wrelation = self.dbSchema + "." + wrelation self.modelRiviere.setTable(wrelation) self.modelRiviere.setFilter("ceau_nom <> 'NR'") self.modelRiviere.setSort(2, Qt.AscendingOrder) if (not self.modelRiviere.select()): QMessageBox.critical(self, u"Remplissage du modèle Rivière", self.modelRiviere.lastError().text(), QMessageBox.Ok) self.cmbRiviere.setModel(self.modelRiviere) self.cmbRiviere.setModelColumn( self.modelRiviere.fieldIndex("ceau_nom")) self.modelMeau = QSqlQueryModel(self) wrelation = "masse_eau" if self.dbType == "postgres": wrelation = self.dbSchema + "." + wrelation self.modelMeau.setQuery( "select meau_code, meau_code || ' ; ' || meau_nom from " + wrelation + " order by meau_code;", self.db) if self.modelMeau.lastError().isValid(): QMessageBox.critical(self, u"Remplissage du modèle Masse d'eau", self.modelMeau.lastError().text(), QMessageBox.Ok) self.cmbMeau.setModel(self.modelMeau) self.cmbMeau.setModelColumn(1) self.ModelMotif = QSqlTableModel(self, self.db) wrelation = "motif_peche" if self.dbType == "postgres": wrelation = self.dbSchema + "." + wrelation self.ModelMotif.setTable(wrelation) self.ModelMotif.setSort(1, Qt.AscendingOrder) if (not self.ModelMotif.select()): QMessageBox.critical(self, u"Remplissage du modèle Motif", self.ModelMotif.lastError().text(), QMessageBox.Ok) self.cmbMotif.setModel(self.ModelMotif) self.cmbMotif.setModelColumn(self.ModelMotif.fieldIndex("mope_motif")) def reject(self): '''Ferme la fenêtre si clic sur le bouton annuler''' QDialog.reject(self) def raz(self): '''Réinitialise toutes les variables de la fenêtre afin de recommencer une nouvelle requête''' self.spnId.setValue(0) self.wrq = "" self.txtSql.setText("") self.wwhere = "" self.datePeche.setDate(QDate(2000, 1, 1)) self.btnEt.setEnabled(False) self.btnOu.setEnabled(False) self.btnCode.setEnabled(True) self.btnId.setEnabled(True) self.btnPdpg.setEnabled(True) self.btnDate.setEnabled(True) self.btnRiviere.setEnabled(True) self.btnAappma.setEnabled(True) self.btnMeau.setEnabled(True) self.btnMotif.setEnabled(True) self.aappmaBool = False self.motifBool = False self.pdpgBool = False self.ceauBool = False self.meauBool = False self.anneeBool = False def et(self): '''Change l'état des boutons et ajoute "and" à la requête''' self.btnEt.setEnabled(False) self.btnOu.setEnabled(False) self.btnCode.setEnabled(True) self.btnId.setEnabled(True) if self.aappmaBool == False: self.btnAappma.setEnabled(True) if self.motifBool == False: self.btnMotif.setEnabled(True) if self.pdpgBool == False: self.btnPdpg.setEnabled(True) if self.ceauBool == False: self.btnRiviere.setEnabled(True) if self.meauBool == False: self.btnMeau.setEnabled(True) if self.anneeBool == False: self.btnDate.setEnabled(True) self.wwhere += " AND " def ou(self): '''Change l'état des boutons et ajoute "or" à la requête''' self.btnEt.setEnabled(False) self.btnOu.setEnabled(False) self.btnCode.setEnabled(True) self.btnId.setEnabled(True) self.btnPdpg.setEnabled(True) self.btnDate.setEnabled(True) self.btnRiviere.setEnabled(True) self.btnAappma.setEnabled(True) self.btnMeau.setEnabled(True) self.btnMotif.setEnabled(True) self.aappmaBool = False self.motifBool = False self.pdpgBool = False self.ceauBool = False self.meauBool = False self.anneeBool = False self.wwhere += " OR " def ajoutCode(self): '''Change l'état des boutons et ajoute un critère de code opération à la requête''' self.btnOu.setEnabled(True) self.btnCode.setEnabled(False) self.btnId.setEnabled(False) self.btnPdpg.setEnabled(False) self.btnDate.setEnabled(False) self.btnRiviere.setEnabled(False) self.btnAappma.setEnabled(False) self.btnMeau.setEnabled(False) self.btnMotif.setEnabled(False) self.wcode = self.leCodeOpe.text() if self.leCodeOpe.text() != "": if self.wcode != "": self.wwhere += "opep_ope_code ilike '%" + self.wcode + "%'" self.leCodeOpe.setText("") self.leCodeOpe.setFocus() def ajoutId(self): '''Change l'état des boutons et ajoute un critère d'id à la requête''' self.btnOu.setEnabled(True) self.btnCode.setEnabled(False) self.btnId.setEnabled(False) self.btnPdpg.setEnabled(False) self.btnDate.setEnabled(False) self.btnRiviere.setEnabled(False) self.btnAappma.setEnabled(False) self.btnMeau.setEnabled(False) self.btnMotif.setEnabled(False) self.wid = self.spnId.value() if self.spnId.value() != "": if self.wid != "": self.wwhere += "opep_id = '" + str(self.wid) + "'" self.spnId.setValue(0) self.spnId.setFocus() def ajoutDate(self): '''Change l'état des boutons et ajoute un critère de date à la requête''' self.btnEt.setEnabled(True) self.btnOu.setEnabled(True) self.anneeBool = True self.btnCode.setEnabled(False) self.btnId.setEnabled(False) self.btnPdpg.setEnabled(False) self.btnDate.setEnabled(False) self.btnRiviere.setEnabled(False) self.btnAappma.setEnabled(False) self.btnMeau.setEnabled(False) self.btnMotif.setEnabled(False) self.wopep_date = self.datePeche.date().toString("yyyy") if self.wopep_date != "": self.wwhere += "date_part('year', opep_date) = '" + self.wopep_date + "'" def ajoutPdpg(self): '''Change l'état des boutons et ajoute un critère de pdpg à la requête''' self.btnEt.setEnabled(True) self.btnOu.setEnabled(True) self.btnCode.setEnabled(False) self.btnId.setEnabled(False) self.btnPdpg.setEnabled(False) self.btnDate.setEnabled(False) self.btnRiviere.setEnabled(False) self.btnAappma.setEnabled(False) self.btnMeau.setEnabled(False) self.btnMotif.setEnabled(False) self.pdpgBool = True wfromOperation = "operation" wfromStation = "station" wfromPeche = "ope_peche_elec" if self.dbType == "postgres": self.wfromPdpg = self.dbSchema + "." + wfromPeche + ", " + self.dbSchema + "." + wfromOperation + ", " + self.dbSchema + "." + wfromStation wrecord = self.cmbPdpg.model().record(self.cmbPdpg.currentIndex()) self.wsta_pdpg = wrecord.value(0) if self.cmbPdpg.currentText() != "": if self.wsta_pdpg != "": self.wwhere += " opep_id in (select distinct opep_id from " + self.wfromPdpg + " where (opep_ope_code = ope_code) and (ope_sta_id = sta_id) and sta_pdpg_id = '" + str( self.wsta_pdpg) + "')" def ajoutRiviere(self): '''Change l'état des boutons et ajoute un critère de cours d'eau à la requête''' self.btnEt.setEnabled(True) self.btnOu.setEnabled(True) self.btnCode.setEnabled(False) self.btnId.setEnabled(False) self.btnPdpg.setEnabled(False) self.btnDate.setEnabled(False) self.btnRiviere.setEnabled(False) self.btnAappma.setEnabled(False) self.btnMeau.setEnabled(False) self.btnMotif.setEnabled(False) self.ceauBool = True wfromOperation = "operation" wfromStation = "station" wfromPeche = "ope_peche_elec" if self.dbType == "postgres": self.wfromCeau = self.dbSchema + "." + wfromPeche + ", " + self.dbSchema + "." + wfromOperation + ", " + self.dbSchema + "." + wfromStation wrecord = self.cmbRiviere.model().record( self.cmbRiviere.currentIndex()) self.wsta_riviere = wrecord.value(0) if self.cmbRiviere.currentText() != "": if self.wsta_riviere != "": self.wwhere += " opep_id in (select distinct opep_id from " + self.wfromCeau + " where (opep_ope_code = ope_code) and (ope_sta_id = sta_id) and sta_ceau_id = '" + str( self.wsta_riviere) + "')" def ajoutAappma(self): '''Change l'état des boutons et ajoute un critère d'AAPPMA à la requête''' self.btnEt.setEnabled(True) self.btnOu.setEnabled(True) self.btnCode.setEnabled(False) self.btnId.setEnabled(False) self.btnPdpg.setEnabled(False) self.btnDate.setEnabled(False) self.btnRiviere.setEnabled(False) self.btnAappma.setEnabled(False) self.btnMeau.setEnabled(False) self.btnMotif.setEnabled(False) self.aappmaBool = True wfromOperation = "operation" wfromStation = "station" wfromPeche = "ope_peche_elec" if self.dbType == "postgres": self.wfromAappma = self.dbSchema + "." + wfromPeche + ", " + self.dbSchema + "." + wfromOperation + ", " + self.dbSchema + "." + wfromStation wrecord = self.cmbAappma.model().record(self.cmbAappma.currentIndex()) self.wsta_aappma = wrecord.value(0) if self.cmbAappma.currentText() != "": if self.wsta_aappma != "": self.wwhere += " opep_id in (select distinct opep_id from " + self.wfromAappma + " where (opep_ope_code = ope_code) and (ope_sta_id = sta_id) and sta_apma_id = '" + str( self.wsta_aappma) + "')" def ajoutMeau(self): '''Change l'état des boutons et ajoute un critère de Masse d'eau à la requête''' self.btnEt.setEnabled(True) self.btnOu.setEnabled(True) self.btnCode.setEnabled(False) self.btnId.setEnabled(False) self.btnPdpg.setEnabled(False) self.btnDate.setEnabled(False) self.btnRiviere.setEnabled(False) self.btnAappma.setEnabled(False) self.btnMeau.setEnabled(False) self.btnMotif.setEnabled(False) self.meauBool = True wfromOperation = "operation" wfromStation = "station" wfromPeche = "ope_peche_elec" if self.dbType == "postgres": self.wfromMeau = self.dbSchema + "." + wfromPeche + ", " + self.dbSchema + "." + wfromOperation + ", " + self.dbSchema + "." + wfromStation wrecord = self.cmbMeau.model().record(self.cmbMeau.currentIndex()) self.wsta_meau = wrecord.value(0) if self.cmbMeau.currentText() != "": if self.wsta_meau != "": self.wwhere += " opep_id in (select distinct opep_id from " + self.wfromMeau + " where (opep_ope_code = ope_code) and (ope_sta_id = sta_id) and sta_meau_code = '" + str( self.wsta_meau) + "')" def ajoutMotif(self): '''Change l'état des boutons et ajoute un critère de motif de pêche à la requête''' self.btnEt.setEnabled(True) self.btnOu.setEnabled(True) self.btnCode.setEnabled(False) self.btnId.setEnabled(False) self.btnPdpg.setEnabled(False) self.btnDate.setEnabled(False) self.btnRiviere.setEnabled(False) self.btnAappma.setEnabled(False) self.btnMeau.setEnabled(False) self.btnMotif.setEnabled(False) self.motifBool = True wrecord = self.cmbMotif.model().record(self.cmbMotif.currentIndex()) self.wopep_motif = wrecord.value(0) if self.cmbMotif.currentText() != "": if self.wopep_motif != "": self.wwhere += "opep_mope_id = '" + str(self.wopep_motif) + "'" def creaRequete(self): # def previSql(self): '''Regroupe les différentes variables contenant les clauses de la requête SQL et les concatène pour en faire une requête exécutable''' self.wrq = "" # Construit la clause FROM de la requête cfrom = "ope_peche_elec" if self.dbType == "postgres": cfrom = self.dbSchema + "." + cfrom # Construit la clause SELECT et ajoute la clause FROM à la requête self.wrq = "SELECT DISTINCT opep_id FROM " + cfrom # Construit la clause WHERE et ORDER BY et l'ajoute à la requête if self.wwhere != "": #Supprime l'opérateur "and" ou "or" si celui-ci n'est pas suivi d'un critère operateurs = ["AND", "OR"] fin_where = self.wwhere[-5:] for ext in operateurs: if ext in fin_where: self.wwhere = self.wwhere[:-4] self.wrq += " WHERE " + self.wwhere + " ORDER BY opep_id" else: self.wrq += " ORDER BY opep_id" def previSql(self): '''Permet de prévisualiser la requête avant de l'éxecuter''' self.txtSql.setText("") self.creaRequete() # Affiche la requête self.txtSql.setText(self.wrq) def execution(self): '''Permet d'éxecuter la requête''' # Vérifie la non présence de mot pouvant endommager la base de données erreur = False interdit = [ "update", "delete", "insert", "intersect", "duplicate", "merge", "truncate", "create", "drop", "alter" ] if self.txtSql.toPlainText() != "": self.requete = self.txtSql.toPlainText() else: self.creaRequete() self.requete = self.wrq testRequete = self.requete.lower() for mot in interdit: if mot in testRequete: erreur = True if erreur == True: QMessageBox.critical( self, u"Erreur SQL", u"Vous essayez d'exécuter une requête qui peut endommager la base de données !", QMessageBox.Ok) # Après récupération du contenu de la zone de texte, exécute la requête else: query = QSqlQuery(self.db) query.prepare(self.requete) if query.exec_(): wparam = "" while query.next(): wparam += str(query.value(0)) + "," if (wparam != ""): wparam = "(" + wparam[0:len(wparam) - 1] + ")" if self.modelPeche: # Filtre le modèle des inventaires de reproduction et ferme la fenêtre self.modelPeche.setFilter("opep_id in %s" % wparam) self.modelPeche.select() QDialog.accept(self) else: QMessageBox.information( self, "Filtrage", u"Aucun pêche électrique ne correspond aux critères ...", QMessageBox.Ok) else: QMessageBox.critical(self, u"Erreur SQL", query.lastError().text(), QMessageBox.Ok)
class FilteringComboBox(Widget): """Combination of QCombobox and QLineEdit with autocompletionself. Line edit and completer model is taken from QSqlTable mod Parameters: table (str): db table name containing data for combobox column (str): column name containing data for combobox color (str): 'rgb(r, g, b)' used for primary color font_size (int): default text font size in pt _model (QSqlTableModel): data model _col (int): display data model source coulumn _proxy (QSortFilterProxyModel): completer data model. _proxy.sourceModel() == _model _le (QLineEdit): QCombobox LineEdit Methods: createEditor(): (Widget): returns user input widgets value(): (str): returns user input text value setValue(value(str)): sets editor widget display value style(): (str): Returns CSS stylesheet string for input widget updateModel(): updates input widget model Args: table (str): db table name containing data for combobox column (str): column name containing data for combobox """ def __init__(self, parent, placeholderText, table, column, color='rgb(0,145,234)', image=''): self.table = table self.column = column self.color = color super().__init__(parent, placeholderText, image) self.updateModel() def createEditor(self): # setup data model self._model = QSqlTableModel() self._model.setTable(self.table) self._col = self._model.fieldIndex(self.column) # setup filter model for sorting and filtering self._proxy = QSortFilterProxyModel() self._proxy.setFilterCaseSensitivity(Qt.CaseInsensitive) self._proxy.setSourceModel(self._model) self._proxy.setFilterKeyColumn(self._col) # setup completer self._completer = QCompleter() self._completer.setModel(self._proxy) self._completer.setCompletionColumn(self._col) self._completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion) # setup combobox editor = QComboBox() editor.setModel(self._proxy) editor.setModelColumn(self._col) editor.setEditable(True) editor.setFocusPolicy(Qt.StrongFocus) editor.setInsertPolicy(QComboBox.NoInsert) editor.setCompleter(self._completer) # setup connections editor.currentTextChanged[str].connect(self.onActivated) # setup editor appearence style = self.style() editor.setStyleSheet(style) editor.lineEdit().setStyleSheet(style) font = editor.font() self._completer.popup().setFont(font) return editor @pyqtSlot(str) def onActivated(self, text): print('combo_box filter text', text) if not text: # placeholder text displayed and label is not visible self._editor.setCurrentIndex(-1) if self.toggle: self._label.showLabel(False) else: # selected text is displayed and label is visible # self._editor.showPopup() # self._editor.lineEdit().setFocus() print('current copmpletion string', self._completer.currentCompletion()) self._proxy.setFilterFixedString(text) if self.toggle: self._label.showLabel(True) def style(self): """Returns stylesheet for editors Returns: style (str) """ style = """ QLineEdit {{ border: none; padding-bottom: 2px; border-bottom: 1px solid rgba(0,0,0,0.42); background-color: white; color: rgba(0,0,0,0.42); font-size: {font_size}pt;}} QLineEdit:editable {{ padding-bottom: 2px; border-bottom: 1px rgba(0,0,0,0.42); color: rgba(0,0,0,0.42);}} QLineEdit:disabled {{ border: none; padding-bottom: 2px; border-bottom: 1px rgba(0,0,0,0.42); color: rgba(0,0,0,0.38);}} QLineEdit:hover {{ padding-bottom: 2px; border-bottom: 2px solid rgba(0,0,0,0.6); color: rgba(0,0,0,0.54); }} QLineEdit:focus {{ padding-bottom: 2px; border-bottom: 2px solid {color}; color: rgba(0,0,0,0.87);}} QLineEdit:pressed {{ border-bottom: 2px {color}; font: bold; color: rgba(0,0,0,0.87)}} QComboBox {{ border: none; padding-bottom: 2px; font-size: {font_size}pt; }} QComboBox::down-arrow {{ image: url('dropdown.png'); background-color: white; border: 0px white; padding: 0px; margin: 0px; height:14px; width:14px;}} QComboBox::drop-down{{ subcontrol-position: center right; border: 0px; margin: 0px; }} QComboBox QAbstractItemView {{ font: {font_size};}} """.format(color=self.color, font_size=self._editor_font_size, dropdown=DROPDOWN_PNG) return style def updateModel(self): model = self._editor.model().sourceModel() col = self._editor.modelColumn() model.select() model.sort(col, Qt.AscendingOrder) def value(self): return self._editor.currentText() def setValue(self, value): self._editor.setCurrentText(value)
class SqliteDbTableEditer(QWidget): #Db=sqlite3.connect("test.db") def __init__(self,dbPath,tblName='',parent=None): self.app=QApplication(sys.argv) self.SqliteDbTypes=['integer','real','text','blob'] self.DbPath,self.CurrentTable=dbPath,tblName #连接数据库 self.Db=sqlite3.connect(self.DbPath) #构建Gui组件 super(SqliteDbTableEditer,self).__init__(parent) self.setWindowTitle('Sqlite数据库表修改器') screen=QDesktopWidget().availableGeometry(0) self.setGeometry(screen.width()/3/2-1, screen.height()/5/2-1, screen.width()*2/3, screen.height()*4/5 ) #lay lay=QVBoxLayout() self.setLayout(lay) #数据库表设置控件 ##layDb layDb=QHBoxLayout() lay.addLayout(layDb) ###lblDb lblDb=QLabel('数据库:') layDb.addWidget(lblDb) ###self.leDb self.leDb=QLineEdit() self.leDb.setText(self.DbPath) layDb.addWidget(self.leDb) ###btnDb btnChangeDb=QPushButton('浏览') btnChangeDb.clicked.connect(self.btnChangeDb_Clicked) layDb.addWidget(btnChangeDb) ###lblTbl lblTbl=QLabel('数据表:') layDb.addWidget(lblTbl) ###self.cbbTbls self.cbbTbls=QComboBox() tbls=list(map(lambda x:x[1], list(filter(lambda x:x[0]=='table', self.Db.execute( 'Select * From sqlite_master' ).fetchall() ) ) ) ) self.cbbTbls.addItems(tbls) if self.CurrentTable!='' : self.cbbTbls.setCurrentIndex(tbls.index(self.CurrentTable)) else: self.CurrentTable=tbls[0] self.makeTableInfo() self.cbbTbls.setCurrentIndex(0) layDb.addWidget(self.cbbTbls) ###lblRename lblRename=QLabel('重命名为:') layDb.addWidget(lblRename) ###self.leRename self.leRename=QLineEdit() self.leRename.setFixedWidth(100) layDb.addWidget(self.leRename) ###btnRename btnRenameTable=QPushButton('重命名') btnRenameTable.clicked.connect(self.btnRenameTable_Clicked) layDb.addWidget(btnRenameTable) ###btnDeleteTable btnDeleteTable=QPushButton('删除表') btnDeleteTable.clicked.connect(self.btnDeleteTable_Clicked) layDb.addWidget(btnDeleteTable) ###btnShow self.btnShow=QPushButton('查看表结构') self.btnShow.clicked.connect(self.btnShow_Clicked) layDb.addWidget(self.btnShow) ###设置TableView控件self.tv,以呈现表数据 self.tv=QTableView() lay.addWidget(self.tv) ###self.model基本初始化 self.model=QSqlTableModel(self,QSqlDatabase.addDatabase('QSQLITE')) self.model.setEditStrategy(QSqlTableModel.OnFieldChange) ###self.tv链接到数据源 self.tv.setModel(self.model) ###self.model数据初始化 self.model.database().setDatabaseName(self.DbPath) self.model.database().open() self.model.setTable(self.CurrentTable) self.model.select() self.cbbTbls.currentIndexChanged.connect(self.changeTable) ##layBtns layBtns=QHBoxLayout() lay.addLayout(layBtns) ###btnAddColumn btnAddColumn=QPushButton('添加列') btnAddColumn.setToolTip('给当前表添加列') btnAddColumn.clicked.connect(self.btnAddColumn_Clicked) layBtns.addWidget(btnAddColumn) ###btnDeleteColumn btnDeleteColumn=QPushButton('删除列') btnDeleteColumn.setToolTip('删除当前表的列') btnDeleteColumn.clicked.connect(self.btnDeleteColumn_Clicked) layBtns.addWidget(btnDeleteColumn) ###btnRenameColumn btnRenameColumn=QPushButton('重命名列') btnRenameColumn.setToolTip('重命名当前表的列') btnRenameColumn.clicked.connect(self.btnRenameColumn_Clicked) layBtns.addWidget(btnRenameColumn) ###btnModifyColumnType btnModifyColumnType=QPushButton('修改列数据类型') btnModifyColumnType.setToolTip('修改当前表的列的数据类型') btnModifyColumnType.clicked.connect(self.btnModifyColumnType_Clicked) layBtns.addWidget(btnModifyColumnType) ###btnModifyColumnConstraint btnModifyColumnConstraint=QPushButton('修改列约束') btnModifyColumnConstraint.setToolTip('修改当前表的列的约束') btnModifyColumnConstraint.clicked.connect( self.btnModifyColumnConstraint_Clicked) layBtns.addWidget(btnModifyColumnConstraint) ###btnOrderColumns btnOrderColumns=QPushButton('调整列顺序') btnOrderColumns.setToolTip('调整当前表的列的顺序') btnOrderColumns.clicked.connect(self.btnOrderColumns_Clicked) layBtns.addWidget(btnOrderColumns) ###btnModifyTableStruct btnModifyTableStruct=QPushButton('修改表结构') btnModifyTableStruct.setToolTip('功能:1.增加列;2.删除列;' +'3.修改列名;4.修改列类型;' +'5.修改列约束;6.调整列顺序' ) btnModifyTableStruct.clicked.connect(self.btnModifyTableStruct_Clicked) layBtns.addWidget(btnModifyTableStruct) ###btnInsertRow btnInsertRow=QPushButton('插入行') btnInsertRow.setToolTip('将在数据表最后增加一行新记录') btnInsertRow.clicked.connect(self.btnInsertRow_Clicked) layBtns.addWidget(btnInsertRow) ###btnDeleteRows btnDeleteRows=QPushButton('删除行') btnDeleteRows.setToolTip('删除所有选中项所在的行') btnDeleteRows.clicked.connect(self.btnDeleteRows_Clicked) layBtns.addWidget(btnDeleteRows) ###btnQuery btnQuery=QPushButton('查询数据') btnQuery.setToolTip('对当前表或数据库进行查询,查询语句将被直接链接到self.model上') btnQuery.clicked.connect(self.btnQuery_Clicked) layBtns.addWidget(btnQuery) self.show() self.app.exec_() def __del__(self): #销毁多余数据库连接 #self.Db.commit() self.Db.close() #---------------------------------------------------------------- def makeTableInfo(self): #table_info=self.Db.execute('pragma table_info(%s)'%self.CurrentTable).fetchall() paragmastr="pragma table_info( '" + self.CurrentTable + "' ) " table_info=self.Db.execute(paragmastr).fetchall() self.columnsCount=len(table_info) self.columnsName=list(map(lambda x:x[1],table_info)) self.columnsType=list(map(lambda x:x[2],table_info)) dbinfo=self.Db.execute('select * from sqlite_master').fetchall() for x in dbinfo: if x[0]=='table' and x[1]==self.CurrentTable: self.sqlStr=x[4] break def DeleteColumn(self,tableName,columnName,tempName=''): if tempName=='': #tempName==''表示直接删除对应的列并提交数据库更改 tempName=tableName+'temp' sqlite_master_sql="select * from sqlite_master" sqlite_master=self.Db.execute(sqlite_master_sql).fetchall() createStr=filter(lambda x:x[0]=='table' and x[1]==tableName, self.Db.execute('select * from sqlite_master').fetchall())[0][4] createStr=','.join(filter(lambda x:x.find(columnName)==-1,createStr.split(','))) newColumns=','.join(map(lambda x:x[1],self.Db.execute('Pragma table_info(%s)'%tableName).fetchall())) #将旧表重命名为临时表名 self.Db.execute("Alter Table %s Rename To %s"%(tableName,tempName)) #新建删除了指定列的数据表 self.Db.execute(createStr) #将旧表的数据导入新表 self.Db.execute('Insert Into %s Select %s From %s'% (tableName,newColumns,tempName)) #删除旧表 self.Db.execute('Drop Table %s'%tempName) #---------------------------------------------------------------- def btnChangeDb_Clicked(self,event): pt=QFileDialog.getOpenFileName( caption='请选择一个sqlite数据库文件:', filter='sqlite数据库文件 (*.db)', directory=os.path.dirname(self.DbPath) ) p=pt[0] if platform.system()=='Windows': p=p.replace('/','\\') if os.path.exists(p): self.DbPath=p self.Db=sqlite3.connect(self.DbPath) tbls=map(lambda x:x[1], filter(lambda x:x[0]=='table', self.Db.execute( 'Select * From sqlite_master' ).fetchall() ) ) self.cbbTbls.currentIndexChanged.disconnect(self.changeTable) self.cbbTbls.clear() self.cbbTbls.addItems(tbls) self.cbbTbls.currentIndexChanged.connect(self.changeTable) self.CurrentTable=tbls[0] self.cbbTbls.setCurrentIndex(0) self.leDb.setText(p) self.model.database().setDatabaseName(self.DbPath) self.model.database().open() self.model.setTable(self.CurrentTable) self.model.select() def changeTable(self,event): if self.CurrentTable!=self.cbbTbls.itemText(event): self.CurrentTable=self.cbbTbls.itemText(event) self.model.setTable(self.CurrentTable) self.model.select() self.makeTableInfo() self.btnShow.setText('查看表结构') def btnDeleteTable_Clicked(self,event): self.Db.execute('Drop Table %s'%self.CurrentTable) for i in range(self.cbbTbls.count()-1,-1,-1): if self.cbbTbls.itemText(i)==self.CurrentTable: self.cbbTbls.removeItem(i) break self.CurrentTable=self.cbbTbls.itemText(0) self.model.setTable(self.CurrentTable) self.model.select() def btnRenameTable_Clicked(self,event): if self.leRename.text()!='': if self.leRename.text()!=self.CurrentTable: try: self.Db.execute('Alter Table %s Rename To %s'% (self.CurrentTable,self.leRename.text()) ) except sqlite3.OperationalError as e: if e.message=='there is already another table or index with this name: %s'%self.leRename.text(): QMessageBox.information(self,'错误', '抱歉,本数据库中以“'+self.leRename.text()+ '”为名称的表或索引已经存在,无法完'+ '成重命名,请重新输入一个名称', '知道了') else: QMessageBox.information(self,'错误', '抱歉,可能是因表名包含非法字符,故'+ '无法完成重命名,请重新输入表名', '知道了') self.leRename.setText('') return self.CurrentTable=self.leRename.text() self.cbbTbls.setItemText(self.cbbTbls.currentIndex(), self.CurrentTable ) self.model.clear() self.model.setQuery(QSqlQuery( 'Select * From %s'%self.CurrentTable)) self.model.select() self.leRename.setText('') else: QMessageBox.information(self,'注意', '抱歉,你还没有输入当前表要修改成的表名\n\n'+ '请先在文本框里输入当前表要重命名成的名字,再点击我', '知道了') def btnShow_Clicked(self,event): if self.btnShow.text()=='查看表结构': self.model.setTable('') self.model.setQuery(QSqlQuery( 'pragma table_info(%s)'%self.CurrentTable)) self.model.select() self.btnShow.setText('查看表数据') else: self.model.setTable(self.CurrentTable) self.model.select() self.btnShow.setText('查看表结构') #---------------------------------------------------------------- def btnInsertRow_Clicked(self,event): self.dlg_InsertRow_Values=[] #self.dlg self.dlg=QDialog() self.dlg.setWindowTitle('插入数据行:') #lay lay=QVBoxLayout() self.dlg.setLayout(lay) #lblprompt lblprompt=QLabel( '请参照创建此表的Sql字符串:\n'+self.sqlStr+ '\n设置各个字段的数据:') lay.addWidget(lblprompt) #layG layG=QGridLayout() lay.addLayout(layG) for i in range(len(self.columnsName)): #lbl lbl=QLabel(self.columnsName[i]+'('+self.columnsType[i]+'):') lbl.setAlignment(Qt.AlignRight) layG.addWidget(lbl,i,0) #le le=QLineEdit() layG.addWidget(le,i,1) if self.columnsType[i].lower() not in self.SqliteDbTypes: #cbb cbb=QComboBox() cbb.addItems(self.SqliteDbTypes) cbb.setCurrentIndex(2) cbb.setToolTip( '此字段的数据类型不是sqlite标准数据'+ '类型,请设置其存储时的使用的sqlite数据类型') layG.addWidget(cbb,i,2) self.dlg_InsertRow_Values.append((le,cbb)) else: self.dlg_InsertRow_Values.append((le,self.columnsType[i])) layG.setColumnStretch(1,1) #layH layH=QHBoxLayout() lay.addLayout(layH) #btnOk btnOk=QPushButton('确定') btnOk.clicked.connect(self.dlg_InsertRow_btnOk_Clicked) layH.addWidget(btnOk) #btnCancel btnCancel=QPushButton('取消') btnCancel.clicked.connect(self.dlg.close) layH.addWidget(btnCancel) self.dlg.show() def dlg_InsertRow_btnOk_Clicked(self,event): sqlStr="Insert Into %s Values("%self.CurrentTable for item in self.dlg_InsertRow_Values: if item[0].text()!='': if type(item[1])==QComboBox: print (item[0].text(),item[1].currentText()) else: print (item[0].text(),item[1]) else: pass def btnDeleteRows_Clicked(self,event): rs=list(map(lambda x:x.row(),self.tv.selectedIndexes())) if len(rs)==0: QMessageBox.information(self,'提醒','请先选中至少一行,再点击此按钮!') return for i in reversed(rs): self.model.removeRows(i,1) self.model.submitAll() def btnQuery_Clicked(self,event): sqltxt,ok=QInputDialog.getText(self,'查询语句设置', '参照创建此表的Sql字符串:\n'+self.sqlStr+ '\n请输入要设置到self.model的查询语句:') if ok: self.model.setTable('') self.model.setQuery(QSqlQuery(sqltxt)) self.model.select() #---------------------------------------------------------------- def btnAddColumn_Clicked(self,event): self.dlgMake_AddColumn() def dlgMake_AddColumn(self,lay=None): if lay is None: self.dlg=QDialog(self) self.dlg.setWindowTitle('添加列:') else: ##self.grpAddColumn self.grpAddColumn=QGroupBox('添加列:') self.grpAddColumn.setCheckable(True) self.grpAddColumn.setChecked(True) lay.addWidget(self.grpAddColumn) ###layAddColumn layAddColumn=QVBoxLayout() if lay is None: self.dlg.setLayout(layAddColumn) else: self.grpAddColumn.setLayout(layAddColumn) ####self.grpAddColumn_ByCmdArgs self.grpAddColumn_ByCmdArgs=QGroupBox('使用参数创建列:') self.grpAddColumn_ByCmdArgs.setCheckable(True) self.grpAddColumn_ByCmdArgs.setChecked(True) self.PreviousChecked=0 self.grpAddColumn_ByCmdArgs.toggled.connect( self.grpAddColumn_ByCmd_toggled) layAddColumn.addWidget(self.grpAddColumn_ByCmdArgs) #####layAddColumn_ByCmdArgs layAddColumn_ByCmdArgs=QHBoxLayout() self.grpAddColumn_ByCmdArgs.setLayout(layAddColumn_ByCmdArgs) ####lblAddColumn_select lblAddColumn_name=QLabel('列名:') layAddColumn_ByCmdArgs.addWidget(lblAddColumn_name) ####self.leAddColumn_name self.leAddColumn_name=QLineEdit() self.leAddColumn_name.setFixedWidth(100) layAddColumn_ByCmdArgs.addWidget(self.leAddColumn_name) ######lblAddColumn_type lblAddColumn_type=QLabel('类型:') layAddColumn_ByCmdArgs.addWidget(lblAddColumn_type) ######self.cbbAddColumn_type self.cbbAddColumn_type=QComboBox() self.cbbAddColumn_type.addItems(self.SqliteDbTypes) self.cbbAddColumn_type.setCurrentIndex(0) self.cbbAddColumn_type.setEditable(True) layAddColumn_ByCmdArgs.addWidget(self.cbbAddColumn_type) ######lblAddColumn_constraint lblAddColumn_constraint=QLabel('约束字符串:') layAddColumn_ByCmdArgs.addWidget(lblAddColumn_constraint) ######self.leAddColumn_constraint self.leAddColumn_constraint=QLineEdit() layAddColumn_ByCmdArgs.addWidget(self.leAddColumn_constraint) ####self.grpAddColumn_ByCmdStr self.grpAddColumn_ByCmdStr=QGroupBox('使用sql字符串创建列:') self.grpAddColumn_ByCmdStr.setCheckable(True) self.grpAddColumn_ByCmdStr.setChecked(False) self.grpAddColumn_ByCmdStr.toggled.connect( self.grpAddColumn_ByCmd_toggled) layAddColumn.addWidget(self.grpAddColumn_ByCmdStr) #####layAddColumn_ByCmdStr layAddColumn_ByCmdStr=QHBoxLayout() self.grpAddColumn_ByCmdStr.setLayout(layAddColumn_ByCmdStr) ######lblAddColumn_cmdstr lblAddColumn_cmdstr=QLabel('用来增加列的部分或完整Sql字符串:') layAddColumn_ByCmdStr.addWidget(lblAddColumn_cmdstr) ######self.leAddColumn_cmdstr self.leAddColumn_cmdstr=QLineEdit() layAddColumn_ByCmdStr.addWidget(self.leAddColumn_cmdstr) if lay is None: self.dlg.show() def grpAddColumn_ByCmd_toggled(self,event): if self.PreviousChecked==0: self.grpAddColumn_ByCmdStr.setChecked(True) self.grpAddColumn_ByCmdArgs.setChecked(False) self.PreviousChecked=1 else: self.grpAddColumn_ByCmdArgs.setChecked(True) self.grpAddColumn_ByCmdStr.setChecked(False) self.PreviousChecked=0 #---------------------------------------------------------------- def btnDeleteColumn_Clicked(self,event): self.dlgMake_DeleteColumn() def dlgMake_DeleteColumn(self,lay=None): if lay is None: self.dlg=QDialog(self) self.dlg.setWindowTitle('删除列:') else: ##self.grpDeleteColumn self.grpDeleteColumn=QGroupBox('删除列:') self.grpDeleteColumn.setCheckable(True) self.grpDeleteColumn.setChecked(False) lay.addWidget(self.grpDeleteColumn) ###layDeleteColumn layDeleteColumn=QHBoxLayout() if lay is None: self.dlg.setLayout(layDeleteColumn) else: self.grpDeleteColumn.setLayout(layDeleteColumn) ###layColumnList layColumnList=QVBoxLayout() layDeleteColumn.addLayout(layColumnList) ####lblDeleteColumn lblDeleteColumn=QLabel('原有的所有列:') layColumnList.addWidget(lblDeleteColumn) ####self.lstColumnList self.lstColumnList=QListWidget() self.lstColumnList.addItems(self.columnsName) self.lstColumnList.setFixedWidth(150) layColumnList.addWidget(self.lstColumnList) ###layDeleteBtns layDeleteBtns=QVBoxLayout() layDeleteColumn.addLayout(layDeleteBtns) ####btnDeleteColumn_Store btnDeleteColumn_Store=QPushButton('>>') btnDeleteColumn_Store.setFixedWidth(50) layDeleteBtns.addWidget(btnDeleteColumn_Store) ####btnDeleteColumn_Unstore btnDeleteColumn_Unstore=QPushButton('<<') btnDeleteColumn_Unstore.setFixedWidth(50) layDeleteBtns.addWidget(btnDeleteColumn_Unstore) ###layColumnsToDelete layColumnsToDelete=QVBoxLayout() layDeleteColumn.addLayout(layColumnsToDelete) ####lblColumnsToDelete lblColumnsToDelete=QLabel('要删除的列:') layColumnsToDelete.addWidget(lblColumnsToDelete) ####self.lstColumnsToDelete self.lstColumnsToDelete=QListWidget() self.lstColumnsToDelete.setFixedWidth(150) layColumnsToDelete.addWidget(self.lstColumnsToDelete) if lay is None: self.dlg.show() #---------------------------------------------------------------- def btnRenameColumn_Clicked(self,event): self.dlgMake_RenameColumn() def dlgMake_RenameColumn(self,lay=None): if lay is None: self.dlg=QDialog(self) self.dlg.setWindowTitle('重命名列:') else: ##self.grpRenameColumn self.grpRenameColumn=QGroupBox('重命名列:') self.grpRenameColumn.setCheckable(True) self.grpRenameColumn.setChecked(False) lay.addWidget(self.grpRenameColumn) ###layRenameColumn layRenameColumn=QHBoxLayout() if lay is None: self.dlg.setLayout(layRenameColumn) else: self.grpRenameColumn.setLayout(layRenameColumn) ####lblRenameColumn_select lblRenameColumn_select=QLabel('选择列:') layRenameColumn.addWidget(lblRenameColumn_select) ####self.cbbRenameColumn_select self.cbbRenameColumn_select=QComboBox() self.cbbRenameColumn_select.addItems(self.columnsName) layRenameColumn.addWidget(self.cbbRenameColumn_select) ####lblRenameColumn_renameto lblRenameColumn_renameto=QLabel('重命名为:') layRenameColumn.addWidget(lblRenameColumn_renameto) ####self.leRenameColumn_renameto self.leRenameColumn_renameto=QLineEdit() self.leRenameColumn_renameto.setFixedWidth(80) layRenameColumn.addWidget(self.leRenameColumn_renameto) ####btnRenameColumn_Store btnRenameColumn_Store=QPushButton('标记 >>') layRenameColumn.addWidget(btnRenameColumn_Store) ####self.cbbRenameColumn_Store self.cbbRenameColumn_Store=QComboBox() layRenameColumn.addWidget(self.cbbRenameColumn_Store,1) if lay is None: self.dlg.show() #---------------------------------------------------------------- def btnModifyColumnType_Clicked(self,event): self.dlgMake_ModifyColumnType() def dlgMake_ModifyColumnType(self,lay=None): if lay is None: self.dlg=QDialog(self) self.dlg.setWindowTitle('修改列数据类型:') else: ##self.grpModifyColumnType self.grpModifyColumnType=QGroupBox('修改列数据类型:') self.grpModifyColumnType.setCheckable(True) self.grpModifyColumnType.setChecked(False) lay.addWidget(self.grpModifyColumnType) ###layModifyColumnType layModifyColumnType=QHBoxLayout() if lay is None: self.dlg.setLayout(layModifyColumnType) else: self.grpModifyColumnType.setLayout(layModifyColumnType) ####lblModifyColumnType_select lblModifyColumnType_select=QLabel('选择列:') layModifyColumnType.addWidget(lblModifyColumnType_select) ####self.cbbModifyColumnType_select self.cbbModifyColumnType_select=QComboBox() self.cbbModifyColumnType_select.addItems(self.columnsName) layModifyColumnType.addWidget(self.cbbModifyColumnType_select) ####lblModifyColumnType_modifyto lblModifyColumnType_modifyto=QLabel('改类型为:') layModifyColumnType.addWidget(lblModifyColumnType_modifyto) ####self.cbbModifyColumnType_modifyto self.cbbModifyColumnType_modifyto=QComboBox() self.cbbModifyColumnType_modifyto.setEditable(True) self.cbbModifyColumnType_modifyto.addItems(self.SqliteDbTypes) self.cbbModifyColumnType_modifyto.setCurrentIndex(2) self.cbbModifyColumnType_modifyto.setFixedWidth(80) layModifyColumnType.addWidget(self.cbbModifyColumnType_modifyto) ####btnModifyColumnType_Store btnModifyColumnType_Store=QPushButton('标记 >>') layModifyColumnType.addWidget(btnModifyColumnType_Store) ####self.cbbModifyColumnType_Store self.cbbModifyColumnType_Store=QComboBox() layModifyColumnType.addWidget(self.cbbModifyColumnType_Store,1) if lay is None: self.dlg.show() #---------------------------------------------------------------- def btnModifyColumnConstraint_Clicked(self,event): self.dlgMake_ModifyColumnConstraint() def dlgMake_ModifyColumnConstraint(self,lay=None): if lay is None: self.dlg=QDialog(self) self.dlg.setWindowTitle('修改列约束:') else: ##self.grpModifyColumnConstraint self.grpModifyColumnConstraint=QGroupBox('修改列约束:') self.grpModifyColumnConstraint.setCheckable(True) self.grpModifyColumnConstraint.setChecked(False) lay.addWidget(self.grpModifyColumnConstraint) ###layModifyColumnConstraint layModifyColumnConstraint=QHBoxLayout() if lay is None: self.dlg.setLayout(layModifyColumnConstraint) else: self.grpModifyColumnConstraint.setLayout(layModifyColumnConstraint) ####lblModifyColumnConstraint_select lblModifyColumnConstraint_select=QLabel('选择列:') layModifyColumnConstraint.addWidget(lblModifyColumnConstraint_select) ####self.cbbModifyColumnConstraint_select self.cbbModifyColumnConstraint_select=QComboBox() self.cbbModifyColumnConstraint_select.addItems(self.columnsName) layModifyColumnConstraint.addWidget(self.cbbModifyColumnConstraint_select) ####lblModifyColumnConstraint_modifyto lblModifyColumnConstraint_modifyto=QLabel('约束改为:') layModifyColumnConstraint.addWidget(lblModifyColumnConstraint_modifyto) ####self.leModifyColumnConstraint_modifyto self.leModifyColumnConstraint_modifyto=QLineEdit() self.leModifyColumnConstraint_modifyto.setFixedWidth(80) layModifyColumnConstraint.addWidget(self.leModifyColumnConstraint_modifyto) ####btnModifyColumnConstraint_Store btnModifyColumnConstraint_Store=QPushButton('标记 >>') layModifyColumnConstraint.addWidget(btnModifyColumnConstraint_Store) ####self.cbbModifyColumnConstraint_Store self.cbbModifyColumnConstraint_Store=QComboBox() layModifyColumnConstraint.addWidget(self.cbbModifyColumnConstraint_Store,1) if lay is None: self.dlg.show() #---------------------------------------------------------------- def btnOrderColumns_Clicked(self,event): self.dlgMake_OrderColumns() def dlgMake_OrderColumns(self,lay=None): if lay is None: self.dlg=QDialog(self) self.dlg.setWindowTitle('调整列顺序:') else: ##self.grpAdjustColumnOrder self.grpAdjustColumnOrder=QGroupBox('调整列顺序:') self.grpAdjustColumnOrder.setCheckable(True) self.grpAdjustColumnOrder.setChecked(False) lay.addWidget(self.grpAdjustColumnOrder) ###layAdjustColumnOrder layAdjustColumnOrder=QVBoxLayout() if lay is None: self.dlg.setLayout(layAdjustColumnOrder) else: self.grpAdjustColumnOrder.setLayout(layAdjustColumnOrder) ####lblAdjustColumnOrder lblAdjustColumnOrder=QLabel('请调整列顺序:') layAdjustColumnOrder.addWidget(lblAdjustColumnOrder) ####self.lstAdjustColumnOrder self.lstAdjustColumnOrder=QListWidget() self.lstAdjustColumnOrder.addItems(self.columnsName) self.lstAdjustColumnOrder.setFixedWidth(150) layAdjustColumnOrder.addWidget(self.lstAdjustColumnOrder) if lay is None: self.dlg.setFixedWidth(175) self.dlg.show() #---------------------------------------------------------------- def btnModifyTableStruct_Clicked(self,event): self.dlg=QDialog(self) self.dlg.setWindowTitle(self.CurrentTable+'表结构修改:') self.dlg.setWindowFlags(Qt.Window| Qt.MSWindowsFixedSizeDialogHint ) #lay lay=QVBoxLayout() self.dlgMake_AddColumn(lay) self.dlgMake_RenameColumn(lay) self.dlgMake_ModifyColumnType(lay) self.dlgMake_ModifyColumnConstraint(lay) #layLists layLists=QHBoxLayout() lay.addLayout(layLists) self.dlgMake_DeleteColumn(layLists) self.dlgMake_OrderColumns(layLists) ##layBtns layBtns=QHBoxLayout() lay.addLayout(layBtns) ##btnOk btnOk=QPushButton('提交修改') btnOk.clicked.connect(self.btnOk_Clicked) layBtns.addWidget(btnOk) ##btnCancel btnCancel=QPushButton('放弃修改') btnCancel.clicked.connect(self.btnCancel_Clicked) layBtns.addWidget(btnCancel) self.dlg.setLayout(lay) self.dlg.open() def btnOk_Clicked(self,event): #do something here self.dlg.close() def btnCancel_Clicked(self,event): self.dlg.close()
# чтобы убрать пустую "мусорную" запись MODEL.select() APP = QApplication(sys.argv) W_OBJ = QWidget() W_OBJ.setWindowTitle("Модель-таблица") # Устанавливаем соединение с базой данных CONN = QSqlDatabase.addDatabase('QSQLITE') CONN.setDatabaseName('test.sqlite3') CONN.open() # Создаем модель MODEL = QSqlTableModel(parent=W_OBJ) MODEL.setTable('vendors') MODEL.setSort(1, QtCore.Qt.AscendingOrder) MODEL.select() # Задаем заголовки для столбцов модели MODEL.setHeaderData(1, QtCore.Qt.Horizontal, 'Название') MODEL.setHeaderData(2, QtCore.Qt.Horizontal, 'Телефон') MODEL.setHeaderData(3, QtCore.Qt.Horizontal, 'Адрес') # Задаем для таблицы только что созданную модель VBOX_OBJ = QVBoxLayout() TV_OBJ = QTableView() TV_OBJ.setModel(MODEL) # Скрываем первый столбец, в котором выводится идентификатор
class MainWindow(QMainWindow): # 继承主窗口函数的类, 继承编写的主函数 def __init__(self, parent=None): super().__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) # 初始化运行A窗口类下的 setupUi 函数 self.open_alltable() self.enterList = {} self.outList = {} self.name_RFID = { '直齿轮': '01B0E00000020010B1', '斜齿轮': '01B0E00000030010B2', '齿轮轴': '01A0E00000010010A1', '光轴': '01A0E00000010010A2', '曲柄': '01C0E00000020010C1', '摇杆': '01C0E00000010010C2' } self.RFID_kind = dict([(value, key) for (key, value) in self.name_RFID.items()]) self.capacity = { '直齿轮': 18, '斜齿轮': 18, '齿轮轴': 24, '光轴': 24, '曲柄': 36, '摇杆': 36 } self.nameNum = { '直齿轮': 3, '斜齿轮': 3, '齿轮轴': 4, '光轴': 4, '曲柄': 6, '摇杆': 6 } self.locateName = { '直齿轮': ['A', 'B', 1], '斜齿轮': ['C', 'D', 1], '齿轮轴': ['A', 'B', 2], '光轴': ['C', 'D', 2], '曲柄': ['A', 'B', 3], '摇杆': ['C', 'D', 3] } self.get_locState() # 获取所有货位的空闲状态 # 初始化出入库按钮使能状态 self.ui.outScan_pushButton.setEnabled(False) self.ui.enterScan_pushButton.setEnabled(False) self.currentList = self.Absolute_statis('current') # 获取入库记录里各种工件的数量 print(self.currentList) def open_alltable(self): ## tableView显示属性设置 self.ui.current_tableView.setSelectionBehavior( QAbstractItemView.SelectItems) self.ui.current_tableView.setSelectionMode( QAbstractItemView.SingleSelection) self.ui.current_tableView.setAlternatingRowColors(True) # 设置相邻记录的不同颜色 self.ui.current_tableView.verticalHeader().setDefaultSectionSize( 22) # 单元格高度 self.ui.current_tableView.horizontalHeader().setDefaultSectionSize( 160) # 单元格宽度 self.ui.enter_tableView.setSelectionBehavior( QAbstractItemView.SelectItems) self.ui.enter_tableView.setSelectionMode( QAbstractItemView.SingleSelection) self.ui.enter_tableView.setAlternatingRowColors(True) # 设置相邻记录的不同颜色 self.ui.enter_tableView.verticalHeader().setDefaultSectionSize( 22) # 单元格高度 self.ui.enter_tableView.horizontalHeader().setDefaultSectionSize( 160) # 单元格宽度 self.ui.out_tableView.setSelectionBehavior( QAbstractItemView.SelectItems) self.ui.out_tableView.setSelectionMode( QAbstractItemView.SingleSelection) self.ui.out_tableView.setAlternatingRowColors(True) # 设置相邻记录的不同颜色 self.ui.out_tableView.verticalHeader().setDefaultSectionSize( 22) # 单元格高度 self.ui.out_tableView.horizontalHeader().setDefaultSectionSize( 160) # 单元格宽度 self.ui.VICEtableView.setSelectionBehavior( QAbstractItemView.SelectItems) self.ui.VICEtableView.setSelectionMode( QAbstractItemView.SingleSelection) self.ui.VICEtableView.setAlternatingRowColors(True) # 设置相邻记录的不同颜色 self.ui.VICEtableView.verticalHeader().setDefaultSectionSize( 22) # 单元格高度 self.ui.VICEtableView.horizontalHeader().setDefaultSectionSize( 240) # 单元格宽度 # 连接到数据库并打开 self.DB = QSqlDatabase.addDatabase( 'QSQLITE') # 建立与数据库的连接,即QSqlDatabase对象 self.DB.setDatabaseName('MES5.db') # 设置数据库名称 self.DB.open() # 打开数据库 print('数据库打开成功') ## 打开现有库存数据表 self.current_tabModel = QSqlTableModel(self, self.DB) # 创建数据表的模型 self.current_tabModel.setTable('工件信息表') # 设置需要连接的数据表 self.current_tabModel.setEditStrategy(QSqlTableModel.OnManualSubmit) ## 打开入库记录表 self.enter_tabModel = QSqlTableModel(self, self.DB) # 创建数据表的模型 self.enter_tabModel.setTable('入库记录表') # 设置需要连接的数据表 self.enter_tabModel.setEditStrategy(QSqlTableModel.OnManualSubmit) ## 打开出库记录表 self.out_tabModel = QSqlTableModel(self, self.DB) # 创建数据表的模型 self.out_tabModel.setTable('出库记录表') # 设置需要连接的数据表 self.out_tabModel.setEditStrategy(QSqlTableModel.OnManualSubmit) ## 打开固定批RFID表======================================================== self.vice_tabModel = QSqlTableModel(self, self.DB) # 创建数据表的模型 self.vice_tabModel.setTable('新建表') # 设置需要连接的数据表 self.vice_tabModel.setEditStrategy(QSqlTableModel.OnManualSubmit) self.ui.VICEtableView.setModel( self.vice_tabModel) # 为一个QTableView组件设置一个QSqlTabelModel模型 self.vice_tabModel.select() # 建立RFID与组件的映射关系 self.mapper = QDataWidgetMapper() self.mapper.setModel(self.vice_tabModel) self.mapper.setSubmitPolicy(QDataWidgetMapper.AutoSubmit) ##界面组件与tabelmodel的具体字段之间的联系 self.mapper.addMapping(self.ui.RFIDlineEdit, 0) self.mapper.toFirst() # 移动到首记录 # 选中数据时信号的发射 self.selModel = QItemSelectionModel(self.vice_tabModel) self.selModel.currentRowChanged.connect(self.do_currentRowChanged) self.ui.VICEtableView.setSelectionModel(self.selModel) # 设置选择模型 # =============================================================================== self.refresh() print('数据表打开成功') ##获取字段名和序号的字典数据 empty = self.current_tabModel.record() # 得到的是一个空的记录,获取表的字段定义 self.fldNum = {} for i in range(empty.count()): filedname = empty.fieldName(i) empty.field(filedname).setReadOnly(True) # 每个字段设置为只读 self.fldNum.setdefault( filedname, i) # 如果字典中包含有给定键,则返回该键对应的值,否则将键添加到字典中,默认值为None print(self.fldNum) print(self.current_tabModel.record().count()) def do_currentRowChanged(self, current): self.mapper.setCurrentIndex(current.row()) def refresh(self): self.ui.current_tableView.setModel(self.current_tabModel) self.current_tabModel.select() self.ui.enter_tableView.setModel( self.enter_tabModel) # 为一个QTableView组件设置一个QSqlTabelModel模型 self.enter_tabModel.select() self.ui.out_tableView.setModel( self.out_tabModel) # 为一个QTableView组件设置一个QSqlTabelModel模型 self.out_tabModel.select() self.inventory_used() #################################路径规划与货位分配########################################### def get_locState(self): # 获取所有货位的状态 self.locationState = {} DecodeLoc = {'A': 0, 'B': 1, 'C': 0, 'D': 1} # 解码字典 for key, value in self.nameNum.items(): self.locationState[key] = np.zeros((2, 3, value), dtype=int) if self.current_tabModel.record(0).isNull('货位') == True: pass else: currentRow = self.current_tabModel.rowCount() # 库存的已记录数 # 根据现有库存更新货位的状态 for i in range(currentRow): curRec = self.current_tabModel.record(i) location = curRec.value('货位') kindname = curRec.value('种类') x = DecodeLoc[location[0]] # 对已有的工件的货位编码进行解码 y = int(location[1]) - 1 z = int(location[5]) - 1 self.locationState[kindname][x][y][z] = 1 #货位分配函数 def allocation(self, name, num, label): # 输入工件名称和对应的数量 if label == 'i': sign = 0 else: sign = 1 itsloc = self.locationState[name] for i in range(3): data = itsloc[:, 0:i + 1] data = data.reshape(1, -1)[0] itsum = sum(data == sign) if itsum >= num: forward_double = i + 1 break idle_loc = np.where( itsloc[:, 0:forward_double] == sign) # 寻找前forward_double对货架的空闲货位 locating = [] # 存放接收工件的货位 for i in range(num): x = idle_loc[0][i] y = idle_loc[1][i] z = idle_loc[2][i] self.locationState[name][x][y][z] = 1 - sign # 分配好后即更新货位状态 locating.append([x, y, z]) EncodeLoc = [] for i in locating: s = self.locateName[name][i[0]] + str(i[1] + 1) + '-' + \ str(self.locateName[name][2]) + '-' + str(i[2] + 1) EncodeLoc.append(s) return EncodeLoc, forward_double def getLocation(self, outList, direct): ALLlocation = [] forwardLocation = {} for key, value in outList.items(): location, position = self.allocation(key, value, direct) ALLlocation = ALLlocation + location forwardLocation[key] = position - 1 return ALLlocation, forwardLocation # 表里的工件统计 def statistics(self, model): n = model.rowCount() # 总行数 all_list = {} for i in range(n): # 统计入库记录里各种工件的数量 rec = model.record(i) if rec.value('种类') in all_list: all_list[rec.value('种类')] += 1 else: all_list[rec.value('种类')] = 1 return all_list def Absolute_statis(self, label): myModel = QSqlQueryModel(self) if label == 'current': myModel.setQuery("select 种类 from 工件信息表") elif label == 'enter': myModel.setQuery("select 种类 from 入库记录表") elif label == 'out': myModel.setQuery("select 种类 from 出库记录表") allnum = myModel.rowCount() all_dict = {} for i in range(allnum): rec = myModel.record(i) if rec.value('种类') in all_dict: all_dict[rec.value('种类')] += 1 else: all_dict[rec.value('种类')] = 1 return all_dict #寻找出入库记录的最大批次 def getMaxbatch(self, label): myModel = QSqlQueryModel(self) if label == 'enter': myModel.setQuery("select 批次 from 入库记录表") elif label == 'out': myModel.setQuery("select 批次 from 出库记录表") n = myModel.rowCount() if myModel.record(0).isNull('批次') == True: # 检测入库记录里的最大批次 max_batch = 0 else: max_batch = myModel.record(n - 1).value('批次') # 批次按顺序排列,查找最大批次 print('共有%d条记录,最大批次为%d' % (n, max_batch)) return max_batch #################################主操作界面#################################################### # 容量不足信息打印 def on_enterNum_spinBox_valueChanged(self): self.enter_Warning() def on_enterKind_comboBox_currentIndexChanged(self): self.enter_Warning() def enter_Warning(self): num = self.ui.enterNum_spinBox.value() enterKind = self.ui.enterKind_comboBox.currentText() if enterKind not in self.currentList: currentNum = 0 else: currentNum = self.currentList[enterKind] if num + currentNum > self.capacity[enterKind]: self.ui.enterList_pushButton.setEnabled(False) # self.ui.enterScan_pushButton.setEnabled(False) warningText = '⚠警告!' + enterKind + '已经超出库容上限!' else: self.ui.enterList_pushButton.setEnabled(True) # self.ui.enterScan_pushButton.setEnabled(True) warningText = '' self.ui.textEdit.setPlainText(warningText) #############入库函数 ##入库添加工件及对应数量 @pyqtSlot() def on_enterList_pushButton_clicked(self): enterKind = self.ui.enterKind_comboBox.currentText() enterNum = self.ui.enterNum_spinBox.value() if enterKind in self.enterList: self.enterList[enterKind] += enterNum else: self.enterList[enterKind] = enterNum # 激活出库按钮使能状态 self.ui.enterScan_pushButton.setEnabled(True) print(self.enterList) ##扫描入库 @pyqtSlot() def on_enterScan_pushButton_clicked(self): # 根据入库记录里的RFID生成新的RFID enteredList = self.statistics(self.enter_tabModel) # 获取入库记录里各种工件的数量 RFID_list = [] for key in self.enterList.keys(): # 对要入库的工件种类进行迭代 for i in range(self.enterList[key]): if key not in enteredList: no = i + 6 else: no = enteredList[key] + i + 6 RFID = self.name_RFID[key] + str(no).zfill(6) RFID_list.append(RFID) # 将RFID写入txt文件来模拟货物 filename = '卸货区' if not os.path.isdir(filename): os.makedirs(filename) with open('卸货区\待入库货工件.txt', 'w', encoding='utf8') as f: for s in RFID_list: f.write(s + '\n') # 从卸货区寻找模拟货物 dbFilename, flt = QFileDialog.getOpenFileName(self, "寻找入库货物", "", "模拟货物(*.txt)") if (dbFilename == ''): return with open(dbFilename, 'r', encoding='utf8') as f: enterRFID = f.readlines() all_location, forwardLocation = self.getLocation(self.enterList, 'i') self.ui.widget.get_path(forwardLocation, 'i') # 绘制路径 self.enter(enterRFID, all_location) # 入库操作 def enter(self, enterRFID, all_location): #print('入库函数,enterRFID=',enterRFID,'all_location=',all_location) # 准备写入工件信息表和入库记录表 currentQuery = QSqlQuery(self.DB) enterQuery = QSqlQuery(self.DB) currentQuery.prepare('''INSERT INTO 工件信息表 (RFID,种类,货位,生产商, 批次,入库日期,入库时间,重量) VALUES(:RFID,:kind,:location,:manufacture,:batch, :enterDate,:enterTime,:weight)''') enterQuery.prepare('''INSERT INTO 入库记录表 (RFID,种类,生产商, 批次,入库日期,入库时间) VALUES(:RFID,:kind, :manufacture,:batch, :enterDate,:enterTime)''') # 准备数据(都是恒量) RFID_manufacture = { 'E0000001': '西安交大一厂', 'E0000002': '西安交大二厂', 'E0000003': '西安交大三厂' } max_batch = self.getMaxbatch('enter') enterDate = self.ui.dealdate.date().toString(Qt.ISODate) # 获取日期 enterTime = time.strftime('%H:%M:%S', time.localtime(time.time())) # 获取时分秒 weightList = { '直齿轮': 15, '斜齿轮': 20, '齿轮轴': 7, '光轴': 5, '曲柄': 2, '摇杆': 1 } check = True # 扫码并写入记录表 for i in range(len(enterRFID)): # 解码 s = enterRFID[i].rstrip('\n') kind = self.RFID_kind[s[0:18]] manufacture = RFID_manufacture[s[4:12]] weight = weightList[kind] # 加入现有库存 currentQuery.bindValue(":RFID", s) currentQuery.bindValue(":kind", kind) currentQuery.bindValue(":location", all_location[i]) currentQuery.bindValue(":manufacture", manufacture) currentQuery.bindValue(":batch", max_batch + 1) currentQuery.bindValue(":enterDate", enterDate) currentQuery.bindValue(":enterTime", enterTime) currentQuery.bindValue(":weight", weight) res = currentQuery.exec() # 执行SQL语句 check = check & res # 加入入库记录表 enterQuery.bindValue(":RFID", s) enterQuery.bindValue(":kind", kind) enterQuery.bindValue(":manufacture", manufacture) enterQuery.bindValue(":batch", max_batch + 1) enterQuery.bindValue(":enterDate", enterDate) enterQuery.bindValue(":enterTime", enterTime) enterQuery.exec() # 执行SQL语句 if check == False: QMessageBox.critical( self, "错误", "添加记录出现错误\n" + currentQuery.lastError().text()) print('入库异常') else: self.enterList = {} self.refresh() self.ui.enterScan_pushButton.setEnabled(False) self.ui.textEdit.setPlainText('入库操作成功') #############出库函数 # 库存不足信息打印 def on_outNum_spinBox_valueChanged(self): self.out_Warning() def on_outKind_comboBox_currentIndexChanged(self): self.out_Warning() def out_Warning(self): num = self.ui.outNum_spinBox.value() outKind = self.ui.outKind_comboBox.currentText() self.currentList = self.Absolute_statis('current') if outKind not in self.currentList: # 防止有些工件没有时作为字典的键出错 currentNum = 0 else: currentNum = self.currentList[outKind] if num > currentNum: self.ui.outList_pushButton.setEnabled(False) # self.ui.outScan_pushButton.setEnabled(False) warningText = '⚠警告!' + outKind + '已经超出库存上限!' else: self.ui.outList_pushButton.setEnabled(True) # self.ui.outScan_pushButton.setEnabled(True) warningText = '' self.ui.textEdit.setPlainText(warningText) # 添加出库工件 @pyqtSlot() def on_outList_pushButton_clicked(self): outKind = self.ui.outKind_comboBox.currentText() outNum = self.ui.outNum_spinBox.value() if outKind in self.outList: self.outList[outKind] += outNum else: self.outList[outKind] = outNum self.ui.outScan_pushButton.setEnabled(True) print("要出库的货物:", self.outList) @pyqtSlot() def on_outScan_pushButton_clicked(self): currentRow = self.current_tabModel.rowCount() # 库存的已记录数 RFID_list = [] outLocation, forwardLocation = self.getLocation(self.outList, 'o') # 从现有库存里取符合条件的RFID for i in range(currentRow): curRec = self.current_tabModel.record(i) location = curRec.value('货位') if location in outLocation: RFID_list.append(curRec.value('RFID')) # 将RFID写入模拟货物 filename = '发货区' if not os.path.isdir(filename): os.makedirs(filename) with open('发货区\待出库货工件.txt', 'w', encoding='utf8') as f: for s in RFID_list: f.write(s + '\n') # 从卸货区寻找模拟货物 dbFilename, flt = QFileDialog.getOpenFileName(self, "寻找出库货物", "", "模拟货物(*.txt)") if (dbFilename == ''): return with open(dbFilename, 'r', encoding='utf8') as f: outRFID = f.readlines() for i in range(len(outRFID)): # 去除所有的换行符 outRFID[i] = outRFID[i].rstrip('\n') self.ui.widget.get_path(forwardLocation, 'o') #出库路径绘制 self.out(outRFID) def out(self, outRFID): # 出库函数,参数只有RFID列表 currentRow = self.current_tabModel.rowCount() # 库存的已记录数 currentQuery = QSqlQuery(self.DB) # 准备删除 outQuery = QSqlQuery(self.DB) # 准备插入 outQuery.prepare('''INSERT INTO 出库记录表 (RFID,种类,生产商, 批次,出库日期,出库时间) VALUES(:RFID,:kind, :manufacture,:batch, :outDate,:outTime)''') currentQuery.prepare('''DELETE FROM 工件信息表 WHERE RFID=:ID''') # 获取出库记录表里的最大批次 batch = self.getMaxbatch('out') outDate = self.ui.dealdate.date().toString(Qt.ISODate) outTime = time.strftime('%H:%M:%S', time.localtime(time.time())) check = True # 读取要出库的工件的RFID for i in range(currentRow): # 遍历现有库存找到要出库的RFID curRec = self.current_tabModel.record(i) if curRec.value('RFID') in outRFID: outQuery.bindValue(":RFID", curRec.value('RFID')) outQuery.bindValue(":kind", curRec.value('种类')) outQuery.bindValue(":manufacture", curRec.value('生产商')) outQuery.bindValue(":batch", batch + 1) outQuery.bindValue(":outDate", outDate) outQuery.bindValue(":outTime", outTime) outQuery.exec() # 执行SQL语句 currentQuery.bindValue(":ID", curRec.value('RFID')) res = currentQuery.exec() check = check & res if check == False: QMessageBox.critical( self, "错误", "出库记录出现错误\n" + currentQuery.lastError().text()) else: self.refresh() self.outList = {} self.ui.outScan_pushButton.setEnabled(False) self.ui.textEdit.setPlainText('出库操作成功') self.out_Warning() # 库存不足则打印信息,改变按键使能状态 # =================================副操作界面================================================== def getCurrentNum(self): currentQryModel = QSqlQueryModel(self) currentQryModel.setQuery("select RFID from 工件信息表") allnum = currentQryModel.rowCount() return allnum, currentQryModel ##单件扫描 @pyqtSlot() def on_emitPushButton_pressed(self): RFID = self.ui.RFIDlineEdit.text() forwardLocation = {} kind = self.RFID_kind[RFID[0:18]] kindlist = [] kindlist.append(RFID) allnum, currentQryModel = self.getCurrentNum() for i in range(allnum): cur = currentQryModel.record(i) if RFID == cur.value('RFID'): self.out(kindlist) self.get_locState() return # 因为已经指定了RFID,所以出库没有路径规划 location, position = self.allocation(kind, 1, 'i') self.enter(kindlist, location) forwardLocation[kind] = position - 1 self.ui.widget.get_path(forwardLocation, 'i') ##多件扫描 @pyqtSlot() def on_ScanPushButton_pressed(self): outRFID = [] inkindNum = {} dbFilename, flt = QFileDialog.getOpenFileName(self, "寻找入库货物", "", "模拟货物(*.txt)") if (dbFilename == ''): return with open(dbFilename, 'r', encoding='utf8') as f: RFID = f.readlines() for i in range(len(RFID)): # 去除所有的换行符 RFID[i] = RFID[i].rstrip('\n') allnum, currentQryModel = self.getCurrentNum() for i in range(allnum): cur = currentQryModel.record(i) if cur.value('RFID') in RFID: outRFID.append(cur.value('RFID')) # 如果现有库存里存在,则添加到出库RFID列表中 RFID.remove(cur.value('RFID')) # 移除 if outRFID != []: self.out(outRFID) self.get_locState() if RFID != []: for i in RFID: kind = self.RFID_kind[i[0:18]] if kind in inkindNum: inkindNum[kind] += 1 else: inkindNum[kind] = 1 inLocation, forwardLocation = self.getLocation(inkindNum, 'i') self.ui.widget.get_path(forwardLocation, 'i') #绘制路径 self.enter(RFID, inLocation) #入库操作 #################################现有库存界面#################################################### ##种类过滤 def on_currentComboBox_currentIndexChanged(self, curText): self.current_filter() ##批次过滤 def on_batchSpinBox_valueChanged(self, num): self.current_filter() ##是否选择批次 def on_batchCheckBox_stateChanged(self): self.current_filter() def current_filter(self): kind = self.ui.currentComboBox.currentText() batch = self.ui.batchSpinBox.value() if kind == '全选': if self.ui.batchCheckBox.isChecked() == True: self.current_tabModel.setFilter("批次='%d'" % (batch)) else: self.current_tabModel.setFilter("") else: if self.ui.batchCheckBox.isChecked() == True: self.current_tabModel.setFilter("批次='%d' and 种类='%s'" % (batch, kind)) else: self.current_tabModel.setFilter("种类='%s'" % (kind)) # 已用库存百分比显示 def inventory_used(self): # 通过进度条表示库存余量 currentQryModel = QSqlQueryModel(self) currentQryModel.setQuery("select RFID from 工件信息表") allnum = currentQryModel.rowCount() progress = int((100 * allnum / 156) + 0.5) self.ui.progressBar.setValue(progress) @pyqtSlot() def on_delete_pushButton_pressed(self): query = QSqlQuery(self.DB) print('开始删除') query.exec("DELETE FROM 工件信息表 WHERE 批次>=0") query.exec("DELETE FROM 出库记录表 WHERE 批次>=0") check = query.exec("DELETE FROM 入库记录表 WHERE 批次>=0") if check == False: QMessageBox.critical(self, "错误", "删除记录出现错误\n" + query.lastError().text()) else: self.refresh() #################################入库记录界面#################################################### ##种类过滤 def on_enterComboBox_currentIndexChanged(self): self.enter_filter() ##日期过滤 def on_enterDate_dateChanged(self): self.enter_filter() ##是否选择批次 def on_enterCheckBox_stateChanged(self): self.enter_filter() def enter_filter(self): kind = self.ui.enterComboBox.currentText() date = self.ui.enterDate.date().toString(Qt.ISODate) if self.ui.enterCheckBox.isChecked() == True: if kind == '全选': self.enter_tabModel.setFilter("入库日期='%s'" % (date)) else: self.enter_tabModel.setFilter("入库日期='%s' and 种类='%s'" % (date, kind)) else: if kind == '全选': self.enter_tabModel.setFilter("") else: self.enter_tabModel.setFilter("种类='%s'" % (kind)) # 入库记录可视化 @pyqtSlot() def on_drawEnter_pushButton_pressed(self): self.recordDemo(self.enter_tabModel) #################################出库记录界面#################################################### ##种类过滤 def on_outComboBox_currentIndexChanged(self): self.out_filter() ##日期过滤 def on_outDate_dateChanged(self): self.out_filter() ##是否选择批次 def on_outCheckBox_stateChanged(self): self.out_filter() def out_filter(self): kind = self.ui.outComboBox.currentText() date = self.ui.outDate.date().toString(Qt.ISODate) if self.ui.outCheckBox.isChecked() == True: if kind == '全选': self.out_tabModel.setFilter("出库日期='%s'" % (date)) else: self.out_tabModel.setFilter("出库日期='%s' and 种类='%s'" % (date, kind)) else: if kind == '全选': self.out_tabModel.setFilter("") else: self.out_tabModel.setFilter("种类='%s'" % (kind)) # 出库记录可视化 @pyqtSlot() def on_drawOut_pushButton_pressed(self): self.recordDemo(self.out_tabModel) #################################数据可视化################################################ # 现有库存可视化 @pyqtSlot() def on_drawCurrent_pushButton_pressed(self): # def demo(self): #self.currentList = self.statistics(self.current_tabModel) self.currentList = self.Absolute_statis('current') labels = [] values = [] for key, value in self.currentList.items(): labels.append(key) values.append(value) if self.ui.pie_radioButton.isChecked() == True: trace = [go.Pie(labels=labels, values=values)] layout = go.Layout(title='工件库存比例配比图', ) elif self.ui.bar_radioButton.isChecked() == True: trace = [go.Bar(x=labels, y=values)] layout = go.Layout(title='工件库存直方图', ) print(labels) print(values) fig = go.Figure(data=trace, layout=layout) file = 'F:\source\python代码\MES库存管理\VisualData' if not os.path.isdir(file): os.makedirs(file) filename = 'F:\source\python代码\MES库存管理\VisualData\\currentDemo.html' pyof.plot(fig, filename=filename, auto_open=False) win = DemoWindow(filename) win.exec() def recordDemo(self, model): record = {} enterRow = model.rowCount() # 库存的已记录数 dateName = model.record().fieldName(4) # 入库日期&出库日期 TimeName = model.record().fieldName(5) for i in range(enterRow): curRec = model.record(i) kind = curRec.value('种类') date = curRec.value(dateName) Time = curRec.value(TimeName) dateTime = date + ' ' + Time dateRecord = {} if kind not in record: # 工件种类第一次检索到,将其添加到reord中 dateRecord[dateTime] = 1 # 同时将对应的日期添加到record中 record[kind] = dateRecord else: if dateTime not in record[kind]: # 种类存在,但是第一次检索到某个日期时 record[kind][dateTime] = 1 else: record[kind][dateTime] += 1 traces = [] for key1 in record.keys(): x = [] y = [] for key2 in record[key1].keys(): x.append(key2) y.append(record[key1][key2]) trace = go.Scatter( x=x, y=y, # mode = 'markers', name=key1) traces.append(trace) layout = go.Layout(title=dateName[0:2] + '记录', ) fig = go.Figure(data=traces, layout=layout) file = 'F:\source\python代码\MES库存管理\VisualData' if not os.path.isdir(file): os.makedirs(file) filename = 'F:\source\python代码\MES库存管理\VisualData\\recordDemo.html' pyof.plot(fig, filename=filename, auto_open=False) win = DemoWindow(filename) win.exec()
class OrganTab(QWidget): def __init__(self, ctx, *args, **kwargs): super(OrganTab, self).__init__(*args, **kwargs) self.ctx = ctx self.alfas = None self.betas = None self.organ_dose_db = None self.organ_names = [] self.fig = {} self.is_quick_mode = False self.show_hk = False self.show_dosemap = False self.show_distmap = False self.show_dosedist = False self.initModel() self.initVar() self.initUI() self.sigConnect() def initVar(self): self.dist_map = None self.dose_map = None self.poly = None self.ssdec = 0 self.ssdep = 0 self.organ_dose_mean = 0 self.organ_dose_std = 0 self.diameter = 0 self.ssde = 0 self.ctdi = 0 self.ssdecs = {} self.ssdeps = {} self.means = {} self.stds = {} self.dist_maps = {} self.dose_maps = {} self.polys = {} def initModel(self): self.protocol_model = QSqlTableModel(db=self.ctx.database.ssde_db) self.organ_model = QSqlTableModel(db=self.ctx.database.ssde_db) self.organ_dose_model = QSqlTableModel(db=self.ctx.database.ssde_db) self.protocol_model.setTable("Protocol") self.organ_model.setTable("Organ") self.organ_dose_model.setTable("Organ_Dose") self.protocol_model.setFilter("Group_ID=1") self.organ_dose_model.setFilter("Protocol_ID=1") self.protocol_model.select() self.organ_model.select() self.organ_dose_model.select() def sigConnect(self): self.method_cb.activated[int].connect(self.on_method_changed) self.protocol_cb.activated[int].connect(self.on_protocol_changed) self.calc_db_btn.clicked.connect(self.on_calculate_db) self.calc_cnt_btn.clicked.connect(self.on_calculate_cnt) self.add_cnt_btn.clicked.connect(self.on_contour) self.is_quick_mode_chk.stateChanged.connect(self.on_quick_mode_check) self.show_hk_chk.stateChanged.connect(self.on_show_hk_check) self.show_dosemap_chk.stateChanged.connect(self.on_show_dosemap_check) self.show_distmap_chk.stateChanged.connect(self.on_show_distmap_check) self.show_dosedist_chk.stateChanged.connect( self.on_show_dosedist_check) self.ctx.app_data.modeValueChanged.connect(self.diameter_mode_handle) # self.ctx.app_data.diameterValueChanged.connect(self.diameter_handle) # self.ctx.app_data.CTDIValueChanged.connect(self.ctdiv_handle) # self.ctx.app_data.SSDEValueChanged.connect(self.ssdew_handle) self.ctx.app_data.diametersUpdated.connect(self.update_values) self.ctx.app_data.ctdivsUpdated.connect(self.update_values) self.ctx.app_data.ssdesUpdated.connect(self.update_values) self.ctx.app_data.imgChanged.connect(self.img_changed_handle) self.ctx.axes.addPolyFinished.connect(self.add_cnt_handle) def initUI(self): self.figure = PlotDialog() self.method_cb = QComboBox() self.method_cb.addItems(['MC Data', 'Direct calculation']) self.init_db_method_ui() self.init_cnt_method_ui() self.main_area = QStackedWidget() self.main_area.addWidget(self.db_method_ui) self.main_area.addWidget(self.cnt_method_ui) self.on_method_changed() main_layout = QVBoxLayout() main_layout.addWidget(QLabel('Method:')) main_layout.addWidget(self.method_cb) main_layout.addWidget(self.main_area) main_layout.addStretch() self.setLayout(main_layout) def init_db_method_ui(self): self.protocol_cb = QComboBox() self.protocol_cb.setModel(self.protocol_model) self.protocol_cb.setModelColumn(self.protocol_model.fieldIndex('name')) self.calc_db_btn = QPushButton('Calculate') self.organ_labels = [] self.organ_edits = [QLineEdit('0') for i in range(28)] [organ_edit.setMaximumWidth(70) for organ_edit in self.organ_edits] [organ_edit.setReadOnly(True) for organ_edit in self.organ_edits] [ organ_edit.setAlignment(Qt.AlignRight) for organ_edit in self.organ_edits ] left = QFormLayout() right = QFormLayout() grid = QHBoxLayout() organ_grpbox = QGroupBox('Organ Dose') scroll = QScrollArea() for idx, organ_edit in enumerate(self.organ_edits): name = self.organ_model.record(idx).value('name') self.organ_names.append(name[0]) label = QLabel(name) label.setMaximumWidth(100) self.organ_labels.append(label) left.addRow(label, organ_edit) if idx < 14 else right.addRow( label, organ_edit) grid.addLayout(left) grid.addLayout(right) organ_grpbox.setLayout(grid) scroll.setWidget(organ_grpbox) scroll.setWidgetResizable(True) self.db_method_ui = QGroupBox('', self) db_method_layout = QVBoxLayout() db_method_layout.addWidget(QLabel('Protocol:')) db_method_layout.addWidget(self.protocol_cb) db_method_layout.addWidget(self.calc_db_btn) db_method_layout.addWidget(scroll) db_method_layout.addStretch() self.db_method_ui.setLayout(db_method_layout) def init_cnt_method_ui(self): self.calc_cnt_btn = QPushButton('Calculate') self.add_cnt_btn = QPushButton('Add Contour') self.is_quick_mode_chk = QCheckBox('Quick Mode') self.is_quick_mode_chk.setEnabled(False) self.show_dosemap_chk = QCheckBox('Show Dose Map') self.show_distmap_chk = QCheckBox('Show Distance Map') self.show_dosedist_chk = QCheckBox('Show Histogram') self.show_hk_chk = QCheckBox('Show Corr. Factor Graph') self.diameter_label = QLabel("<b>Diameter (cm)</b>") self.diameter_edit = QLineEdit('0') self.ctdiv_edit = QLineEdit('0') self.ssdew_edit = QLineEdit('0') self.ssdec_edit = QLineEdit('0') self.ssdep_edit = QLineEdit('0') self.mean_edit = QLineEdit('0') self.std_edit = QLineEdit('0') edits = [ self.diameter_edit, self.ctdiv_edit, self.ssdew_edit, self.ssdec_edit, self.ssdep_edit, self.mean_edit, self.std_edit ] [edit.setReadOnly(True) for edit in edits] self.diameter_mode_handle(DEFF_IMAGE) left = QGroupBox('', self) right = QGroupBox('', self) left_layout = QFormLayout() right_layout = QFormLayout() left_layout.addRow(self.diameter_label, self.diameter_edit) left_layout.addRow(QLabel("<b>CTDI<sub>vol</sub> (mGy)</b>"), self.ctdiv_edit) left_layout.addRow(QLabel("<b>SSDE<sub>w</sub> (mGy)</b>"), self.ssdew_edit) left_layout.addRow(QLabel("<b>SSDE<sub>c</sub> (mGy)</b>"), self.ssdec_edit) left_layout.addRow(QLabel("<b>SSDE<sub>p</sub> (mGy)</b>"), self.ssdep_edit) right_layout.addRow(QLabel("<b>Mean (mGy)</b>"), self.mean_edit) right_layout.addRow(QLabel("<b>Std. Deviation (mGy)</b>"), self.std_edit) left.setLayout(left_layout) right.setLayout(right_layout) output_area = QHBoxLayout() output_area.addWidget(left) output_area.addWidget(right) opt_grpbox = QGroupBox('Options') opt_area = QVBoxLayout() opt_area.addWidget(self.is_quick_mode_chk) opt_area.addWidget(self.show_distmap_chk) opt_area.addWidget(self.show_dosemap_chk) opt_area.addWidget(self.show_dosedist_chk) opt_area.addWidget(self.show_hk_chk) opt_grpbox.setLayout(opt_area) btn_layout = QVBoxLayout() btn_layout.addStretch() btn_layout.addWidget(self.add_cnt_btn) btn_layout.addWidget(self.calc_cnt_btn) btn_layout.addStretch() btn_opt_layout = QHBoxLayout() btn_opt_layout.addLayout(btn_layout) btn_opt_layout.addWidget(opt_grpbox) main_layout = QVBoxLayout() main_layout.addLayout(output_area) main_layout.addLayout(btn_opt_layout) self.cnt_method_ui = QGroupBox('', self) self.cnt_method_ui.setLayout(main_layout) def plot(self): xdict = dict(enumerate(self.organ_names, 1)) stringaxis = AxisItem(orientation='bottom') stringaxis.setTicks([xdict.items()]) # fm = QFontMetrics(stringaxis.font()) # minHeight = max(fm.boundingRect(QRect(), Qt.AlignLeft, t).width() for t in xdict.values()) # stringaxis.setHeight(minHeight + fm.width(' ')) self.figure = PlotDialog(size=(900, 600), straxis=stringaxis) self.figure.setTitle('Organ Dose') self.figure.axes.showGrid(False, True) self.figure.setLabels('', 'Dose', '', 'mGy') self.figure.bar(x=list(xdict.keys()), height=self.organ_dose_db, width=.8, brush='g') self.figure.show() def plot_cnt(self, dose_vec): self.figure = PlotDialog() self.figure.actionEnabled(True) self.figure.trendActionEnabled(False) self.figure.opts_dlg.y_mean_chk.setEnabled(False) self.figure.opts_dlg.y_stdv_chk.setEnabled(False) self.figure.histogram(dose_vec, fillLevel=0, brush=(0, 0, 255, 150), symbol='o', symbolSize=5) self.figure.axes.showGrid(True, True) self.figure.setLabels('Organ Dose', 'Frequency', 'mGy', '') self.figure.setTitle('Organ Dose') self.figure.show() def plot_hk(self): h, k, dw = self.get_interpolation() h_data = h(dw) k_data = k(dw) diameter = self.diameter c = h(diameter) p = k(diameter) anc_c = (1, 0) if diameter > 13.575512 else (1, 1) anc_p = (1, 1) if diameter > 13.575512 else (1, 0) self.figure_hk = PlotDialog() self.figure_hk.setTitle('Correction Factor') self.figure_hk.plot(dw, h_data, pen={ 'color': "FFFF00", 'width': 2 }, symbol=None, name='h_factor') self.figure_hk.plot(dw, k_data, pen={ 'color': "00FFFF", 'width': 2 }, symbol=None, name='k_factor') self.figure_hk.plot([diameter], [c], symbol='o', symbolPen=None, symbolSize=8, symbolBrush=(255, 0, 0, 255)) self.figure_hk.plot([diameter], [p], symbol='o', symbolPen=None, symbolSize=8, symbolBrush=(255, 0, 0, 255)) self.figure_hk.annotate( 'cfh', pos=(diameter, c), text=f'diameter = {diameter:#.2f}\nh-factor = {c:#.2f}', anchor=anc_c) self.figure_hk.annotate( 'cfk', pos=(diameter, p), text=f'diameter = {diameter:#.2f}\nk-factor = {p:#.2f}', anchor=anc_p) self.figure_hk.axes.showGrid(True, True) self.figure_hk.setLabels('Diameter', 'Correction Factor', 'mm', '') self.figure_hk.axes.setXRange(np.min(dw), np.max(dw)) self.figure_hk.axes.setYRange(np.min([np.min(k_data), np.min(h_data)]), np.max([np.max(k_data), np.max(h_data)])) self.figure_hk.show() def plot_dosemap(self): self.figure_dose = ImageViewDialog(unit='dose') self.figure_dose.setTitle('Dose Map') self.figure_dose.imshow(self.dose_map) self.figure_dose.show() def plot_img(self, img, title='figure', unit=(None, None)): key = title.lower().replace(' ', '_') self.fig[key] = ImageViewDialog(unit=unit) self.fig[key].setTitle(title) self.fig[key].imshow(img) self.fig[key].add_roi(self.poly) self.fig[key].show() def getData(self): self.alfas = np.array([ self.organ_dose_model.record(n).value('alfa') for n in range(self.organ_dose_model.rowCount()) ]) self.betas = np.array([ self.organ_dose_model.record(n).value('beta') for n in range(self.organ_dose_model.rowCount()) ]) def diameter_mode_handle(self, value): self.dist_map = None self.dose_map = None self.dist_maps = {} self.dose_maps = {} self.add_cnt_btn.setEnabled(True) self.add_cnt_btn.setText('Add Contour') if value == DW: self.diameter_label.setText('<b>Dw (cm)</b>') self.show_distmap_chk.setText('Show Water Eq. Distance Map') self.is_quick_mode_chk.setEnabled(True) else: self.diameter_label.setText('<b>Deff (cm)</b>') self.show_distmap_chk.setText('Show Effective Distance Map') self.is_quick_mode_chk.setCheckState(Qt.Unchecked) self.is_quick_mode_chk.setEnabled(False) def diameter_handle(self, value): self.diameter_edit.setText(f'{value:#.2f}') def ctdiv_handle(self, value): self.ctdiv_edit.setText(f'{value:#.2f}') def ssdew_handle(self, value): self.ssdew_edit.setText(f'{value:#.2f}') def add_cnt_handle(self, value): self.add_cnt_btn.setEnabled(True) self.calc_cnt_btn.setEnabled(True) def img_changed_handle(self, value): if value: self.update_values() def on_method_changed(self): self.main_area.setCurrentIndex(self.method_cb.currentIndex()) def on_protocol_changed(self, idx): self.protocol_id = self.protocol_model.record(idx).value("id") self.organ_dose_model.setFilter(f'Protocol_ID={self.protocol_id}') self.getData() print(self.protocol_id, self.protocol_model.record(idx).value("name")) def on_calculate_db(self): self.organ_dose_db = self.ctx.app_data.CTDIv * np.exp( self.alfas * self.ctx.app_data.diameter + self.betas) [ self.organ_edits[idx].setText(f'{dose:#.2f}') for idx, dose in enumerate(self.organ_dose_db) ] self.plot() def get_ssde(self): h, k, _ = self.get_interpolation() self.ssdec = h(self.diameter) * self.ssde self.ssdep = k(self.diameter) * self.ssde self.ssdec_edit.setText(f'{self.ssdec:#.2f}') self.ssdep_edit.setText(f'{self.ssdep:#.2f}') self.ssdecs[self.ctx.current_img] = self.ssdec self.ssdeps[self.ctx.current_img] = self.ssdep def build_dose_map(self): from functools import partial def avg_profile_line(p2, p1): x0, y0 = p1 x1, y1 = p2 length = int(np.hypot(x1 - x0, y1 - y0)) x = np.linspace(x0, x1, length).astype(int) y = np.linspace(y0, y1, length).astype(int) return img[x, y].mean() cancel = False rd = self.ctx.recons_dim row, col = self.ctx.get_current_img().shape mask = self.get_img_mask(self.ctx.get_current_img(), largest_only=True) if mask is not None: mask = mask.astype(float) mask_pos = np.argwhere(mask == 1) center = get_center(mask) dist_vec = np.sqrt(((mask_pos - center)**2).sum(1)) if self.ctx.app_data.mode == DW: img = self.ctx.get_current_img() profile_line_vec = np.zeros_like(dist_vec, dtype=float) n = mask_pos.shape[0] progress = QProgressDialog(f"Building dose map...", "Stop", 0, n, self) progress.setWindowModality(Qt.WindowModal) progress.setMinimumDuration(1000) profile_line = partial(avg_profile_line, center) for idx, pos in enumerate(mask_pos): profile_line_vec[idx] = profile_line(pos) progress.setValue(idx) if progress.wasCanceled(): cancel = True break progress.setValue(n) if np.isnan(profile_line_vec.sum()): profile_line_vec = np.nan_to_num(profile_line_vec) dist_vec *= ((profile_line_vec / 1000) + 1) if cancel: return dist_vec *= (0.1 * (rd / row)) dose_vec = ((dist_vec / ((self.diameter * 0.5) - 1)) * (self.ssdep - self.ssdec)) + self.ssdec self.dist_map = np.zeros_like(mask, dtype=float) self.dose_map = np.zeros_like(mask, dtype=float) self.dist_map[tuple(mask_pos.T)] = dist_vec self.dose_map[tuple(mask_pos.T)] = dose_vec self.dist_maps[self.ctx.current_img] = self.dist_map self.dose_maps[self.ctx.current_img] = self.dose_map def on_calculate_cnt(self): if self.ctx.axes.poly is None: QMessageBox.warning(None, "Warning", "Organ contour not found.") return self.poly = self.ctx.axes.poly self.polys[self.ctx.current_img] = self.poly self.get_ssde() if self.dose_map is None: self.build_dose_map() if self.dose_map is None: return organ_dose_map = self.poly.getArrayRegion(self.dose_map, self.ctx.axes.image, returnMappedCoords=False) organ_dose_mask_pos = np.argwhere(organ_dose_map != 0) organ_dose_vec = organ_dose_map[tuple(organ_dose_mask_pos.T)] self.organ_dose_mean = organ_dose_vec.mean() self.organ_dose_std = organ_dose_vec.std() self.means[self.ctx.current_img] = self.organ_dose_mean self.stds[self.ctx.current_img] = self.organ_dose_std self.mean_edit.setText(f'{self.organ_dose_mean:#.2f}') self.std_edit.setText(f'{self.organ_dose_std:#.2f}') if self.show_hk: self.plot_hk() if self.show_distmap: self.plot_img(self.dist_map, 'Distance Map', ('dist', 'cm')) if self.show_dosemap: self.plot_img(self.dose_map, 'Dose Map', ('dose', 'mGy')) if self.show_dosedist: self.plot_cnt(organ_dose_vec) def on_contour(self): print(self.ctx.axes.rois) if not self.ctx.isImage: QMessageBox.warning(None, "Warning", "Open DICOM files first.") return if self.ctx.axes.poly is None: self.ctx.axes.addPoly() self.add_cnt_btn.setText("Clear Contour") self.add_cnt_btn.setEnabled(False) self.calc_cnt_btn.setEnabled(False) else: self.ctx.axes.clearPoly() self.poly = None self.polys.pop(self.ctx.current_img, None) self.means.pop(self.ctx.current_img, None) self.stds.pop(self.ctx.current_img, None) self.organ_dose_mean = 0 self.organ_dose_std = 0 self.mean_edit.setText(f'{self.organ_dose_mean:#.2f}') self.std_edit.setText(f'{self.organ_dose_std:#.2f}') self.add_cnt_btn.setText("Add Contour") def get_organ_mask(self, roi, dose_map): img = roi.getArrayRegion(dose_map, self.ctx.axes.image, returnMappedCoords=False) return roi.renderShapeMask(img.shape[0], img.shape[1]) def get_img_mask(self, *args, **kwargs): mask = get_mask(*args, **kwargs) if mask is None: QMessageBox.warning( None, 'Segmentation Failed', 'No object found during segmentation process.') return mask def get_interpolation(self): arr = scio.loadmat(self.ctx.hk_data)['A'] dw = arr[0] hf = arr[5] kf = arr[11] h = interpolate.interp1d(dw, hf, kind='cubic') k = interpolate.interp1d(dw, kf, kind='cubic') return (h, k, dw) def on_quick_mode_check(self, state): self.is_quick_mode = state == Qt.Checked def on_show_dosemap_check(self, state): self.show_dosemap = state == Qt.Checked def on_show_distmap_check(self, state): self.show_distmap = state == Qt.Checked def on_show_dosedist_check(self, state): self.show_dosedist = state == Qt.Checked def on_show_hk_check(self, state): self.show_hk = state == Qt.Checked def update_values(self, val=True): if not val: return self.diameter = self.ctx.app_data.diameters[ self.ctx. current_img] if self.ctx.current_img in self.ctx.app_data.diameters.keys( ) else 0 self.ctdi = self.ctx.app_data.CTDIvs[ self.ctx. current_img] if self.ctx.current_img in self.ctx.app_data.CTDIvs.keys( ) else 0 self.ssde = self.ctx.app_data.SSDEs[ self.ctx. current_img] if self.ctx.current_img in self.ctx.app_data.SSDEs.keys( ) else 0 self.ssdec = self.ssdecs[ self.ctx.current_img] if self.ctx.current_img in self.ssdecs.keys( ) else 0 self.ssdep = self.ssdeps[ self.ctx.current_img] if self.ctx.current_img in self.ssdeps.keys( ) else 0 self.organ_dose_mean = self.means[ self.ctx.current_img] if self.ctx.current_img in self.means.keys( ) else 0 self.organ_dose_std = self.stds[ self.ctx.current_img] if self.ctx.current_img in self.stds.keys( ) else 0 self.dist_map = self.dist_maps[ self.ctx. current_img] if self.ctx.current_img in self.dist_maps.keys( ) else None self.dose_map = self.dose_maps[ self.ctx. current_img] if self.ctx.current_img in self.dose_maps.keys( ) else None if self.ctx.current_img in self.polys.keys(): self.poly = self.polys[self.ctx.current_img] self.ctx.axes.applyPoly(self.poly) self.add_cnt_btn.setText("Clear Contour") else: self.poly = None self.add_cnt_btn.setText("Add Contour") self.diameter_edit.setText(f'{self.diameter:#.2f}') self.ctdiv_edit.setText(f'{self.ctdi:#.2f}') self.ssdew_edit.setText(f'{self.ssde:#.2f}') self.ssdec_edit.setText(f'{self.ssdec:#.2f}') self.ssdep_edit.setText(f'{self.ssdep:#.2f}') self.mean_edit.setText(f'{self.organ_dose_mean:#.2f}') self.std_edit.setText(f'{self.organ_dose_std:#.2f}') def reset_fields(self): [organ_edit.setText('0') for organ_edit in self.organ_edits] self.protocol_cb.setCurrentIndex(0) self.on_protocol_changed(0) self.initVar() self.ctx.axes.cancel_addPoly() self.calc_cnt_btn.setEnabled(True) self.add_cnt_btn.setEnabled(True) self.add_cnt_btn.setText('Add Contour') self.update_values()
class Main(QMainWindow): def __init__(self): super(Main, self).__init__() # 初始化,super集成父类的属性 self.ui = PreviewApp.Ui_MainWindow() # 实例化 self.ui.setupUi(self) self.setWindowIcon(QIcon('db/logo.jpg')) self.db = QSqlDatabase.addDatabase('QSQLITE') self.db.setDatabaseName('db/App.db') self.db.open() self.tableView = self.ui.tableView # 获取TableView对象 self.tableView1 = self.ui.tableView1 self.model = QSqlTableModel(self) # 设置数据库模型 self.model.setTable("Preview") # 选择db的其中一个表 self.tableView.setModel(self.model) # 设置TableView的模型 self.tableView.setEditTriggers(QTableView.NoEditTriggers) # 设置表1内容不可编辑 self.model.select() # model1为页面2对象 self.model1 = QSqlTableModel(self) self.model1.setTable("Container") self.tableView1.setModel(self.model1) self.model1.select() self.ui.btn1.clicked.connect(self.addRow) self.ui.btn2.clicked.connect(self.delRow) self.ui.btn3.clicked.connect(self.CPU) self.ui.btn4.clicked.connect(self.Memory) self.ui.btn5.clicked.connect(self.CPU_temp) self.ip_list = [] self.tcpserver = TcpServer(self) self.tcpserver.listen(QHostAddress("0,0,0,0,"), Port) # 绑定监听端口 self.tcpserver.signRecv.connect(self.Recv) # self.tcpserver.signGetAddress.connect(self.updateCombox) self.updateCombox() def updateCombox(self): if self.db.open(): print("open") # 打开了数据库 query1 = QSqlQuery() query1.exec_("SELECT adress FROM IP") #打开查询数据库表 for i in range(query1.size()): print(query1.value(0)) self.ui.comboBox1.addItem(query1.value(0)) # 添加下拉列表框事件 query1.next() def Recv(self, msg): reply = QMessageBox.information(self, "标题", msg, QMessageBox.Yes | QMessageBox.No) def Send(self, msg): # 调用接口函数,向客户端发送消息 print('发送信号发出') for id in self.tcpserver.socketList: self.tcpserver.signSend.emit(msg, id) def addRow(self): # 添加一行 row = self.model1.rowCount() self.model1.insertRow(row) index = self.model1.index(row, CONTAINER) self.tableView1.setCurrentIndex(index) self.tableView1.edit(index) def delRow(self): index = self.tableView1.currentIndex() if not index.isValid(): return record = self.model1.record(index.row()) container = record.value(CONTAINER) state = record.value(STATE) if (QMessageBox.question( self, "Container Data", # 删容器时弹框 ("Delete this record?".format(state, container)), QMessageBox.Yes | QMessageBox.No) == QMessageBox.No): return self.model1.removeRow(index.row()) self.model1.submitAll() self.model1.select() def CPU(self): # CPU占有率曲线 self.ui.label2.setPixmap(QPixmap("db/CPU_percent.png")) def Memory(self): # 内存曲线 self.ui.label2.setPixmap(QPixmap("db/memory.jpg")) def CPU_temp(self): # CPU温度 self.ui.label2.setPixmap(QPixmap("db/CPU.jpg"))
class Db(QObject): #QObject а не object для pyqtSignal """ основная работа с базой SQLITE """ databaseOpened = pyqtSignal(str) #сигналы открытия, закрытия, модификации базы (полный путь текущей базы) databaseClosed = pyqtSignal(str) databaseUpdated = pyqtSignal(str) def __init__(self): super(Db, self).__init__() self.db = QSqlDatabase.addDatabase("QSQLITE") self.IsNtr=False; self.last_error='' self.lottery_config=self.LotteryConfig() self.path = '' self.isClosed = True self.configmodel = QSqlTableModel() self.historymodel =QSqlTableModel() def __initialized_history_model(self): self.historymodel.setTable("history") self.historymodel.select() self.historymodel.setHeaderData(DRAWNUMBER_COLUMN_INDEX, Qt.Horizontal, "№"); self.historymodel.setHeaderData(UNIXTIME_COLUMN_INDEX, Qt.Horizontal, "Дата"); if self.lottery_config.IsFonbet: self.historymodel.setHeaderData(FONBETID_COLUMN_INDEX, Qt.Horizontal, "Id"); def __initialized_config_model(self): self.configmodel.setTable("config") self.configmodel.select() def update_history_view(self): """ перечитаем историю , может быть после обновления """ self.__get_limit_values() self.historymodel.select() def open(self, path): self.path = path filename, file_extension = os.path.splitext(path) if file_extension.lower()=='.ntr': """ открываем как ntr. Нужно создать виртуальные history и config """ self.db.setDatabaseName(":memory:") if not self.db.open(): raise Exception('Ошибка создания базы в памяти') NtrDb(self.db, path); self.IsNtr=True; else: """ открываем как sqlite """ self.db.setDatabaseName(path) if not self.db.open(): raise Exception('Ошибка создания открытия базы') self.IsNtr=False; self.__load_config() self.__get_limit_values() self.__initialized_config_model() self.__initialized_history_model() self.select_balls_sql = '' # внутри self.__prepare_history_insert_sql() self.insert_history_sql = '' # внутри self.__prepare_history_insert_sql() self.__prepare_history_insert_sql() # подготовим некоторые строки запроса на будущее в зависимости от числа шаров self.insert_prizes_sql = '' # внутри self.__prepare_prizes_insert_sql() self.__prepare_prizes_insert_sql() # подготовим строку запроса на будущее # эмитируем сигнал открытия self.databaseOpened.emit(self.path) self.isClosed = False def close(self): self.isClosed = True self.db.close() self.configmodel.clear() self.historymodel.clear() self.lottery_config=self.LotteryConfig() #aka clear() # Emit the signal. self.databaseClosed.emit(self.path) def __prepare_history_insert_sql(self): """ Подготовим строку для вставки нового тиража """ try: str_list_insert = ['INSERT INTO [History] ([DrawNumber],[Timestamp]'] # запрос на вставку str_select_balls=[] # часть запроса номеров P1,P2....S2 for i in range(self.lottery_config.NumberOfBalls1): str_list_insert.append(',[P'+str(i+1)+']') str_select_balls.append('P'+str(i+1)) for i in range(self.lottery_config.NumberOfBalls2): str_list_insert.append(',[S'+str(i+1)+']') str_select_balls.append('S'+str(i+1)) if self.lottery_config.IsFonbet: str_list_insert.append(',[FonbetId]') str_list_insert.append(') VALUES (:DrawNumber,:Timestamp') for i in range(self.lottery_config.NumberOfBalls1): str_list_insert.append(',:P'+str(i+1)+'') for i in range(self.lottery_config.NumberOfBalls2): str_list_insert.append(',:S'+str(i+1)+'') if self.lottery_config.IsFonbet: str_list_insert.append(',:FonbetId') str_list_insert.append(')') self.select_balls_sql = ','.join(str_select_balls) self.insert_history_sql = ''.join(str_list_insert) except Exception as e: print('__prepare_history_insert_sql error: ', e) dbg_except() pass #end __prepare_history_insert_sql def __prepare_prizes_insert_sql(self): """ Подготовим строку для вставки призов нового тиража """ try: str_list_insert = ['INSERT INTO [Prizes] ([DrawId]'] for i in range(len(self.lottery_config.WinCategoriesPrizesArray)): str_list_insert.append(f',[{self.lottery_config.WinCategoriesPrizesArray[i]}]') str_list_insert.append(') VALUES (:DrawId') for i in range(len(self.lottery_config.WinCategoriesPrizesArray)): str_list_insert.append(f',:{self.lottery_config.WinCategoriesPrizesArray[i]}') str_list_insert.append(')') self.insert_prizes_sql = ''.join(str_list_insert) except Exception as e: print('__prepare_prizes_insert_sql error: ', e) dbg_except() pass #end __prepare_prizes_insert_sql def __get_limit_values(self): """определяем первые и конечные тиражи""" try: query = QSqlQuery("SELECT * FROM history ORDER BY DrawNumber DESC LIMIT 1") while query.next(): self.lottery_config.LastDrawNumber=query.value(DRAWNUMBER_COLUMN_INDEX) self.lottery_config.LastDrawDate=datetime.datetime.fromtimestamp(query.value(UNIXTIME_COLUMN_INDEX)) if self.lottery_config.IsFonbet: self.lottery_config.LastFonbetId=query.value(FONBETID_COLUMN_INDEX) query = QSqlQuery("SELECT * FROM history ORDER BY DrawNumber ASC LIMIT 1") while query.next(): self.lottery_config.FirstDrawNumber=query.value(DRAWNUMBER_COLUMN_INDEX) self.lottery_config.FirstDrawDate=datetime.datetime.fromtimestamp(query.value(UNIXTIME_COLUMN_INDEX)) except Exception as e: print('Db:getLimitValues error: ', e) dbg_except() pass #end getLimitValues def __load_config(self): """Загружаем настройки лотереи из таблицы config""" query = QSqlQuery("SELECT * FROM config") fieldKey = query.record().indexOf("key") fieldValue = query.record().indexOf("value") while query.next(): key = query.value(fieldKey) value = query.value(fieldValue) self.lottery_config._parse_config_record(key,value) def get_draws_iter(self,fromDraw,toDraw): """Выбираем тиражи между fromDraw и toDraw включительно итерабельно""" query = QSqlQuery(f"SELECT * FROM history WHERE DrawNumber>={fromDraw} AND DrawNumber<={toDraw}") rec = query.record() fields = [rec.fieldName(i) for i in range(rec.count())] rowtype = collections.namedtuple('DrawResult', fields) while query.next(): rec = query.record() yield rowtype(*[rec.value(i) for i in range(rec.count())]) def get_draws_balls_iter(self,fromDraw,toDraw): """Выбираем только шары в тиражах между fromDraw и toDraw включительно итерабельно""" query = QSqlQuery(f"SELECT * FROM history WHERE DrawNumber>={fromDraw} AND DrawNumber<={toDraw}") rec = query.record() fields = [rec.fieldName(i) for i in range(UNIXTIME_COLUMN_INDEX+1, rec.count())] rowtype = collections.namedtuple('DrawResult', fields) while query.next(): rec = query.record() yield [rec.value(i) for i in range(UNIXTIME_COLUMN_INDEX+1, rec.count())] def get_draws_balls_numpy(self,fromDraw,toDraw): """Выбираем только шары в тиражах между fromDraw и toDraw включительно и возвращаем в виде двумерного массива Numpy""" #типа self.select_balls_sql='P 1, P2 .... S2' query = QSqlQuery(f"SELECT {self.select_balls_sql} FROM history WHERE DrawNumber>={fromDraw} AND DrawNumber<={toDraw}") rec = query.record() data = np.empty((0,rec.count()), dtype=int) while query.next(): rec = query.record() arr=[rec.value(i) for i in range(rec.count())] data=np.append(data,[arr], axis=0) return data #data = np.empty((0,rec.count()-UNIXTIME_COLUMN_INDEX-1), dtype=int) #while query.next(): # rec = query.record() # arr=[rec.value(i) for i in range(UNIXTIME_COLUMN_INDEX+1, rec.count())] # data=np.append(data,[arr], axis=0) #return data pass # end get_draws_balls_numpy def get_last_fonbet_id(self): """ Для фонбетовской базы получаем fonbet_id для последнего тиража из базы""" """ Но также при загрузке базы получаю в __get_limit_values """ try: query = QSqlQuery(f"SELECT FonbetId FROM history ORDER BY DrawNumber DESC LIMIT 1") while query.next(): return query.record().value(0) return None except Exception as e: print('database error get_last_fonbet_id: ', e) dbg_except() return None pass # end get_last_fonbet_id def add_draw(self, draw): """ Записываем draw:DrawResult в базу """ try: self.last_error='' #History query = QSqlQuery() query.prepare(self.insert_history_sql) query.bindValue(":DrawNumber", draw.draw_number) query.bindValue(":Timestamp", draw.draw_date.timestamp()) #а теперь шары P for i in range(self.lottery_config.NumberOfBalls1): query.bindValue(":P"+str(i+1), draw.balls1[i]) pass #а теперь шары S for i in range(self.lottery_config.NumberOfBalls2): query.bindValue(":S"+str(i+1), draw.balls2[i]) pass #а теперь FonbetId if self.lottery_config.IsFonbet: query.bindValue(":FonbetId", draw.fonbet_id) pass result=query.exec_() if not result: return False #Prizes а теперь выигрыши если есть if draw.wins: last_insert_id =query.lastInsertId(); query = QSqlQuery() query.prepare(self.insert_prizes_sql) query.bindValue(":DrawId", last_insert_id) for i in range(len(self.lottery_config.WinCategoriesPrizesArray)): newkey=self.lottery_config.WinCategoriesPrizesArray[i].replace('WP',"").replace('S','+') #удалим WP и заменим S на + query.bindValue(f':{self.lottery_config.WinCategoriesPrizesArray[i]}', draw.wins.get(newkey,0.0)) result=query.exec_() pass # эмитируем сигнал self.databaseUpdated.emit(self.path) return result except Exception as e: self.last_error=printf('update_draws error: ', e) dbg_except() return False pass # add_draw class LotteryConfig(object): """ класс конфигурации лотереи из таблицы config """ def __init__(self): """ это хранится в конфиге""" self.LottoName = "" self.NumberOfBalls1=0 self.StartOfBalls1=0 self.EndOfBalls1=0 self.NumberOfBalls2=0 self.StartOfBalls2=0 self.EndOfBalls2=0 self.DataImportPlugin='' # имя файла отвечающего за обновление без расширения .py self.WinCategories='' self.DefaultWinCost='' self.GameType = "" # Toto для Фонбета self.IsTop3=False; self.IsFonbet=False; self.MultipleAppearance1=False; self.MultipleAppearance2=False; self.WithWins=False; """ это вспомогательное - вычисляется""" self.LastDrawNumber=0 self.LastDrawDate=datetime.date.min self.FirstDrawNumber=0 self.FirstDrawDate=datetime.date.min self.WinCategoriesPrizesArray=[] self.LastFonbetId=0 # Fonbet only pass #end __init__ def _parse_config_record(self, key,value): """ парсим параметры конфигурации """ if key.lower() == 'LottoName'.lower(): self.LottoName=str(value) elif key.lower() == 'NumberOfBalls1'.lower(): self.NumberOfBalls1=int(value) elif key.lower() == 'NumberOfBalls2'.lower(): self.NumberOfBalls2=int(value) elif key.lower() == 'StartOfBalls1'.lower(): self.StartOfBalls1=int(value) elif key.lower() == 'StartOfBalls2'.lower(): self.StartOfBalls2=int(value) elif key.lower() == 'EndOfBalls1'.lower(): self.EndOfBalls1=int(value) elif key.lower() == 'EndOfBalls2'.lower(): self.EndOfBalls2=int(value) elif key.lower() == 'DataImportPlugin'.lower(): self.DataImportPlugin=str(value) elif key.lower() == 'WinCategories'.lower(): self.WinCategories=str(value) self._prepare_prizes_array() elif key.lower() == 'DefaultWinCost'.lower(): self.DefaultWinCost=str(value) elif key.lower() == 'GameType'.lower(): self.GameType=str(value) elif key.lower() == 'IsFonbet'.lower(): self.IsFonbet=bool(distutils.util.strtobool(value)) elif key.lower() == 'IsTop3'.lower(): self.IsTop3=bool(distutils.util.strtobool(value)) elif key.lower() == 'WithWins'.lower(): self.WithWins=bool(distutils.util.strtobool(value)) elif key.lower() == 'MultipleAppearance1'.lower(): self.MultipleAppearance1=bool(distutils.util.strtobool(value)) elif key.lower() == 'MultipleAppearance2'.lower(): self.MultipleAppearance2=bool(distutils.util.strtobool(value)) def _prepare_prizes_array(self): """из 4+1,5,...,8,8+1 сделать список['WP4S1,WP5,...WP8,WP8S1'] """ arr=self.WinCategories.split(',') self.WinCategoriesPrizesArray.clear() for line in arr: line='WP'+line.replace('+','S') self.WinCategoriesPrizesArray.append(line) pass
class ReferenceDataDlg(QDialog): def __init__(self, parent=None): super(ReferenceDataDlg, self).__init__(parent) self.model = QSqlTableModel(self) self.model.setTable("reference") self.model.setSort(ID, Qt.AscendingOrder) self.model.setHeaderData(ID, Qt.Horizontal, "ID") self.model.setHeaderData(CATEGORY, Qt.Horizontal, "小车编号") self.model.setHeaderData(SHORTDESC, Qt.Horizontal, "检查记录") self.model.setHeaderData(LONGDESC, Qt.Horizontal, "巡检日期") self.model.select() self.view = QTableView() self.view.setModel(self.model) self.view.setSelectionMode(QTableView.SingleSelection) self.view.setSelectionBehavior(QTableView.SelectRows) self.view.setColumnHidden(ID, True) self.view.resizeColumnsToContents() buttonBox = QDialogButtonBox() addButton = buttonBox.addButton("&添加", QDialogButtonBox.ActionRole) deleteButton = buttonBox.addButton("&删除", QDialogButtonBox.ActionRole) sortButton = buttonBox.addButton("&排序", QDialogButtonBox.ActionRole) if not MAC: addButton.setFocusPolicy(Qt.NoFocus) deleteButton.setFocusPolicy(Qt.NoFocus) sortButton.setFocusPolicy(Qt.NoFocus) menu = QMenu(self) sortByCategoryAction = menu.addAction("按小车编号排序") sortByDescriptionAction = menu.addAction("按检查记录排序") sortByIDAction = menu.addAction("按编号顺序排序") sortButton.setMenu(menu) closeButton = buttonBox.addButton(QDialogButtonBox.Close) layout = QVBoxLayout() layout.addWidget(self.view) layout.addWidget(buttonBox) self.setLayout(layout) addButton.clicked.connect(self.addRecord) deleteButton.clicked.connect(self.deleteRecord) sortByCategoryAction.triggered.connect(lambda: self.sort(CATEGORY)) sortByDescriptionAction.triggered.connect(lambda: self.sort(SHORTDESC)) sortByIDAction.triggered.connect(lambda: self.sort(ID)) closeButton.clicked.connect(self.accept) self.setWindowTitle("巡检历史数据") self.setWindowIcon( QtGui.QIcon('icon/update_128px_1156069_easyicon.net.ico')) def addRecord(self): row = self.model.rowCount() self.model.insertRow(row) index = self.model.index(row, CATEGORY) self.view.setCurrentIndex(index) self.view.edit(index) def deleteRecord(self): index = self.view.currentIndex() if not index.isValid(): return record = self.model.record(index.row()) category = record.value(CATEGORY) desc = record.value(SHORTDESC) if (QMessageBox.question(self, "Reference Data", ("确定删除 {1} 的数据?".format(desc, category)), QMessageBox.Yes | QMessageBox.No) == QMessageBox.No): return self.model.removeRow(index.row()) self.model.submitAll() self.model.select() def sort(self, column): self.model.setSort(column, Qt.AscendingOrder) self.model.select()
def exportToMobile(model, params): IMAGE_FORMAT = 'jpg' IMAGE_COMPRESS = 50 USED_FIELDS = ('title', 'unit', 'country', 'year', 'mint', 'mintmark', 'issuedate', 'type', 'series', 'subjectshort', 'material', 'fineness', 'diameter', 'thickness', 'weight', 'mintage', 'rarity', 'obverseimg', 'reverseimg', 'subject', 'price1', 'price2', 'price3', 'price4') if os.path.isfile(params['file']): os.remove(params['file']) db = QSqlDatabase.addDatabase('QSQLITE', 'mobile') db.setDatabaseName(params['file']) if not db.open(): print(db.lastError().text()) QMessageBox.critical(None, "Create mobile collection", "Can't open collection") return sql = """CREATE TABLE "android_metadata" ("locale" TEXT DEFAULT 'en_US')""" QSqlQuery(sql, db) sql = """INSERT INTO "android_metadata" VALUES ('en_US')""" QSqlQuery(sql, db) mobile_settings = {'Version': 1, 'Type': 'MobilePro', 'Filter': params['filter']} sql = """CREATE TABLE settings ( title CHAR NOT NULL UNIQUE, value CHAR)""" QSqlQuery(sql, db) for key, value in mobile_settings.items(): query = QSqlQuery(db) query.prepare("""INSERT INTO settings (title, value) VALUES (?, ?)""") query.addBindValue(key) query.addBindValue(str(value)) query.exec_() sql = """CREATE TABLE updates ( title CHAR NOT NULL UNIQUE, value CHAR)""" QSqlQuery(sql, db) sql = """INSERT INTO updates (title, value) VALUES ('160203', '2016-02-03T10:19:00')""" QSqlQuery(sql, db) sql = """CREATE TABLE photos ( id INTEGER PRIMARY KEY, image BLOB)""" QSqlQuery(sql, db) sql = """CREATE TABLE coins ( id INTEGER PRIMARY KEY, description_id INTEGER, grade INTEGER, createdat STRING)""" QSqlQuery(sql, db) sql = """CREATE INDEX coins_descriptions ON coins(description_id)""" QSqlQuery(sql, db) sqlFields = [] fields = CollectionFieldsBase() for field in fields: if field.name == 'id': sqlFields.append('id INTEGER PRIMARY KEY') elif field.name == 'image': sqlFields.append('image INTEGER') elif field.name in USED_FIELDS: sqlFields.append("%s %s" % (field.name, Type.toSql(field.type))) sql = "CREATE TABLE descriptions (" + ", ".join(sqlFields) + ")" QSqlQuery(sql, db) while model.canFetchMore(): model.fetchMore() dest_model = QSqlTableModel(None, db) dest_model.setEditStrategy(QSqlTableModel.OnManualSubmit) dest_model.setTable('descriptions') dest_model.select() height = 64 if params['density'] == 'HDPI': height *= 1.5 elif params['density'] == 'XHDPI': height *= 2 elif params['density'] == 'XXHDPI': height *= 3 elif params['density'] == 'XXXHDPI': height *= 4 maxHeight = height * 4 is_obverse_enabled = params['image'] in (ExportDialog.IMAGE_OBVERSE, ExportDialog.IMAGE_BOTH) is_reverse_enabled = params['image'] in (ExportDialog.IMAGE_REVERSE, ExportDialog.IMAGE_BOTH) fields = CollectionFieldsBase() count = model.rowCount() progressDlg = Gui.ProgressDialog("Exporting records", "Cancel", count, None) for i in range(count): progressDlg.step() if progressDlg.wasCanceled(): break coin = model.record(i) if coin.value('status') in ('pass', 'sold'): continue dest_record = dest_model.record() for field in fields: if field.name in ('id', 'image', 'obverseimg', 'reverseimg'): continue if field.name in USED_FIELDS: val = coin.value(field.name) if val is None or val == '': continue dest_record.setValue(field.name, val) # Process images is_obverse_present = not coin.isNull('obverseimg') is_reverse_present = not coin.isNull('reverseimg') if is_obverse_present or is_reverse_present: obverseImage = QImage() reverseImage = QImage() if is_obverse_present: ba = QtCore.QByteArray() buffer = QtCore.QBuffer(ba) buffer.open(QtCore.QIODevice.WriteOnly) obverseImage.loadFromData(coin.value('obverseimg')) if not obverseImage.isNull() and not params['fullimage'] and obverseImage.height() > maxHeight: scaledImage = obverseImage.scaled(maxHeight, maxHeight, Qt.KeepAspectRatio, Qt.SmoothTransformation) scaledImage.save(buffer, IMAGE_FORMAT, IMAGE_COMPRESS) save_data = ba else: if not obverseImage.isNull(): obverseImage.save(buffer, IMAGE_FORMAT, IMAGE_COMPRESS) save_data = ba else: save_data = coin.value('obverseimg') query = QSqlQuery(db) query.prepare("""INSERT INTO photos (image) VALUES (?)""") query.addBindValue(save_data) query.exec_() img_id = query.lastInsertId() dest_record.setValue('obverseimg', img_id) if not obverseImage.isNull(): obverseImage = obverseImage.scaledToHeight(height, Qt.SmoothTransformation) if is_reverse_present: ba = QtCore.QByteArray() buffer = QtCore.QBuffer(ba) buffer.open(QtCore.QIODevice.WriteOnly) reverseImage.loadFromData(coin.value('reverseimg')) if not reverseImage.isNull() and not params['fullimage'] and reverseImage.height() > maxHeight: scaledImage = reverseImage.scaled(maxHeight, maxHeight, Qt.KeepAspectRatio, Qt.SmoothTransformation) scaledImage.save(buffer, IMAGE_FORMAT, IMAGE_COMPRESS) save_data = ba else: if not reverseImage.isNull(): reverseImage.save(buffer, IMAGE_FORMAT, IMAGE_COMPRESS) save_data = ba else: save_data = coin.value('reverseimg') query = QSqlQuery(db) query.prepare("""INSERT INTO photos (image) VALUES (?)""") query.addBindValue(save_data) query.exec_() img_id = query.lastInsertId() dest_record.setValue('reverseimg', img_id) if not reverseImage.isNull(): reverseImage = reverseImage.scaledToHeight(height, Qt.SmoothTransformation) if not is_obverse_enabled: obverseImage = QImage() if not is_reverse_enabled: reverseImage = QImage() image = QImage(obverseImage.width() + reverseImage.width(), height, QImage.Format_RGB32) image.fill(QColor(Qt.white).rgb()) paint = QPainter(image) if is_obverse_present and is_obverse_enabled: paint.drawImage(QtCore.QRectF(0, 0, obverseImage.width(), height), obverseImage, QtCore.QRectF(0, 0, obverseImage.width(), height)) if is_reverse_present and is_reverse_enabled: paint.drawImage(QtCore.QRectF(obverseImage.width(), 0, reverseImage.width(), height), reverseImage, QtCore.QRectF(0, 0, reverseImage.width(), height)) paint.end() ba = QtCore.QByteArray() buffer = QtCore.QBuffer(ba) buffer.open(QtCore.QIODevice.WriteOnly) image.save(buffer, IMAGE_FORMAT, 75) query = QSqlQuery(db) query.prepare("""INSERT INTO photos (image) VALUES (?)""") query.addBindValue(ba) query.exec_() img_id = query.lastInsertId() dest_record.setValue('image', img_id) dest_model.insertRecord(-1, dest_record) progressDlg.setLabelText("Saving...") dest_model.submitAll() progressDlg.setLabelText("Compact...") QSqlQuery("""UPDATE descriptions SET reverseimg = (select t2.id from descriptions t3 join (select id, image from photos group by image having count(*) > 1) t2 on t1.image = t2.image join photos t1 on t3.reverseimg = t1.id where t1.id <> t2.id and t3.id = descriptions.id) WHERE descriptions.id in (select t3.id from descriptions t3 join (select id, image from photos group by image having count(*) > 1) t2 on t1.image = t2.image join photos t1 on t3.reverseimg = t1.id where t1.id <> t2.id) """, db) QSqlQuery("""UPDATE descriptions SET obverseimg = (select t2.id from descriptions t3 join (select id, image from photos group by image having count(*) > 1) t2 on t1.image = t2.image join photos t1 on t3.obverseimg = t1.id where t1.id <> t2.id and t3.id = descriptions.id) WHERE descriptions.id in (select t3.id from descriptions t3 join (select id, image from photos group by image having count(*) > 1) t2 on t1.image = t2.image join photos t1 on t3.obverseimg = t1.id where t1.id <> t2.id) """, db) QSqlQuery("""UPDATE descriptions SET image = (select t2.id from descriptions t3 join (select id, image from photos group by image having count(*) > 1) t2 on t1.image = t2.image join photos t1 on t3.image = t1.id where t1.id <> t2.id and t3.id = descriptions.id) WHERE descriptions.id in (select t3.id from descriptions t3 join (select id, image from photos group by image having count(*) > 1) t2 on t1.image = t2.image join photos t1 on t3.image = t1.id where t1.id <> t2.id) """, db) QSqlQuery("""DELETE FROM photos WHERE id NOT IN (SELECT id FROM photos GROUP BY image)""", db) db.close() progressDlg.setLabelText("Vacuum...") db = QSqlDatabase.addDatabase('QSQLITE', 'mobile') db.setDatabaseName(params['file']) if not db.open(): print(db.lastError().text()) QMessageBox.critical(None, "Create mobile collection", "Can't open collection") return QSqlQuery("VACUUM", db) db.close() progressDlg.reset()
class Contacts(QMainWindow): def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("QTableView Example") self.resize(415, 200) # Set up the model self.model = QSqlTableModel(self) self.model.setTable("contacts") self.model.setEditStrategy(QSqlTableModel.OnFieldChange) self.model.setHeaderData(0, Qt.Horizontal, "ID") self.model.setHeaderData(1, Qt.Horizontal, "Name") self.model.setHeaderData(2, Qt.Horizontal, "Job") self.model.setHeaderData(3, Qt.Horizontal, "Email") self.model.select() # Set up the view self.view = QTableView() self.view.setModel(self.model) self.view.resizeColumnsToContents() self.setCentralWidget(self.view)
class DatabaseTableView(QTableView): """customized table view""" TABLE = '' def __init__(self, db, parent=None): super().__init__(parent) self.db = db self._init_model() self._init_context_menu() def _init_model(self): self.model = QSqlTableModel(db=self.db) self.model.setTable(self.TABLE) self.model.setEditStrategy(QSqlTableModel.OnManualSubmit) self.setModel(self.model) self.model.select() def _init_context_menu(self): self.setContextMenuPolicy(Qt.CustomContextMenu) self._context_menu = QMenu(self) self.customContextMenuRequested.connect(self._on_context_menu) self._add_row_action = QAction("添加行", self) self._del_row_action = QAction("删除行", self) self._submit_action = QAction("提交修改", self) self._modify_filter_action = QAction("筛选", self) self._update_action = QAction("刷新", self) self._show_detail_action = QAction("详情", self) self._context_menu.addAction(self._add_row_action) self._context_menu.addAction(self._del_row_action) self._context_menu.addAction(self._submit_action) self._context_menu.addAction(self._modify_filter_action) self._context_menu.addAction(self._update_action) self._context_menu.addAction(self._show_detail_action) def _on_context_menu(self, pos): action = self._context_menu.exec_(self.viewport().mapToGlobal(pos)) if action == self._add_row_action: self.model.insertRows(self.model.rowCount(), 1) elif action == self._del_row_action: self.model.removeRow(self.currentIndex().row()) elif action == self._submit_action: res = self.model.submitAll() if not res: QMessageBox.warning(self, "Sql Error", self.model.lastError().text()) elif action == self._modify_filter_action: self._modify_filter() elif action == self._update_action: self._update_model() elif action == self._show_detail_action: self._show_detail() def _modify_filter(self): filter_cmd = self.model.filter() new_filter, succ = QInputDialog.getText(self, "过滤", "过滤表达式", text=filter_cmd) if succ: self.model.setFilter(new_filter) self.model.select() def _show_detail(self): row = self.currentIndex().row() idn = self.model.index(row, 0).data() if idn is None: return self._get_detail(idn).show() def _get_detail(self, idn): raise NotImplementedError() def _update_model(self): self.model.select()
sqlFields = [] fields = CollectionFieldsBase() for field in fields: if field.name == 'id': sqlFields.append('id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT') elif field.name == 'image': sqlFields.append('image INTEGER') elif field.name in SKIPPED_FIELDS: continue else: sqlFields.append("%s %s" % (field.name, Type.toSql(field.type))) sql = "CREATE TABLE coins (" + ", ".join(sqlFields) + ")" QSqlQuery(sql, db) dest_model = QSqlTableModel(None, db) dest_model.setEditStrategy(QSqlTableModel.OnManualSubmit) dest_model.setTable('coins') dest_model.select() height = 64 if density == 'HDPI': height *= 1.5 elif density == 'XHDPI': height *= 2 elif density == 'XXHDPI': height *= 3 elif density == 'XXXHDPI': height *= 4 coin_id = 0
def flags(self, index): fl = QSqlTableModel.flags(self, index) if index.column() in self.protected: fl = Qt.ItemIsEnabled | Qt.ItemIsSelectable # disable Qt.ItemIsEditable return fl
class PropertiesService(QObject): controller = None # type: PropertiesController question_type_model = None # type: QSqlTableModel question_type_filter_proxy_model = None # type: 'QuestionTypeFilterProxyModel' def __init__(self, parent=None): QObject.__init__(self, parent) self.connect_slots() def connect_slots(self): application.app.aboutToQuit.connect( self.on_about_to_quit ) def dispose(self): pass def show(self, tab_wanted: str = 'general'): from genial.services import document_service if document_service.database is not None: if self.question_type_model is None: self.question_type_model = QSqlTableModel( self, document_service.database ) self.question_type_model.setTable("question_type") self.question_type_model.setEditStrategy( QSqlTableModel.OnManualSubmit ) self.question_type_filter_proxy_model = QuestionTypeFilterProxyModel() self.question_type_filter_proxy_model.setSourceModel( self.question_type_model ) self.question_type_filter_proxy_model.sort( self.question_type_model.fieldIndex("position"), Qt.AscendingOrder ) self.question_type_filter_proxy_model.setDynamicSortFilter(True) if self.controller is None: self.controller = PropertiesController() self.controller.start() self.controller.show(tab_wanted) @pyqtSlot() def on_about_to_quit(self): self.dispose()