class VisualController(Controller): def __init__(self): super().__init__() self.results = QStringListModel(["Worker Results:"]) self.listview = QListView() self.listview.setModel(self.results) def start(self): super().start() self.listview.show() @Slot(int) def on_worker_result(self, result: int): super().on_worker_result(result) row_count = self.results.rowCount() assert self.results.insertRows(row_count, 1) new_row_idx = self.results.index(row_count, 0) self.results.setData(new_row_idx, str(result)) self._resize_to_fit_contents() def _resize_to_fit_contents(self): QApplication.processEvents() view_geo = self.listview.geometry() view_geo.setHeight( max(view_geo.height(), self.listview.contentsSize().height())) self.listview.setGeometry(view_geo)
class rename_one(QWidget): def __init__(self,parent=None): super().__init__(parent) self.mydelegate = MyDelegate() self.listview = QListView() self.mymodel = QStringListModel() self.listview.setModel(self.mymodel) # 设置我们自己的delegate self.listview.setItemDelegate(self.mydelegate) self.battle_allies=r'battle_allies' self.battle_allies_list=[] for i in range (1,11): self.battle_allies_list.append(self.battle_allies+'%s.xml'%str(i)) self.mymodel.setStringList(self.battle_allies_list) print(self.battle_allies_list) print(self.mymodel.index(2,0).data())
class LabelConfigurator(QDialog): def __init__(self, boxManager, spawnPos): super().__init__() # Variables self.spawnPos = spawnPos # Objects self.boxManager = boxManager self.layout = QVBoxLayout(self) self.contentLayout = QHBoxLayout() self.settingsLayout = QVBoxLayout() self.isOccludedButton = Check('Occluded', boxManager.getRecentIsOccluded()) self.isTruncatedButton = Check('Truncated', boxManager.getRecentIsTruncated()) self.isGroupOfButton = Check('Group Of', boxManager.getRecentIsGroupOf()) self.isDepictionButton = Check('Depiction', boxManager.getRecentIsDepiction()) self.isInsideButton = Check('Inside', boxManager.getRecentIsInside()) self.acceptButton = QPushButton('Accept') self.cancelButton = QPushButton('Cancel') self.labelsModel = QStringListModel() self.labelsView = QListView() # Layout self.setWindowFlags(Qt.Popup) self.settingsLayout.setAlignment(Qt.AlignTop | Qt.AlignCenter) self.settingsLayout.setMargin(0) self.settingsLayout.addWidget(self.isOccludedButton) self.settingsLayout.addWidget(self.isTruncatedButton) self.settingsLayout.addWidget(self.isGroupOfButton) self.settingsLayout.addWidget(self.isDepictionButton) self.settingsLayout.addWidget(self.isInsideButton) self.settingsLayout.addStretch(1) self.settingsLayout.addWidget(self.acceptButton) self.settingsLayout.addWidget(self.cancelButton) self.contentLayout.addWidget(self.labelsView) self.contentLayout.addLayout(self.settingsLayout) self.layout.addLayout(self.contentLayout) # Styling self.setStyleSheet('LabelConfigurator { ' 'background-color: ' + ThemeManager.BG_L1 + ';' 'border-top-left-radius: ' + str(ThemeManager.CURVE) + 'px;' 'border-bottom-left-radius: ' + str(ThemeManager.CURVE) + 'px;' 'border-top-right-radius: ' + str(ThemeManager.CURVE) + 'px;' 'border-bottom-right-radius: ' + str(ThemeManager.CURVE) + 'px;' 'border-width: 0px;' 'border-style: solid;' '}' 'QPushButton {' 'background-color: ' + ThemeManager.BG_L2 + ';' 'border-radius: 10px;' 'color: ' + ThemeManager.LABEL + ';' 'font-size: 14px;' '}' 'QPushButton:hover {' 'background-color: ' + ThemeManager.BG_L3 + ';' '}' 'QListView { ' 'background-color: ' + ThemeManager.BG_L2 + ';' '}') self.layout.setMargin(20) self.layout.setSpacing(10) self.contentLayout.setMargin(0) self.labelsModel.setStringList(boxManager.loadLabels()) self.labelsView.setFixedWidth(80) self.labelsView.setFrameStyle(QFrame.NoFrame) self.labelsView.setModel(self.labelsModel) self.labelsView.setItemDelegate(ListDelegate.ListDelegate()) index = None try: row = self.labelsModel.stringList().index( boxManager.getRecentLabelName()) index = self.labelsModel.index(row) except ValueError: index = self.labelsModel.index(0) if index is not None: self.labelsView.setCurrentIndex(index) # Connections self.acceptButton.clicked.connect(self.close) self.cancelButton.clicked.connect(self.reject) def showEvent(self, event): super().showEvent(event) self.move(self.spawnPos) def closeEvent(self, event): labelConfig = (self.labelsView.selectedIndexes()[0].data( role=Qt.DisplayRole), self.isOccludedButton.getEnabled(), self.isTruncatedButton.getEnabled(), self.isGroupOfButton.getEnabled(), self.isDepictionButton.getEnabled(), self.isInsideButton.getEnabled()) self.labelAccepted.emit(labelConfig) super().closeEvent(event) def getLabelConfig(self): return labelAccepted = Signal(object)
## ## $QT_BEGIN_LICENSE:GPL-EXCEPT$ ## Commercial License Usage ## Licensees holding valid commercial Qt licenses may use this file in ## accordance with the commercial license agreement provided with the ## Software or, alternatively, in accordance with the terms contained in ## a written agreement between you and The Qt Company. For licensing terms ## and conditions see https://www.qt.io/terms-conditions. For further ## information use the contact form at https://www.qt.io/contact-us. ## ## GNU General Public License Usage ## Alternatively, this file may be used under the terms of the GNU ## General Public License version 3 as published by the Free Software ## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT ## included in the packaging of this file. Please review the following ## information to ensure the GNU General Public License requirements will ## be met: https://www.gnu.org/licenses/gpl-3.0.html. ## ## $QT_END_LICENSE$ ## ############################################################################# from PySide2.QtCore import Qt, QPersistentModelIndex, QStringListModel if __name__ == '__main__': stringListModel = QStringListModel(['one', 'two']) idx = stringListModel.index(1, 0) persistentModelIndex = QPersistentModelIndex(idx) stringListModel.data(persistentModelIndex, Qt.DisplayRole)
class Query(QMainWindow): """显示试卷和练习题的容器""" def __init__(self, record_id): super().__init__() self.record_id = record_id self.session = dbSession() # 获取答题总时间和当前题号 self.totaltime, self.current_v_question_id, self.max_num = self.load_data( ) # 使用答题已用时间初始化UI self.ui = Ui_Query(self.totaltime) self.option_model = QStringListModel() self.ui.question_panel.ui.listViewOptions.setModel(self.option_model) self.update_question() # 信号连接 self.ui.about_close.connect(self.quit_action) self.ui.question_panel.ui.pushButtonPrevious.clicked.connect( self.previous_question) self.ui.question_panel.ui.pushButtonPause.clicked.connect( self.toggle_pause_question) self.ui.question_panel.ui.pushButtonNext.clicked.connect( self.next_question) self.ui.question_panel.ui.pushButtonCommit.clicked.connect( self.commit_query) self.ui.question_panel.ui.listViewOptions.clicked.connect( self.choose_option) # TODO 能不能改进,当前index改变时 self.ui.note.textChanged.connect(self.update_note) self.ui.question_panel.ui.pushButtonChooseQuestion.clicked.connect( self.open_option_panel) def load_data(self): record = self.session.query(Record).get(self.record_id) totaltime = record.totaltime # ! 新建的试卷,此值为None current_v_question_id = record.last_v_question_id if record.max_num: max_num = record.max_num else: # 所有问题的数量 -> 最大题号 v_questions = (self.session.query(V_Question).filter_by( record_id=self.record_id).all()) max_num = len(v_questions) record.max_num = max_num self.session.commit() if not current_v_question_id: # 把此值改为record_id相同的第一个 # 记录的第一个是不是就是第一题? current_v_question_id = v_questions[0].id return totaltime, current_v_question_id, max_num def update_question(self): v_question = self.session.query(V_Question).get( self.current_v_question_id) question = self.session.query(Question).get(v_question.question_id) q = f"{question.num}. {question.question}" options = [] options.append(f"A. {question.A}") options.append(f"B. {question.B}") options.append(f"C. {question.C}") options.append(f"D. {question.D}") self.ui.question_panel.ui.textEditQuestion.setHtml(q) self.option_model.setStringList(options) # 如果这道题已经被选过答案,则阴影突出答案 record = self.session.query(Q_Record).get(v_question.id) if record: row = record.chosen index = self.option_model.index(row, 0) self.ui.question_panel.ui.listViewOptions.setCurrentIndex(index) def add_operation_time(self, operation): question_operation = Q_Operation( v_question_id=self.current_v_question_id, operation=operation, datetime=QDateTime.currentDateTime().toTime_t(), ) self.session.add(question_operation) self.session.commit() def previous_question(self): # 改变model,以改变view self.add_operation_time(OP.PREVIOUS_QUESTION) self.current_v_question_id -= 1 v_question = self.session.query(V_Question).get( self.current_v_question_id) if not v_question or v_question.record_id != self.record_id: self.current_v_question_id += self.max_num self.add_operation_time(OP.PASSIVE_START) self.update_question() def toggle_pause_question(self): if self.ui.paused: self.add_operation_time(OP.PAUSE_QUESTION) else: self.add_operation_time(OP.CONTINUE_QUESTION) def next_question(self): # 改变model,以改变view self.add_operation_time(OP.NEXT_QUESTION) self.current_v_question_id += 1 v_question = self.session.query(V_Question).get( self.current_v_question_id) if not v_question or v_question.record_id != self.record_id: self.current_v_question_id -= self.max_num self.add_operation_time(OP.PASSIVE_START) self.update_question() def choose_option(self): # 0, 1, 2, 3代表 A, B, C, D choice = self.ui.question_panel.ui.listViewOptions.currentIndex().row() q_record = self.session.query(Q_Record).get(self.current_v_question_id) if q_record: q_record.chosen = choice else: q_record = Q_Record(v_question_id=self.current_v_question_id, chosen=choice) self.session.add(q_record) self.session.commit() # print(choice) self.next_question() def open_option_panel(self): self.optionPanel = Ui_optionPanel(self.max_num) # 根据131_0的格式,131为题号,0是选项A # 找到所有已经做了的题,把答案显示出来 v_questions = (self.session.query(V_Question).filter_by( record_id=self.record_id).all()) for v_question in v_questions: v_num = v_question.v_num q_record = self.session.query(Q_Record).get(v_question.id) if q_record: chosen = q_record.chosen if chosen != -1: btn = self.optionPanel.findChild(QPushButton, f"{v_num}_{chosen}") btn.set_button_chosen() self.optionPanel.show() # 找到所有的数字按钮,把点击他们的信号连接到跳转题目 for i in range(1, self.max_num + 1): btn = self.optionPanel.findChild(QPushButton, str(i)) btn.clicked.connect(self.goto_question) for j in range(4): option_btn = self.optionPanel.findChild( QPushButton, f"{i}_{j}") # TODO 这个信号连接不太优雅 option_btn.clicked.connect(self.choose_with_option_panel) def choose_with_option_panel(self): """点击答题卡,同样db中的数据也被修改,不只是UI""" option_btn = self.sender() name = option_btn.objectName() v_num, chosen = name.split("_") v_question = (self.session.query(V_Question).filter_by( record_id=self.record_id, v_num=int(v_num)).one_or_none()) q_record = self.session.query(Q_Record).get(v_question.id) # 如果鼠标点击的按钮为选中状态,则在db中也选中该选项 # 如果鼠标点击的按钮为非选中状态,则该题没有任何选项被选中 if option_btn.isChosen: q_record.chosen = int(chosen) else: q_record.chosen = -1 self.session.commit() self.update_question() def goto_question(self): """self.sender()方法能知道调用槽函数的发送者是谁,就不再需要lambda了""" self.add_operation_time(OP.GOTO_QUESTION) btn = self.sender() v_num = int(btn.objectName()) v_question = (self.session.query(V_Question).filter_by( record_id=self.record_id, v_num=v_num).one_or_none()) self.current_v_question_id = v_question.id self.add_operation_time(OP.PASSIVE_START) self.update_question() def commit_query(self): # TODO 这个提交需要终止答题 self.add_operation_time(OP.COMMIT_QUERY) self.count_question_time() # 标记记录为完成 record = (self.session.query(Record).filter_by( id=self.record_id, is_practice=False).one_or_none()) record.finished = True self.session.commit() def count_question_time(self): # 查询所有v_questions v_questions = (self.session.query(V_Question).filter_by( record_id=self.record_id).all()) # 对于每个v_question,到Q_Operation中去查找有无operation datetimes = [] for v_question in v_questions: operations = (self.session.query(Q_Operation).filter_by( v_question_id=v_question.id).all()) if operations: datetimes = [operation.datetime for operation in operations] # 两两成对,舍去最后一位 if len(datetimes) % 2: datetimes = datetimes[:-1] total = 0 j = 0 # 将每两位的差加在一起,就是该问题的总时间 while j < len(datetimes): total += datetimes[j + 1] - datetimes[j] j += 2 q_record = self.session.query(Q_Record).get(v_question.id) q_record.question_time = total self.session.commit() def update_note(self): # TODO 能不能做题时只显示本次做题的note # TODO 交卷时显示历次的note note = self.ui.note.toPlainText() q_record = self.session.query(Q_Record).get(self.current_v_question_id) q_record.note = note self.session.commit() def quit_action(self): self.add_operation_time(OP.QUIT_QUERY) print("saveing Data into DB...") # 如果本试卷还没有交卷,则计算question_time,否则不再计算question_time record = self.session.query(Record).get(self.record_id) if not record.finished: self.count_question_time() if self.ui.totaltime is 0: # ! totaltime的单位是毫秒 self.ui.totaltime = self.ui.elapsed_time.elapsed() record.totaltime = self.ui.totaltime record.last_v_question_id = self.current_v_question_id self.session.commit()