class GroupWidget(QWidget): _COLUMN_MAP = students.StudentColumnMap( columns=[ students.StudentColumn.SEQUENCE_NUM, students.StudentColumn.ID, students.StudentColumn.NAME, ]) def __init__(self, listing, student_tabs): super().__init__(student_tabs.tabs) self.listing = listing layout = QVBoxLayout() self.setLayout(layout) self.table = QTableView() self.table.setMinimumWidth(500) self.table.setMinimumHeight(300) layout.addWidget(self.table) self.model = StudentsTableModel(listing, GroupWidget._COLUMN_MAP, self) self.table.setModel(self.model) self.table.setSelectionBehavior(QTableView.SelectRows) layout.setAlignment(self.table, Qt.AlignHCenter) self._resize_table() def add_students(self, student_list): self.listing.add_students(student_list) self.listing_updated() def listing_updated(self): self.model.data_reset() self._resize_table() def _resize_table(self): self.table.resizeColumnToContents(0) self.table.horizontalHeader().setStretchLastSection(True)
def setupTable(self, data_model, query_cmdline): """Set up the main window. The SQL model used is based on data_model; The query_cmdline argument is a list of queries from the command line.""" if data_model == "read-write": # Create the model instance self.model = QSqlTableModel() # Populate the model with data. Example of using setQuery() to display data in the # table view; you would typically use setTable() to populate the model for qry in query_cmdline: query = QSqlQuery(qry) self.model.setQuery(query) elif data_model == "read-only": self.model = QSqlQueryModel() # Populate the model with data for qry in query_cmdline: self.model.setQuery(qry) table_view = QTableView() table_view.setModel(self.model) table_view.hideColumn( 0) # Useful if you don't want to view the id values table_view.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) self.setCentralWidget(table_view)
class SurveyTableView(AppWidget): def __init__(self): super().__init__() # table self.surveyTableView = QTableView() self.initTableView() # buttons self.addSurveyButton = ShrinkableButton(R.addSurveyButtonText) self.editSurveyButton = ShrinkableButton(R.editSurveyButtonText) self.deleteSurveyButton = ShrinkableButton(R.deleteSurveyButtonText) self.loadAudioButton = ShrinkableButton(R.loadAudioButtonText) self.combineButton = ShrinkableButton(R.combineButtonText) self.assemble(self.initButtons()) def initTableView(self): self.surveyTableView.setSelectionBehavior(QAbstractItemView.SelectRows) self.surveyTableView.setSelectionMode(QAbstractItemView.ExtendedSelection) self.surveyTableView.setEditTriggers(QAbstractItemView.NoEditTriggers) self.surveyTableView.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents) self.surveyTableView.setSortingEnabled(True) def initButtons(self): self.addSurveyButton.setDisabled(False) # TODO self.editSurveyButton.setDisabled(True) self.deleteSurveyButton.setDisabled(True) self.loadAudioButton.setDisabled(True) self.combineButton.setDisabled(True) buttonLayout = QHBoxLayout() buttonLayout.addWidget(self.addSurveyButton) buttonLayout.addWidget(self.editSurveyButton) buttonLayout.addWidget(self.deleteSurveyButton) buttonLayout.addWidget(self.loadAudioButton) buttonLayout.addWidget(self.combineButton) return buttonLayout def assemble(self, buttonLayout): self.mainLayout.addWidget(self.surveyTableView) self.mainLayout.addLayout(buttonLayout) @pyqtSlot(bool) def surveyMode(self, modeOn): self.surveyTableView.setDisabled(modeOn) self.addSurveyButton.setDisabled(modeOn) self.editSurveyButton.setDisabled(modeOn) self.deleteSurveyButton.setDisabled(modeOn) self.loadAudioButton.setDisabled(modeOn) self.combineButton.setDisabled(modeOn) @pyqtSlot(bool) def editMode(self, modeOn): self.surveyTableView.setEnabled(modeOn) self.addSurveyButton.setEnabled(modeOn) self.editSurveyButton.setEnabled(modeOn) self.deleteSurveyButton.setEnabled(modeOn) self.loadAudioButton.setEnabled(modeOn) self.combineButton.setEnabled(modeOn)
class MyTableViewModelSimple(QGroupBox): def __init__(self): super().__init__() self.setTitle('Simple QTableView') self.init_ui() def init_ui(self): self.model = QStandardItemModel(4, 4) # 4행 4열의 모델 정 self.model.setHorizontalHeaderLabels(['번호', '이름', '나이', '주소']) for row in range(4): for column in range(4): i = QStandardItem("row %s,column %s" % (row, column)) i.setTextAlignment(Qt.AlignCenter) self.model.setItem(row, column, i) self.tableView = QTableView() self.tableView.setModel(self.model) # self.tableView.horizontalHeader().setStretchLastSection(True) # 마지막 열은 남은 경계면을 채우기 self.tableView.horizontalHeader().setSectionResizeMode( QHeaderView.Stretch) ## 모든 열은 자동으로 당겨져서 경계면이 가득채우 layout = QVBoxLayout() layout.addWidget(self.tableView) self.setLayout(layout)
def initTableUI(self, tableView: QTableView, showLabel: dict, isSortable=True): """ 初始化tableview显示. :param tableView: tableview对象 :param showLabel: 列标题dict :param isSortable: 列是否可以排序 :return: """ if len(showLabel) > 0: # 设置模型及标题 model = QStandardItemModel() model.setColumnCount(len(showLabel)) for cindex, value in enumerate(showLabel.values()): model.setHeaderData(cindex, Qt.Horizontal, value) tableView.setModel(model) # 设置自适应列宽 tableView.horizontalHeader().setSectionResizeMode( QHeaderView.ResizeToContents) tableView.horizontalHeader().setMinimumSectionSize(100) tableView.setSortingEnabled(isSortable)
def __init__(self, parent=None, **kwargs): super().__init__(parent, **kwargs) self._file_copier = FileCopier( self, copy_complete=self.copy_complete, copy_error=self.copy_error, copy_progress=self.copy_progress, ) self._progress_dialog = ProgressDialog(self) l = QVBoxLayout(self) source_config_layout = QFormLayout() source_path_layout = QHBoxLayout() self._source_path_le = QLineEdit(self) source_path_layout.addWidget(self._source_path_le) source_path_layout.addWidget( QPushButton("Browse...", self, clicked=self._browse_for_source_path)) source_config_layout.addRow("Source:", source_path_layout) self._source_format_list = FormatList(self) source_config_layout.addRow("File Type:", self._source_format_list) source_config_layout.addRow( "", QPushButton("Find files...", self, clicked=self._find_files)) l.addLayout(source_config_layout) self._file_model = FileModel(self) table_view = QTableView(self) table_view.horizontalHeader().setStretchLastSection(True) table_view.setSelectionBehavior(QTableView.SelectRows) table_view.setModel(self._file_model) l.addWidget(table_view) dest_config_layout = QFormLayout() dest_path_layout = QHBoxLayout() self._dest_path_le = QLineEdit(self) dest_path_layout.addWidget(self._dest_path_le) dest_path_layout.addWidget( QPushButton("Browse...", self, clicked=self._browse_for_dest_path)) dest_config_layout.addRow("Destination:", dest_path_layout) l.addLayout(dest_config_layout) self._copy_pb = QPushButton("Copy...", clicked=self._start_copy) l.addWidget(self._copy_pb) with Settings() as s: if len(s["dest"]["path"]): self._dest_path_le.setText(s["dest"]["path"]) if len(s["file_type"]["file_type"]): self._source_format_list.set_selected_formats( s["file_type"]["file_type"])
def __init__(self): super().__init__() self.resize(800, 600) mainLayout = QVBoxLayout() players = ("Nadal", "Djokovic", "Federer", "Thiem", "Medvedev") model = QStandardItemModel(len(players), 1) model.setHorizontalHeaderLabels(["Player"]) for row, player in enumerate(players): item = QStandardItem(player) model.setItem(row, 0, item) filter_proxy_model = QSortFilterProxyModel() filter_proxy_model.setSourceModel(model) # case sensitive comment out this line filter_proxy_model.setFilterCaseSensitivity(Qt.CaseInsensitive) filter_proxy_model.setFilterKeyColumn(0) search_field = QLineEdit() search_field.setStyleSheet("font-size: 25px; height 30px") search_field.textChanged.connect(filter_proxy_model.setFilterRegExp) mainLayout.addWidget(search_field) table = QTableView() table.setStyleSheet("font-size: 25px") table.verticalHeader().setSectionResizeMode(QHeaderView.Stretch) table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) table.setModel(filter_proxy_model) mainLayout.addWidget(table) self.setLayout(mainLayout)
class PlanCropRotationView(ViewWidget): year = None def __init__(self): super().__init__() self.v_layout = QVBoxLayout() self.q_line_edit = QLineEdit() self.model = PlanCropRotationModel(self) self.table = QTableView() self.controller = PlanCropRotationController(self, self.model) self.init_gui() self.init_main_layout() self.init_input_form() def init_input_form(self): label = QLabel() label.setText("Введите год") label.setStyleSheet("font-size:20px;" "color:#FFFFFF") self.v_layout.addWidget(label, 0, Qt.AlignCenter) self.q_line_edit.setMaximumWidth(100) self.q_line_edit.setStyleSheet("text-align:center;" "color: #FFFFFF") self.q_line_edit.keyReleaseEvent = self.controller.key_input_form_event self.v_layout.addWidget(self.q_line_edit, 0, Qt.AlignCenter) def show_table(self): self.table.setStyleSheet("selection-background-color: #0f5b8d;" "background-color: #505052;" "color: #f0f4f7;" "font-size:14px;" "gridline-color:#324148;" "text-align:center;") self.table.horizontalHeader().setStyleSheet("background-color:#3b3b3d") self.table.setModel(self.model) self.table.keyReleaseEvent = self.controller.key_input for i in range(4): self.table.setColumnWidth(i, 240) self.table.setModel(self.model) self.table.setEditTriggers(QAbstractItemView.DoubleClicked) self.v_layout.addWidget(self.table) def show_nothing(self): label = QLabel("Ничего не найдено") label.setAlignment(Qt.AlignCenter) label.setStyleSheet("font-size:20px;" "color: #FFFFFF;" "background-color:#505052") self.v_layout.addWidget(label) def update_view(self): self.clear_layout() if self.year is not None: self.model.update(self.year) self.init_input_form() self.show_table() else: self.init_input_form() def clear_layout(self): for i in reversed(range(self.v_layout.count())): self.v_layout.itemAt(i).widget().setParent(None)
def main(args): app = QApplication(args) page = QSplitter() data = Model(1000, 10, page) selections = QItemSelectionModel(data) table = QTableView() table.setModel(data) table.setSelectionModel(selections) table.horizontalHeader().setSectionsMovable(True) table.verticalHeader().setSectionsMovable(True) # Set StaticContents to enable minimal repaints on resizes. table.viewport().setAttribute(Qt.WA_StaticContents) page.addWidget(table) tree = QTreeView() tree.setModel(data) tree.setSelectionModel(selections) tree.setUniformRowHeights(True) tree.header().setStretchLastSection(False) tree.viewport().setAttribute(Qt.WA_StaticContents) # Disable the focus rect to get minimal repaints when scrolling on Mac. tree.setAttribute(Qt.WA_MacShowFocusRect, False) page.addWidget(tree) list = QListView() list.setModel(data) list.setSelectionModel(selections) list.setViewMode(QListView.IconMode) list.setSelectionMode(QAbstractItemView.ExtendedSelection) list.setAlternatingRowColors(False) list.viewport().setAttribute(Qt.WA_StaticContents) list.setAttribute(Qt.WA_MacShowFocusRect, False) page.addWidget(list) page.setWindowIcon(QIcon(images_dir + "/interview.png")) page.setWindowTitle("Interview") page.show() return app.exec_()
def setupModelView(self): """Set up widgets, and standard item model and table view.""" user_gb = QGroupBox("Users") new_user_button = QPushButton(QIcon("images/plus.png"), "Create New User") new_user_button.setMaximumWidth(160) new_user_button.clicked.connect(self.createNewUserDialog) self.list_of_table_headers = ["First Name", "Last Name", "Profile Name", "Location"] self.model = QStandardItemModel() self.model.setHorizontalHeaderLabels(self.list_of_table_headers) table_view = QTableView() table_view.setModel(self.model) table_view.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) # Set initial row and column values self.model.setRowCount(0) self.model.setColumnCount(4) v_box = QVBoxLayout() v_box.addWidget(new_user_button, Qt.AlignLeft) v_box.addWidget(table_view) user_gb.setLayout(v_box) self.setCentralWidget(user_gb)
class Table(QWidget): def __init__(self, arg=None): super(Table, self).__init__(arg) self.initUI() def initUI(self): self.setWindowTitle("QTableView例子") self.resize(500, 300) self.model = QStandardItemModel(4, 4) self.model.setHorizontalHeaderLabels( ['title1', 'title2', 'title3', 'title4']) for row in range(4): for col in range(4): item = QStandardItem("row %s, column %s" % (row, col)) self.model.setItem(row, col, item) self.tableView = QTableView() self.tableView.setModel(self.model) self.tableView.horizontalHeader().setStretchLastSection(True) self.tableView.horizontalHeader().setSectionResizeMode( QHeaderView.Stretch) dlglayout = QVBoxLayout() dlglayout.addWidget(self.tableView) self.setLayout(dlglayout)
def setupMilitaryCombo(self): model = QSqlQueryModel(self) model.setQuery( "SELECT DISTINCT militaernummer as milnum FROM film WHERE militaernummer IS NOT NULL UNION ALL SELECT DISTINCT militaernummer_alt as milnum FROM film WHERE militaernummer_alt IS NOT NULL ORDER BY milnum", self.dbm.db) tv = QTableView() self.uiMilitaryNumberCombo.setView(tv) tv.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) tv.setSelectionMode(QAbstractItemView.SingleSelection) tv.setSelectionBehavior(QAbstractItemView.SelectRows) tv.setAutoScroll(False) self.uiMilitaryNumberCombo.setModel(model) self.uiMilitaryNumberCombo.setModelColumn(0) self.uiMilitaryNumberCombo.setInsertPolicy(QComboBox.NoInsert) tv.resizeColumnsToContents() tv.resizeRowsToContents() tv.verticalHeader().setVisible(False) tv.horizontalHeader().setVisible(True) #tv.setMinimumWidth(tv.horizontalHeader().length()) tv.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
def __init__(self, update_interval_ms, *args, **kwargs): super().__init__(*args, **kwargs) layout = QVBoxLayout() gb1 = QGroupBox("instance counts") gb1_layout = QVBoxLayout() tableView = QTableView() gcmodel = GCTableModel() tableView.setModel(gcmodel) tableView.verticalHeader().hide() tableView.horizontalHeader().setSectionResizeMode( 1, QHeaderView.ResizeToContents) tableView.horizontalHeader().setSectionResizeMode( 0, QHeaderView.Stretch) gb1_layout.addWidget(tableView) gb1.setLayout(gb1_layout) layout.addWidget(gb1) gb2 = QGroupBox("reference") gb2_layout = QHBoxLayout() gb2_layout.addStretch() pb = QPushButton("set reference") pb.clicked.connect(lambda: self.set_reference_command(True)) gb2_layout.addWidget(pb) pb = QPushButton("clear reference") pb.clicked.connect(lambda: self.set_reference_command(False)) gb2_layout.addWidget(pb) gb2_layout.addStretch() gb2.setLayout(gb2_layout) layout.addWidget(gb2) gb3 = QGroupBox("garbage collector commands") gb3_layout = QHBoxLayout() gb3_layout.addStretch() pb = QPushButton("collect(0)") pb.clicked.connect(lambda: gc.collect(0)) gb3_layout.addWidget(pb) pb = QPushButton("collect(1)") pb.clicked.connect(lambda: gc.collect(1)) gb3_layout.addWidget(pb) pb = QPushButton("collect(2)") pb.clicked.connect(lambda: gc.collect(2)) gb3_layout.addWidget(pb) gb3_layout.addStretch() gb3.setLayout(gb3_layout) layout.addWidget(gb3) self.setLayout(layout) self.reference = Counter() self.reference_time = None self.reference_active = False self.reference_command = None # None: keep; True: update reference; False: clear reference. self.gcmodel = gcmodel self.update_gc_info() self.timer = QTimer() self.timer.timeout.connect(self.update_gc_info) self.timer.start(update_interval_ms)
def main(args): app = QApplication(args) page = QSplitter() data = Model(1000, 10, page) selections = QItemSelectionModel(data) table = QTableView() table.setModel(data) table.setSelectionModel(selections) table.horizontalHeader().setSectionsMovable(True) table.verticalHeader().setSectionsMovable(True) # Set StaticContents to enable minimal repaints on resizes. table.viewport().setAttribute(Qt.WA_StaticContents) page.addWidget(table) tree = QTreeView() tree.setModel(data) tree.setSelectionModel(selections) tree.setUniformRowHeights(True) tree.header().setStretchLastSection(False) tree.viewport().setAttribute(Qt.WA_StaticContents) # Disable the focus rect to get minimal repaints when scrolling on Mac. tree.setAttribute(Qt.WA_MacShowFocusRect, False) page.addWidget(tree) list = QListView() list.setModel(data) list.setSelectionModel(selections) list.setViewMode(QListView.IconMode) list.setSelectionMode(QAbstractItemView.ExtendedSelection) list.setAlternatingRowColors(False) list.viewport().setAttribute(Qt.WA_StaticContents) list.setAttribute(Qt.WA_MacShowFocusRect, False) page.addWidget(list) page.setWindowIcon(QIcon(images_dir + '/interview.png')) page.setWindowTitle("Interview") page.show() return app.exec_()
def setupComboBox(self, editor, modelColumn): tv = QTableView() editor.setView(tv) tv.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) tv.setSelectionMode(QAbstractItemView.SingleSelection) tv.setSelectionBehavior(QAbstractItemView.SelectRows) tv.setAutoScroll(False) editor.setModel(self.model) editor.setModelColumn(modelColumn) editor.setInsertPolicy(QComboBox.NoInsert) tv.resizeColumnsToContents() tv.resizeRowsToContents() tv.verticalHeader().setVisible(False) tv.horizontalHeader().setVisible(True) #tv.setMinimumWidth(tv.horizontalHeader().length()) tv.horizontalHeader().setStretchLastSection(True) #tv.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents) tv.resizeColumnsToContents() scroll = 0 if editor.count() <= editor.maxVisibleItems( ) else QApplication.style().pixelMetric(QStyle.PM_ScrollBarExtent) tv.setMinimumWidth(tv.horizontalHeader().length() + scroll)
class CultureView(ViewWidget): def __init__(self): super().__init__() self.v_layout = QVBoxLayout() self.model = CultureModel(self) self.controller = CultureController(self.model, self) self.init_gui() self.init_main_layout() self.table = QTableView() self.show_table() def show_table(self): self.table.setStyleSheet("selection-background-color: #0f5b8d;" "background-color: #505052;" "color: #f0f4f7;" "font-size:14px;" "gridline-color:#324148;" "text-align:center;") self.table.horizontalHeader().setStyleSheet("background-color:#3b3b3d") self.table.setModel(self.model) self.table.keyReleaseEvent = self.controller.key_input for i in range(4): self.table.setColumnWidth(i, 240) self.table.setModel(self.model) self.table.setEditTriggers(QAbstractItemView.DoubleClicked) self.v_layout.addWidget(self.table) def update_view(self): self.model.update() self.clear_layout() self.show_table()
class WAtQtMain(CgAt): def __init__(self): super().__init__() self.wn_init() def wn_init(self): self.wu_wgt = QMainWindow() self.wu_wgt.setWindowTitle(GC_APP_NM) self.wu_cw = QWidget() self.wu_lo = QVBoxLayout() self.wu_tv = QTableView() self.wu_tv.verticalHeader().hide() self.wu_tv.horizontalHeader().setStretchLastSection(True) self.wu_tv.setModel(HSpellout(32345678)) self.wu_tv.scrollToBottom() self.wu_lo.addWidget(self.wu_tv) self.wu_cw.setLayout(self.wu_lo) self.wu_wgt.setCentralWidget(self.wu_cw) self.wu_wgt.resize(777, 333) self.wu_wgt.show() self.wu_wgt.raise_() self.wn_move_center() def wn_move_center(self): nu_cp = QDesktopWidget().availableGeometry().center() # center point self.wu_wgt.move(nu_cp.x() - self.wu_wgt.width() / 2, nu_cp.y() - self.wu_wgt.height() / 2)
def _createUi(self) -> None: input_box = self._createUi_input_box() table_view = QTableView(self) self._table_model = EAOCTableModel( pd.DataFrame(columns=list(_HEADER_MAP.keys())), table_view ) table_view.setModel(self._table_model) table_view.horizontalHeader().setSectionResizeMode( QHeaderView.Stretch) table_view.setMaximumHeight(300) self._eaoc_figure = Figure() self._eaoc_canvas = FigureCanvasQTAgg(self._eaoc_figure) self._eaoc_plt_tbar = NavigationToolbar2QT(self._eaoc_canvas, self) self._util_figure = Figure() self._util_canvas = FigureCanvasQTAgg(self._util_figure) self._util_plt_tbar = NavigationToolbar2QT(self._util_canvas, self) layout = QGridLayout() layout.addWidget(input_box, 0, 0, 1, 1) layout.addWidget(table_view, 0, 1, 1, 3) layout.addWidget(self._eaoc_canvas, 1, 0, 1, 2) layout.addWidget(self._eaoc_plt_tbar, 2, 0, 1, 2, Qt.AlignCenter) layout.addWidget(self._util_canvas, 1, 2, 1, 2) layout.addWidget(self._util_plt_tbar, 2, 2, 1, 2, Qt.AlignCenter) self.setLayout(layout)
def setupSearchComboBoxByQuery(self, editor, query, modelcolumn=0): model = QSqlQueryModel(self) model.setQuery(query, self.dbm.db) tv = QTableView() editor.setView(tv) tv.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) #tv.setSelectionMode(QAbstractItemView.MultiSelection) tv.setSelectionMode(QAbstractItemView.SingleSelection) tv.setSelectionBehavior(QAbstractItemView.SelectRows) tv.setAutoScroll(False) editor.setModel(model) editor.setModelColumn(modelcolumn) editor.setInsertPolicy(QComboBox.NoInsert) tv.resizeColumnsToContents() tv.resizeRowsToContents() tv.verticalHeader().setVisible(False) tv.horizontalHeader().setVisible(True) # tv.setMinimumWidth(tv.horizontalHeader().length()) tv.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) # FIXME PyQt5 AutoCompletion #editor.setAutoCompletion(True) editor.setCurrentIndex(-1)
def init_ui_status(self, main_layout): """ Build status (right side) of the UI """ # Server status area, row 0, col 1 in layout status_area = QGroupBox("Server status") status_layout = QVBoxLayout() status_area.setLayout(status_layout) main_layout.addWidget(status_area, 0, 1) # Server status table status = QTableView() status_model = QStandardItemModel() status_model.setHorizontalHeaderLabels( ["Status", "Name", "IPv4/6", "URL", "Port"]) status.setModel(status_model) # Enable alternating rows status.setAlternatingRowColors(True) # Stretch Ip and URL headers to fit any given table size status.horizontalHeader().setSectionResizeMode(2, QHeaderView.Stretch) status.horizontalHeader().setSectionResizeMode(3, QHeaderView.Stretch) # Disables user editing of this table status.setEditTriggers(QAbstractItemView.NoEditTriggers) # Set object name for our QTableView status.setObjectName("status_server_list") # Make our model easily accessible self.server_list_status = status_model # Add our table to the layout status_layout.addWidget(status)
def setupToolsDockWidget(self): """Set up the dock widget that displays different tools and themes for interacting with the chart. Also displays the data values in a table view object.""" tools_dock = QDockWidget() tools_dock.setWindowTitle("Tools") tools_dock.setMinimumWidth(400) tools_dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) # Create widgets for dock widget area themes_cb = QComboBox() themes_cb.addItems(["Light", "Cerulean Blue", "Dark", "Sand Brown", "NCS Blue", "High Contrast", "Icy Blue", "Qt"]) themes_cb.currentTextChanged.connect(self.changeChartTheme) self.animations_cb = QComboBox() self.animations_cb.addItem("No Animation", QChart.NoAnimation) self.animations_cb.addItem("Grid Animation", QChart.GridAxisAnimations) self.animations_cb.addItem("Series Animation", QChart.SeriesAnimations) self.animations_cb.addItem("All Animations", QChart.AllAnimations) self.animations_cb.currentIndexChanged.connect(self.changeAnimations) self.legend_cb = QComboBox() self.legend_cb.addItem("No Legend") self.legend_cb.addItem("Align Left", Qt.AlignLeft) self.legend_cb.addItem("Align Top", Qt.AlignTop) self.legend_cb.addItem("Align Right", Qt.AlignRight) self.legend_cb.addItem("Align Bottom", Qt.AlignBottom) self.legend_cb.currentTextChanged.connect(self.changeLegend) self.antialiasing_check_box = QCheckBox() self.antialiasing_check_box.toggled.connect(self.toggleAntialiasing) reset_button = QPushButton("Reset Chart Axes") reset_button.clicked.connect(self.resetChartZoom) # Create table view and set its model data_table_view = QTableView() data_table_view.setModel(self.model) data_table_view.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) data_table_view.verticalHeader().setSectionResizeMode(QHeaderView.Stretch) dock_form = QFormLayout() dock_form.setAlignment(Qt.AlignTop) dock_form.addRow("Themes:", themes_cb) dock_form.addRow("Animations:", self.animations_cb) dock_form.addRow("Legend:", self.legend_cb) dock_form.addRow("Anti-Aliasing", self.antialiasing_check_box) dock_form.addRow(reset_button) dock_form.addRow(data_table_view) # Create QWidget object to act as a container for dock widgets tools_container = QWidget() tools_container.setLayout(dock_form) tools_dock.setWidget(tools_container) self.addDockWidget(Qt.LeftDockWidgetArea, tools_dock) # Handles the visibility of the dock widget self.toggle_dock_tools_act = tools_dock.toggleViewAction()
class _MetadataGroupBox(QGroupBox): def __init__(self, parent: QWidget) -> None: super().__init__("Meta data:", parent) self.model = QStandardItemModel(self) self.model.setHorizontalHeaderLabels(["Key", "Value"]) self._table_view = QTableView(self) self._table_view.setModel(self.model) self._table_view.setTabKeyNavigation(False) self._table_view.horizontalHeader().setSectionResizeMode( 0, QHeaderView.ResizeToContents) self._table_view.horizontalHeader().setSectionResizeMode( 1, QHeaderView.Stretch) self._table_view.verticalHeader().setSectionsMovable(True) self._table_view.verticalHeader().setDragEnabled(True) self._table_view.verticalHeader().setDragDropMode( QAbstractItemView.InternalMove) self._table_view.verticalHeader().setDefaultSectionSize( int(self._table_view.fontMetrics().height() * 1.8)) strip = QWidget(self) add_row_button = QPushButton("Add new row", strip) del_rows_button = QPushButton("Remove selected rows", strip) strip_layout = QHBoxLayout(strip) strip_layout.setContentsMargins(0, 0, 0, 0) strip_layout.addWidget(add_row_button) strip_layout.addWidget(del_rows_button) strip_layout.addStretch() add_row_button.clicked.connect(self._on_add_button_click) del_rows_button.clicked.connect(self._on_delete_rows_button_click) layout = QVBoxLayout(self) layout.addWidget(self._table_view) layout.addWidget(strip) def get_data(self) -> dict[str, str]: metadata: dict[str, str] = OrderedDict() for y in range(self.model.rowCount()): visual_y = self._table_view.verticalHeader().visualIndex(y) key = self.model.item(visual_y, 0).text().strip() value = self.model.item(visual_y, 1).text().strip() if key and value: metadata[key] = value return metadata def _on_add_button_click(self) -> None: self.model.appendRow([QStandardItem(""), QStandardItem("")]) def _on_delete_rows_button_click(self) -> None: rows = set( index.row() for index in self._table_view.selectionModel().selectedIndexes()) for row in sorted(rows, reverse=True): self.model.removeRow(row)
def __init__(self, parent=None): super(TableWidget, self).__init__(parent) # Create a simple model for storing data. model = CustomTableModel() # Create the table view and add the model to it. tableView = QTableView() tableView.setModel(model) tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) tableView.verticalHeader().setSectionResizeMode(QHeaderView.Stretch) chart = QChart() chart.setAnimationOptions(QChart.AllAnimations) # Series 1. series = QLineSeries() series.setName("Line 1") mapper = QVXYModelMapper(self) mapper.setXColumn(0) mapper.setYColumn(1) mapper.setSeries(series) mapper.setModel(model) chart.addSeries(series) # Get the color of the series and use it for showing the mapped area. seriesColorHex = self._series_color(series) model.addMapping(seriesColorHex, QRect(0, 0, 2, model.rowCount())) # Series 2. series = QLineSeries() series.setName("Line 2") mapper = QVXYModelMapper(self) mapper.setXColumn(2) mapper.setYColumn(3) mapper.setSeries(series) mapper.setModel(model) chart.addSeries(series) # Get the color of the series and use it for showing the mapped area. seriesColorHex = self._series_color(series) model.addMapping(seriesColorHex, QRect(2, 0, 2, model.rowCount())) chart.createDefaultAxes() chartView = QChartView(chart) chartView.setRenderHint(QPainter.Antialiasing) chartView.setMinimumSize(640, 480) # Create the main layout. mainLayout = QGridLayout() mainLayout.addWidget(tableView, 1, 0) mainLayout.addWidget(chartView, 1, 1) mainLayout.setColumnStretch(1, 1) mainLayout.setColumnStretch(0, 0) self.setLayout(mainLayout)
class TextTable(QComboBox): view = None model = None index_str_map =[ [ '<p style="font-size: 20px;"></p>', '<inc>[](hl_lines="")', '<att>()', '<img src="" alt="" style="width:100px; height:200px;">' ] ] table = [["<p>", "<inc>", "<att>", "<img>"]] insert = pyqtSignal(str) def __init__(self, parent=None): super().__init__(parent=parent) self.model = TableModel(self.table, parent=self) self.view = QTableView() self.view.setMinimumSize(300, 30) self.view.setMaximumSize(300, 30) self.view.setShowGrid(False) self.view.verticalHeader().setVisible(False) self.view.horizontalHeader().setVisible(False) self.view.horizontalHeader().setSectionResizeMode(1) self.view.verticalHeader().setSectionResizeMode(1) #self.view.setMaximumWidth(200) self.view.setStyleSheet("font-size: 15px;") self.setStyleSheet('''* {font-size: 23px; border: 0px; padding: 0px; background-color: rgba(255,255,255,0);} *::down-arrow {image: url(noimg); border-width: 0px;} *::drop-down {border: none; width: 0px;} }''') self.setModel(self.model) self.setView(self.view) self.activated.connect(self.set_col) def set_col(self, index): index2 = self.view.currentIndex() if not index2.isValid(): return self.insert.emit(self.index_str_map[index][index2.column()])
def table_view_factory(self): table_view = QTableView() table_view.setSortingEnabled(True) table_view.verticalHeader().hide() table_view.horizontalHeader().setStretchLastSection(True) # the last column consumes any empty space table_view.setEditTriggers(QAbstractItemView.NoEditTriggers) # disable editing table_view.setSelectionMode(QAbstractItemView.SingleSelection) # disable multiple highlighting table_view.setSelectionBehavior(QAbstractItemView.SelectRows) # selects the row instead of just the cell return table_view
def createUi(self): toolbar = QToolBar(self) save_icon = QIcon() save_icon.addPixmap(QPixmap(":/files/save_icon.svg"), QIcon.Normal, QIcon.Off) save_action = QAction(save_icon, 'Save', self) save_action.triggered.connect(self.save_design) toolbar.addAction(save_action) above_table_view = QTableView(self) above_table_model = ExchangerDesignTableModel(self._setup, 'abv', above_table_view) above_table_view.setModel(above_table_model) above_table_view.setMinimumHeight(100) above_table_view.setMaximumHeight(150) largest_header = max(HEDFM.headers(), key=len) font = QFont() font.setBold(True) fm = QFontMetrics(font) header = above_table_view.horizontalHeader() header.setMinimumSectionSize(fm.horizontalAdvance(largest_header)) header.setSectionResizeMode(QHeaderView.Stretch) below_table_view = QTableView(self) below_table_model = ExchangerDesignTableModel(self._setup, 'blw', below_table_view) below_table_view.setModel(below_table_model) below_table_view.setMinimumHeight(100) below_table_view.setMaximumHeight(150) largest_header = max(HEDFM.headers(), key=len) fm = QFontMetrics(font) header = below_table_view.horizontalHeader() header.setMinimumSectionSize(fm.horizontalAdvance(largest_header)) header.setSectionResizeMode(QHeaderView.Stretch) self.above_view = QGraphicsView(self) self.above_scene = PinchDesignScene('abv', self._setup, self.above_view) self.above_view.setScene(self.above_scene) self.below_view = QGraphicsView(self) self.below_scene = PinchDesignScene('blw', self._setup, self.below_view) self.below_view.setScene(self.below_scene) layout = QGridLayout() layout.addWidget(toolbar, 0, 0, 1, 1) layout.addWidget(above_table_view, 1, 0, 1, 1) layout.addWidget(self.above_view, 2, 0, 1, 1) layout.addWidget(below_table_view, 1, 1, 1, 1) layout.addWidget(self.below_view, 2, 1, 1, 1) self.setLayout(layout)
class FilterSelectionScreen(SelectionScreen): """ Shows all plans and tasks in a tree view """ def __init__(self, data_context): super(FilterSelectionScreen, self).__init__(data_context) self.table_model = TableModel() self.table_model.setSourceModel(self.data_context.data_model) self.tasks_model = TasksModel() self.tasks_model.setSourceModel(self.table_model) filter_widgets = QFormLayout() self.ancestor_filter = QLineEdit() self.ancestor_filter.textChanged.connect( self.tasks_model.task_matcher.ancestor_filter) filter_widgets.addRow(QLabel("Ancestor:"), self.ancestor_filter) self.text_filter = QLineEdit() self.text_filter.textChanged.connect( self.tasks_model.task_matcher.text_filter) filter_widgets.addRow(QLabel("Text:"), self.text_filter) result_model = QStringListModel(["", "open", "success", "nil"]) self.result_filter = QComboBox() self.result_filter.setModel(result_model) self.result_filter.currentTextChanged.connect( self.tasks_model.task_matcher.result_filter) filter_widgets.addRow(QLabel("Result:"), self.result_filter) self.table_view = QTableView() self.table_view.setModel(self.tasks_model) self.table_view.setEditTriggers(QAbstractItemView.NoEditTriggers) self.table_view.setSelectionBehavior(QAbstractItemView.SelectRows) self.table_view.verticalHeader().hide() self.table_view.horizontalHeader().setStretchLastSection(True) self.table_view.selectionModel().selectionChanged.connect( self.selection_changed) self.table_view.hideColumn(TreeModelCols.DESCRIPTION) self.table_view.hideColumn(TreeModelCols.RESULT) self.table_view.hideColumn(TreeModelCols.LINK) layout = QVBoxLayout() layout.addLayout(filter_widgets) layout.addWidget(self.table_view) self.setLayout(layout) def selection_changed(self, selected, _): """ Handle changed selection """ if len(selected.indexes()) < 1: return index = selected.indexes()[0] flat_index = self.tasks_model.mapToSource(index) tree_index = self.table_model.mapToSource(flat_index) self.item_selected.emit(tree_index) def clear_selection(self): """ Called when screen is being switched to """ self.table_view.selectionModel().clearSelection()
def __init__(self, parent=None): super(TableWidget, self).__init__(parent) # Create a simple model for storing data. model = CustomTableModel() # Create the table view and add the model to it. tableView = QTableView() tableView.setModel(model) tableView.setMinimumWidth(300) tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) tableView.verticalHeader().setSectionResizeMode(QHeaderView.Stretch) chart = QChart() chart.setAnimationOptions(QChart.AllAnimations) # Series 1. series = QBarSeries() first = 3 count = 5 mapper = QVBarModelMapper(self) mapper.setFirstBarSetColumn(1) mapper.setLastBarSetColumn(4) mapper.setFirstRow(first) mapper.setRowCount(count) mapper.setSeries(series) mapper.setModel(model) chart.addSeries(series) # Get the color of the series and use it for showing the mapped area. for i, barset in enumerate(series.barSets()): seriesColorHex = hex(barset.brush().color().rgb()).upper() if seriesColorHex.endswith('L'): seriesColorHex = seriesColorHex[:-1] seriesColorHex = '#' + seriesColorHex[-6:] model.addMapping(seriesColorHex, QRect(1 + i, first, 1, barset.count())) categories = ["April", "May", "June", "July", "August"] axis = QBarCategoryAxis(chart) axis.append(categories) chart.createDefaultAxes() chart.setAxisX(axis, series) chartView = QChartView(chart) chartView.setRenderHint(QPainter.Antialiasing) chartView.setMinimumSize(640, 480) # Create the main layout. mainLayout = QGridLayout() mainLayout.addWidget(tableView, 1, 0) mainLayout.addWidget(chartView, 1, 1) mainLayout.setColumnStretch(1, 1) mainLayout.setColumnStretch(0, 0) self.setLayout(mainLayout)
def ff3_qw_tv(): fu3_tv = QTableView() fu3_tv.verticalHeader().hide() fu3_tv.horizontalHeader().setStretchLastSection(True) fu3_tv.setSelectionBehavior(QAbstractItemView.SelectRows) fu3_tv.setSelectionMode(QAbstractItemView.SingleSelection) fu3_tv.keyboardSearch = lambda x4_search: None fu3_tv.setModel(HSpellout(32345678)) fu3_tv.scrollToBottom() return fu3_tv
def __init__(self, parent=None): super().__init__(parent) self.m_model = CustomTableModel() tableView = QTableView() tableView.setModel(self.m_model) tableView.setMinimumWidth(300) tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) tableView.verticalHeader().setSectionResizeMode(QHeaderView.Stretch) self.m_model.setParent(tableView) chart = QChart() chart.setAnimationOptions(QChart.AllAnimations) series = QBarSeries() first = 3 count = 5 mapper = QVBarModelMapper(self) mapper.setFirstBarSetColumn(1) mapper.setLastBarSetColumn(4) mapper.setFirstRow(first) mapper.setRowCount(count) mapper.setSeries(series) mapper.setModel(self.m_model) chart.addSeries(series) seriesColorHex = "#000000" barsets = series.barSets() for i, barset in enumerate(barsets): seriesColorHex = barset.brush().color().name() self.m_model.addMapping( seriesColorHex, QRect(1 + i, first, 1, barset.count()) ) categories = ("April", "May", "June", "July", "August") axisX = QBarCategoryAxis() axisX.append(categories) chart.addAxis(axisX, Qt.AlignBottom) series.attachAxis(axisX) axisY = QValueAxis() chart.addAxis(axisY, Qt.AlignLeft) series.attachAxis(axisY) chartView = QChartView(chart) chartView.setRenderHint(QPainter.Antialiasing) chartView.setMinimumSize(640, 480) mainLayout = QGridLayout(self) mainLayout.addWidget(tableView, 1, 0) mainLayout.addWidget(chartView, 1, 1) mainLayout.setColumnStretch(1, 1) mainLayout.setColumnStretch(0, 0)
def create_table_view(*args): tableView = QTableView() # header size for i, width in enumerate(args): tableView.horizontalHeader().resizeSection(i, width) tableView.horizontalHeader().setStyleSheet( 'QHeaderView::section{background:#66666666}') # 배경색을 회색 # Set the alignment to the headers tableView.horizontalHeader().setDefaultAlignment(Qt.AlignCenter) # 셀 내용 수정불가 tableView.setEditTriggers(QAbstractItemView.NoEditTriggers) # hide grid tableView.setShowGrid(True) # row단위 선택 tableView.setSelectionBehavior(QAbstractItemView.SelectRows) # hide vertical header hv = tableView.verticalHeader() hv.setVisible(True) # set horizontal header properties hh = tableView.horizontalHeader() hh.setStretchLastSection(True) # set column width to fit contents tableView.resizeColumnsToContents() tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) return tableView
class AddTableDetailsView(QSplitter): """ This is a splitter widget that contains a table and a details widget. Used in the Add Show dialog. """ changed = QtCore.pyqtSignal(dict) def __init__(self, parent=None, worker=None): super().__init__(parent) self.table = QTableView() m = AddTableModel() proxy = QtCore.QSortFilterProxyModel() proxy.setSourceModel(m) self.table.setGridStyle(QtCore.Qt.NoPen) self.table.setSelectionMode(QAbstractItemView.SingleSelection) self.table.setSelectionBehavior(QAbstractItemView.SelectRows) self.table.setEditTriggers(QAbstractItemView.NoEditTriggers) self.table.setModel(proxy) self.table.setSortingEnabled(True) self.table.sortByColumn(0, QtCore.Qt.AscendingOrder) if pyqt_version is 5: self.table.horizontalHeader().setSectionResizeMode( 0, QHeaderView.Stretch) else: self.table.horizontalHeader().setResizeMode(0, QHeaderView.Stretch) self.table.selectionModel().currentRowChanged.connect( self.s_show_selected) self.addWidget(self.table) self.details = DetailsWidget(parent, worker) self.addWidget(self.details) self.setSizes([1, 1]) def s_show_selected(self, new, old=None): if not new: return index = self.table.model().mapToSource(new).row() selected_show = self.getModel().results[index] self.details.load(selected_show) self.changed.emit(selected_show) def setResults(self, results): self.getModel().setResults(results) def getModel(self): return self.table.model().sourceModel() def clearSelection(self): return self.table.clearSelection()
def _makeTable(self, model): table = QTableView(self) table.setModel(model) table.hideColumn(0) table.setShowGrid(False) subListDelegate = SubListItemDelegate() table.setItemDelegateForColumn(1, subListDelegate) table.setItemDelegateForColumn(2, subListDelegate) table.horizontalHeader().setSectionResizeMode(3, QHeaderView.Stretch) table.horizontalHeader().setSectionResizeMode(4, QHeaderView.ResizeToContents) return table
def SetupUI(self, w): info("SetupUI") # Search bar lblName = QLabel('Search') lblResults = QLabel('Results') # Plugin table ledtName = QLineEdit() tblResults = QTableView() tblResultsModel = PluginTableModel(self.available_plugins, Plugin.SQLITE_COLUMNS, w) tblResults.setModel( tblResultsModel ) tblResults.horizontalHeader().setStretchLastSection(True) tblResults.verticalHeader().setVisible(False) tblResults.resizeColumnsToContents() tblResults.setSortingEnabled(True) tblResults.setFont( QFont("Courier New", 8) ) tblResults.setShowGrid(False) ## event handlers ledtName.textChanged.connect(self.OnSearchFieldChange) # Button row btnUpdate = QPushButton("Refresh Plugins List") btnInstall = QPushButton("Install") ## event handlers btnUpdate.clicked.connect(self.RefreshPluginsList) btnInstall.clicked.connect(self.InstallSelected) grid = QGridLayout() grid.addWidget(lblName, 1, 0) grid.addWidget(ledtName, 1, 1) grid.addWidget(lblResults, 2, 0) grid.addWidget(tblResults, 2, 1, 5, 1) vbox = QVBoxLayout() vbox.addStretch(1) vbox.addWidget(btnUpdate) vbox.addWidget(btnInstall) wButtons = QWidget() wButtons.setLayout(vbox) grid.addWidget(wButtons, 5, 1, 4, 1) w.setLayout(grid) return
class UdpLogReceiver(QWidget): """ Log events generated by python logging objects. """ def __init__(self, parent=None): super().__init__(parent) self._model = LogRecordModel() filter_model = QSortFilterProxyModel() filter_model.setSourceModel(self._model) filter_model.setFilterKeyColumn(3) self.msg_filter = QLineEdit() self.log_view = QTableView() self.log_view.setModel(filter_model) header = self.log_view.horizontalHeader() #header.setSectionResizeMode(header.Stretch) header.setStretchLastSection(True) self.status_label = QLabel() # Connect signals: self.msg_filter.textChanged.connect(filter_model.setFilterFixedString) # Make nice layout: layout = QVBoxLayout(self) layout.addWidget(self.msg_filter) layout.addWidget(self.log_view) layout.addWidget(self.status_label) # Attach udp server: self._udpServer = UdpHandler(self._model) self._model.stats_changed.connect(self.status_label.setText)
class ProblemDialog(QDialog): def __init__(self, parent, model, **kwargs): flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint super().__init__(parent, flags, **kwargs) self._setupUi() self.model = model self.model.view = self self.table = ProblemTable(self.model.problem_table, view=self.tableView) self.revealButton.clicked.connect(self.model.reveal_selected_dupe) self.closeButton.clicked.connect(self.accept) def _setupUi(self): self.setWindowTitle(tr("Problems!")) self.resize(413, 323) self.verticalLayout = QVBoxLayout(self) self.label = QLabel(self) msg = tr( "There were problems processing some (or all) of the files. The cause of " "these problems are described in the table below. Those files were not " "removed from your results." ) self.label.setText(msg) self.label.setWordWrap(True) self.verticalLayout.addWidget(self.label) self.tableView = QTableView(self) self.tableView.setEditTriggers(QAbstractItemView.NoEditTriggers) self.tableView.setSelectionMode(QAbstractItemView.SingleSelection) self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows) self.tableView.setShowGrid(False) self.tableView.horizontalHeader().setStretchLastSection(True) self.tableView.verticalHeader().setDefaultSectionSize(18) self.tableView.verticalHeader().setHighlightSections(False) self.verticalLayout.addWidget(self.tableView) self.horizontalLayout = QHBoxLayout() self.revealButton = QPushButton(self) self.revealButton.setText(tr("Reveal Selected")) self.horizontalLayout.addWidget(self.revealButton) spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) self.closeButton = QPushButton(self) self.closeButton.setText(tr("Close")) self.closeButton.setDefault(True) self.horizontalLayout.addWidget(self.closeButton) self.verticalLayout.addLayout(self.horizontalLayout)
def setupViews(self): splitter = QSplitter() table = QTableView() self.pieChart = PieView() splitter.addWidget(table) splitter.addWidget(self.pieChart) splitter.setStretchFactor(0, 0) splitter.setStretchFactor(1, 1) table.setModel(self.model) self.pieChart.setModel(self.model) self.selectionModel = QItemSelectionModel(self.model) table.setSelectionModel(self.selectionModel) self.pieChart.setSelectionModel(self.selectionModel) table.horizontalHeader().setStretchLastSection(True) self.setCentralWidget(splitter)
def draw_table(): tv = QTableView() tv.setMinimumSize(400, 400) tv.setShowGrid(False) vh = tv.verticalHeader() vh.setVisible(False) hh = tv.horizontalHeader() hh.setStretchLastSection(True) tv.setSortingEnabled(True) return tv
class PreviewWidget(QWidget): def __init__(self, student_list, column_map, parent=None): super().__init__(parent) self.listing = students.GroupListing(None, student_list) self.column_map = column_map layout = QVBoxLayout() self.setLayout(layout) self.table = QTableView() self.table.setMinimumWidth(600) self.table.setMinimumHeight(300) layout.addWidget(self.table) self.model = StudentsTableModel(self.listing, column_map, self) self.table.setModel(self.model) self.table.setSelectionMode(QTableView.NoSelection) layout.setAlignment(self.table, Qt.AlignHCenter) self._resize_table() def swap_names(self): for s in self.listing.students: s.first_name, s.last_name = s.last_name, s.first_name self.model.data_reset() self._resize_table() def to_full_name(self, column): attr_name = students.ATTR_NAME[column] for s in self.listing.students: s.full_name = getattr(s, attr_name) s.first_name = '' s.last_name = '' self.column_map = self.column_map.to_full_name() self.model.data_reset(column_map=self.column_map) self._resize_table() def remove_duplicates(self): self.listing.remove_students([s for s in self.listing.students if s.is_duplicate]) self.model.data_reset() def _resize_table(self): for i in range(len(self.column_map) - 1): self.table.resizeColumnToContents(i) self.table.horizontalHeader().setStretchLastSection(True)
def createLibraryPlaylisView(self, uuid): playlistModel = PlaylistModel(uuid) playlistView = QTableView(self) playlistView.setModel(playlistModel) playlistView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) playlistView.setSortingEnabled(True) playlistView.setSelectionBehavior(QAbstractItemView.SelectRows) playlistView.setShowGrid(False) playlistView.horizontalHeader().setSectionResizeMode( QHeaderView.Stretch) playlistView.doubleClicked.connect(self._doubleCLickedWidget) playlistView.customContextMenuRequested.connect( self.customMenuRequested) self.playlistMappings[uuid] = playlistView self.insertWidget(0, playlistView) self.setCurrentWidget(self.playlistMappings[uuid])
class IgnoreListDialog(QDialog): def __init__(self, parent, model, **kwargs): flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint super().__init__(parent, flags, **kwargs) self._setupUi() self.model = model self.model.view = self self.table = IgnoreListTable(self.model.ignore_list_table, view=self.tableView) self.removeSelectedButton.clicked.connect(self.model.remove_selected) self.clearButton.clicked.connect(self.model.clear) self.closeButton.clicked.connect(self.accept) def _setupUi(self): self.setWindowTitle(tr("Ignore List")) self.resize(540, 330) self.verticalLayout = QVBoxLayout(self) self.tableView = QTableView() self.tableView.setEditTriggers(QAbstractItemView.NoEditTriggers) self.tableView.setSelectionMode(QAbstractItemView.ExtendedSelection) self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows) self.tableView.setShowGrid(False) self.tableView.horizontalHeader().setStretchLastSection(True) self.tableView.verticalHeader().setDefaultSectionSize(18) self.tableView.verticalHeader().setHighlightSections(False) self.tableView.verticalHeader().setVisible(False) self.verticalLayout.addWidget(self.tableView) self.removeSelectedButton = QPushButton(tr("Remove Selected")) self.clearButton = QPushButton(tr("Clear")) self.closeButton = QPushButton(tr("Close")) self.verticalLayout.addLayout( horizontalWrap([ self.removeSelectedButton, self.clearButton, None, self.closeButton ]) ) #--- model --> view def show(self): super().show()
class InvertedTable(SQLTable): """a Widget that displays content of an SQLite query inverted (= with rows and columns flipped); """ def __init__(self, log, mydb = ": memory :", add_color_proxy = False): self.add_color_proxy = add_color_proxy super().__init__(log, mydb) self.fill_UI() def fill_UI(self): """sets up the layout """ self.table = QTableView() header = self.table.horizontalHeader() header.hide() header.setStretchLastSection(True) self.table.resizeColumnsToContents() self.table.setAlternatingRowColors(True) self.grid.addWidget(self.table, 1, 0) self.log.debug("\t=> Table created!") def invert_model(self): """inverts the model for the table """ self.flipped_model = GUI_flipped.FlippedProxyModel() if self.model: self.log.debug("Creating the flipped model...") if self.add_color_proxy: (allele_status_column, lab_status_column) = self.add_color_proxy self.log.debug("adding status color background to columns {} and {}".format(allele_status_column, lab_status_column)) self.color_proxy = ColorProxyModel(self, allele_status_column, lab_status_column) self.color_proxy.setSourceModel(self.model) self.flipped_model.setSourceModel(self.color_proxy) else: self.flipped_model.setSourceModel(self.model) self.table.setModel(self.flipped_model) self.table.setItemDelegate(GUI_flipped.FlippedProxyDelegate(self.table)) # use flipped proxy delegate self.log.debug("\t=> Model created")
class FreezeTableWidget(QTableView): def __init__(self, model): super(FreezeTableWidget, self).__init__() self.setModel(model) self.frozenTableView = QTableView(self) self.init() self.horizontalHeader().sectionResized.connect(self.updateSectionWidth) self.verticalHeader().sectionResized.connect(self.updateSectionHeight) self.frozenTableView.verticalScrollBar().valueChanged.connect( self.verticalScrollBar().setValue) self.verticalScrollBar().valueChanged.connect( self.frozenTableView.verticalScrollBar().setValue) def init(self): self.frozenTableView.setModel(self.model()) self.frozenTableView.setFocusPolicy(Qt.NoFocus) self.frozenTableView.verticalHeader().hide() self.frozenTableView.horizontalHeader().setSectionResizeMode( QHeaderView.Fixed) self.viewport().stackUnder(self.frozenTableView) self.frozenTableView.setStyleSheet(''' QTableView { border: none; background-color: #8EDE21; selection-background-color: #999; }''') # for demo purposes self.frozenTableView.setSelectionModel(self.selectionModel()) for col in range(1, self.model().columnCount()): self.frozenTableView.setColumnHidden(col, True) self.frozenTableView.setColumnWidth(0, self.columnWidth(0)) self.frozenTableView.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.frozenTableView.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.frozenTableView.show() self.updateFrozenTableGeometry() self.setHorizontalScrollMode(self.ScrollPerPixel) self.setVerticalScrollMode(self.ScrollPerPixel) self.frozenTableView.setVerticalScrollMode(self.ScrollPerPixel) def updateSectionWidth(self, logicalIndex, oldSize, newSize): if self.logicalIndex == 0: self.frozenTableView.setColumnWidth(0, newSize) self.updateFrozenTableGeometry() def updateSectionHeight(self, logicalIndex, oldSize, newSize): self.frozenTableView.setRowHeight(logicalIndex, newSize) def resizeEvent(self, event): super(FreezeTableWidget, self).resizeEvent(event) self.updateFrozenTableGeometry() def moveCursor(self, cursorAction, modifiers): current = super(FreezeTableWidget, self).moveCursor(cursorAction, modifiers) if (cursorAction == self.MoveLeft and self.current.column() > 0 and self.visualRect(current).topLeft().x() < self.frozenTableView.columnWidth(0)): newValue = (self.horizontalScrollBar().value() + self.visualRect(current).topLeft().x() - self.frozenTableView.columnWidth(0)) self.horizontalScrollBar().setValue(newValue) return current def scrollTo(self, index, hint): if index.column() > 0: super(FreezeTableWidget, self).scrollTo(index, hint) def updateFrozenTableGeometry(self): self.frozenTableView.setGeometry( self.verticalHeader().width() + self.frameWidth(), self.frameWidth(), self.columnWidth(0), self.viewport().height() + self.horizontalHeader().height())
class TableWindow(QMainWindow): def __init__(self, title): super(TableWindow, self).__init__() # Set up the user interface from Designer. self.ui = Ui_MainWindow() self.ui.setupUi(self) self.setWindowTitle(title) self.layout = QHBoxLayout(self.ui.centralwidget) self.ui.windowTitle = title self.ui.centralwidget.setLayout(self.layout) self.tableView = QTableView() self.layout.addWidget(self.tableView) self.tableView.setHorizontalHeader(MyHeaderView(Qt.Horizontal)) self.tableView.setVerticalHeader(MyHeaderView(Qt.Vertical)) def setModel(self, model): self.tableView.setModel(model) margins = self.layout.contentsMargins() self.resize(( margins.left() + margins.right() + self.tableView.frameWidth() * 2 + self.tableView.verticalHeader().width() + self.tableView.horizontalHeader().length()), self.height())
class MainWindow(QMainWindow): def __init__(self, data): super().__init__() self.resize(400, 600) self.setWindowTitle('Logger Skeleton') self.statusBar().showMessage("Ready", 2000) # Make widgets #################################### self.tabs = QTabWidget(self) self.setCentralWidget(self.tabs) # Add tabs self.table_tab = QWidget(self) self.stats_tab = QWidget(self) self.tabs.addTab(self.table_tab, "Table") self.tabs.addTab(self.stats_tab, "Stats") # Table tab ########################################################### self.table_view = QTableView(self.table_tab) self.text_edit = QPlainTextEdit() self.btn_add_row = QPushButton("Add a row") #self.btn_remove_row = QPushButton("Remove selected rows") table_tab_vbox = QVBoxLayout() table_tab_vbox.addWidget(self.table_view) table_tab_vbox.addWidget(self.text_edit) table_tab_vbox.addWidget(self.btn_add_row) #table_tab_vbox.addWidget(self.btn_remove_row) self.table_tab.setLayout(table_tab_vbox) # Set model ####################################### my_model = DataQtModel(data, parent=self) # TODO: right use of "parent" ? # Proxy model ##################################### proxy_model = QSortFilterProxyModel(parent=self) # TODO: right use of "parent" ? proxy_model.setSourceModel(my_model) self.table_view.setModel(proxy_model) #self.table_view.setModel(my_model) # Set the view #################################### self.table_view.setSelectionBehavior(QAbstractItemView.SelectRows) # Select the full row when a cell is selected (See http://doc.qt.io/qt-5/qabstractitemview.html#selectionBehavior-prop ) #self.table_view.setSelectionMode(QAbstractItemView.SingleSelection) # Set selection mode. See http://doc.qt.io/qt-5/qabstractitemview.html#selectionMode-prop self.table_view.setAlternatingRowColors(True) self.table_view.setSortingEnabled(True) self.table_view.setColumnWidth(0, 200) # TODO: automatically get the best width self.table_view.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) # https://stackoverflow.com/q/17535563 self.table_view.setColumnHidden(COMMENT_COLUMN_INDEX, True) delegate = Delegate() self.table_view.setItemDelegate(delegate) # Set key shortcut ################################ # see https://stackoverflow.com/a/17631703 and http://doc.qt.io/qt-5/qaction.html#details # Add row action add_action = QAction(self.table_view) add_action.setShortcut(Qt.CTRL | Qt.Key_N) add_action.triggered.connect(self.add_row_btn_callback) self.table_view.addAction(add_action) # Delete action del_action = QAction(self.table_view) del_action.setShortcut(Qt.Key_Delete) del_action.triggered.connect(self.remove_row_callback) self.table_view.addAction(del_action) # Set QDataWidgetMapper ########################### self.mapper = QDataWidgetMapper() self.mapper.setModel(proxy_model) # WARNING: do not use `my_model` here otherwise the index mapping will be wrong! self.mapper.addMapping(self.text_edit, COMMENT_COLUMN_INDEX) self.mapper.toFirst() # TODO: is it a good idea ? self.table_view.selectionModel().selectionChanged.connect(self.update_selection) # Set slots ####################################### self.btn_add_row.clicked.connect(self.add_row_btn_callback) #self.btn_remove_row.clicked.connect(self.remove_row_callback) #self.table_view.setColumnHidden(1, True) # Stats tab ########################################################### # See https://matplotlib.org/examples/user_interfaces/embedding_in_qt5.html stats_tab_layout = QVBoxLayout(self.stats_tab) self.plot_canvas = PlotCanvas(data, self.stats_tab, width=5, height=4, dpi=100) stats_tab_layout.addWidget(self.plot_canvas) ################################################### #proxy_model.dataChanged.connect(plot_canvas.update_figure) #proxy_model.rowsInserted.connect(plot_canvas.update_figure) # TODO #proxy_model.rowsRemoved.connect(plot_canvas.update_figure) # TODO self.tabs.currentChanged.connect(self.updatePlot) # Update the stats plot when the tabs switch to the stats tab # Show ############################################ self.show() def update_selection(self, selected, deselected): index = self.table_view.selectionModel().currentIndex() self.mapper.setCurrentIndex(index.row()) print("Index: ", index.row()) def updatePlot(self, index): """ Parameters ---------- index Returns ------- """ if index == self.tabs.indexOf(self.stats_tab): self.plot_canvas.update_figure() def add_row_btn_callback(self): parent = QModelIndex() # More useful with e.g. tree structures #row_index = 0 # Insert new rows to the begining row_index = self.table_view.model().rowCount(parent) # Insert new rows to the end self.table_view.model().insertRows(row_index, 1, parent) def remove_row_callback(self): parent = QModelIndex() # More useful with e.g. tree structures # See http://doc.qt.io/qt-5/model-view-programming.html#handling-selections-in-item-views #current_index = self.table_view.selectionModel().currentIndex() #print("Current index:", current_index.row(), current_index.column()) selection_index_list = self.table_view.selectionModel().selectedRows() selected_row_list = [selection_index.row() for selection_index in selection_index_list] print("Current selection:", selected_row_list) #row_index = 0 # Remove the first row #row_index = self.table_view.model().rowCount(parent) - 1 # Remove the last row # WARNING: the list of rows to remove MUST be sorted in reverse order # otherwise the index of rows to remove may change at each iteration of the for loop! # TODO: there should be a lock mechanism to avoid model modifications from external sources while iterating this loop... # Or as a much simpler alternative, modify the ItemSelectionMode to forbid the non contiguous selection of rows and remove the following for loop for row_index in sorted(selected_row_list, reverse=True): # Remove rows one by one to allow the removql of non-contiguously selected rows (e.g. "rows 0, 2 and 3") success = self.table_view.model().removeRows(row_index, 1, parent) if not success: raise Exception("Unknown error...") # TODO
class CSVOptionsWindow(QWidget): def __init__(self, mainwindow): QWidget.__init__(self, mainwindow, Qt.Window) self._setupUi() self.doc = mainwindow.doc self.model = mainwindow.model.csv_options self.tableModel = CSVOptionsTableModel(self.model, self.tableView) self.model.view = self self.encodingComboBox.addItems(SUPPORTED_ENCODINGS) self.cancelButton.clicked.connect(self.hide) self.continueButton.clicked.connect(self.model.continue_import) self.targetComboBox.currentIndexChanged.connect(self.targetIndexChanged) self.layoutComboBox.currentIndexChanged.connect(self.layoutIndexChanged) self.rescanButton.clicked.connect(self.rescanClicked) def _setupUi(self): self.setWindowTitle(tr("CSV Options")) self.resize(526, 369) self.verticalLayout = QVBoxLayout(self) msg = tr( "Specify which CSV columns correspond to which transaction fields. You must also " "uncheck the \"Import\" column for lines that don\'t represent a transaction " "(header, footer, comments)." ) self.label = QLabel(msg) self.label.setWordWrap(True) self.verticalLayout.addWidget(self.label) self.gridLayout = QGridLayout() self.label_2 = QLabel(tr("Layout:")) self.gridLayout.addWidget(self.label_2, 0, 0, 1, 1) self.layoutComboBox = QComboBox(self) self.layoutComboBox.setMinimumSize(QtCore.QSize(160, 0)) self.gridLayout.addWidget(self.layoutComboBox, 0, 1, 1, 1) self.label_4 = QLabel(tr("Delimiter:")) self.gridLayout.addWidget(self.label_4, 0, 3, 1, 1) self.fieldSeparatorEdit = QLineEdit(self) self.fieldSeparatorEdit.setMaximumSize(QtCore.QSize(30, 16777215)) self.gridLayout.addWidget(self.fieldSeparatorEdit, 0, 4, 1, 1) self.targetComboBox = QComboBox(self) self.gridLayout.addWidget(self.targetComboBox, 1, 1, 1, 1) self.label_3 = QLabel(tr("Target:")) self.gridLayout.addWidget(self.label_3, 1, 0, 1, 1) self.encodingComboBox = QComboBox(self) self.gridLayout.addWidget(self.encodingComboBox, 1, 4, 1, 1) spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.gridLayout.addItem(spacerItem, 2, 2, 1, 1) self.horizontalLayout_2 = QHBoxLayout() self.horizontalLayout_2.setSpacing(0) spacerItem1 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_2.addItem(spacerItem1) self.rescanButton = QPushButton(tr("Rescan")) sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.rescanButton.sizePolicy().hasHeightForWidth()) self.rescanButton.setSizePolicy(sizePolicy) self.horizontalLayout_2.addWidget(self.rescanButton) self.gridLayout.addLayout(self.horizontalLayout_2, 2, 3, 1, 2) self.label_5 = QLabel(tr("Encoding:")) self.gridLayout.addWidget(self.label_5, 1, 3, 1, 1) self.verticalLayout.addLayout(self.gridLayout) self.tableView = QTableView(self) self.tableView.setEditTriggers(QAbstractItemView.NoEditTriggers) self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows) self.tableView.setShowGrid(False) self.tableView.horizontalHeader().setHighlightSections(False) self.tableView.verticalHeader().setVisible(False) self.tableView.verticalHeader().setDefaultSectionSize(18) self.verticalLayout.addWidget(self.tableView) self.horizontalLayout = QHBoxLayout() spacerItem2 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem2) self.cancelButton = QPushButton(tr("Cancel")) self.cancelButton.setShortcut("Esc") self.horizontalLayout.addWidget(self.cancelButton) self.continueButton = QPushButton(tr("Continue Import")) self.continueButton.setDefault(True) self.horizontalLayout.addWidget(self.continueButton) self.verticalLayout.addLayout(self.horizontalLayout) # --- Private def _newLayout(self): title = tr("New Layout") msg = tr("Choose a name for your new layout:") name, ok = QInputDialog.getText(self, title, msg) if ok and name: self.model.new_layout(name) def _renameLayout(self): title = tr("Rename Layout") msg = tr("Choose a name for your layout:") name, ok = QInputDialog.getText(self, title, msg) if ok and name: self.model.rename_selected_layout(name) # --- Event Handling def layoutIndexChanged(self, index): # This one is a little complicated. We want to only be able to select the layouts. If # anything else is clicked, we revert back to the old index. If the item has user data, # it means that an action has to be performed. if index < 0: return elif index < len(self.model.layout_names): layout_name = None if index == 0 else str(self.layoutComboBox.itemText(index)) self.model.select_layout(layout_name) else: self.layoutComboBox.setCurrentIndex(self.layoutComboBox.findText(self.model.layout.name)) data = str(self.layoutComboBox.itemData(index)) if data == NEW_LAYOUT: self._newLayout() elif data == RENAME_LAYOUT: self._renameLayout() elif data == DELETE_LAYOUT: self.model.delete_selected_layout() def rescanClicked(self): self.model.encoding_index = self.encodingComboBox.currentIndex() self.model.field_separator = str(self.fieldSeparatorEdit.text()) self.model.rescan() def targetIndexChanged(self, index): self.model.selected_target_index = index # --- model --> view # hide() is called from the model, but is already covered by QWidget def refresh_columns(self): self.tableModel.beginResetModel() self.tableModel.endResetModel() def refresh_columns_name(self): self.tableModel.refreshColumnsName() def refresh_layout_menu(self): self.layoutComboBox.currentIndexChanged.disconnect(self.layoutIndexChanged) self.layoutComboBox.clear() self.layoutComboBox.addItems(self.model.layout_names) self.layoutComboBox.insertSeparator(self.layoutComboBox.count()) self.layoutComboBox.addItem(tr("New Layout..."), NEW_LAYOUT) self.layoutComboBox.addItem(tr("Rename Selected Layout..."), RENAME_LAYOUT) self.layoutComboBox.addItem(tr("Delete Selected Layout"), DELETE_LAYOUT) self.layoutComboBox.setCurrentIndex(self.layoutComboBox.findText(self.model.layout.name)) self.layoutComboBox.currentIndexChanged.connect(self.layoutIndexChanged) def refresh_lines(self): self.tableModel.beginResetModel() self.tableModel.endResetModel() self.fieldSeparatorEdit.setText(self.model.field_separator) def refresh_targets(self): self.targetComboBox.currentIndexChanged.disconnect(self.targetIndexChanged) self.targetComboBox.clear() self.targetComboBox.addItems(self.model.target_account_names) self.targetComboBox.currentIndexChanged.connect(self.targetIndexChanged) def show(self): # For non-modal dialogs, show() is not enough to bring the window at the forefront, we have # to call raise() as well QWidget.show(self) self.raise_() def show_message(self, msg): title = "Warning" QMessageBox.warning(self, title, msg)
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.currentPath = QDir.homePath() self.model = ImageModel(self) centralWidget = QWidget() self.view = QTableView() self.view.setShowGrid(False) self.view.horizontalHeader().hide() self.view.verticalHeader().hide() self.view.horizontalHeader().setMinimumSectionSize(1) self.view.verticalHeader().setMinimumSectionSize(1) self.view.setModel(self.model) delegate = PixelDelegate(self) self.view.setItemDelegate(delegate) pixelSizeLabel = QLabel("Pixel size:") pixelSizeSpinBox = QSpinBox() pixelSizeSpinBox.setMinimum(4) pixelSizeSpinBox.setMaximum(32) pixelSizeSpinBox.setValue(12) fileMenu = QMenu("&File", self) openAction = fileMenu.addAction("&Open...") openAction.setShortcut("Ctrl+O") self.printAction = fileMenu.addAction("&Print...") self.printAction.setEnabled(False) self.printAction.setShortcut("Ctrl+P") quitAction = fileMenu.addAction("E&xit") quitAction.setShortcut("Ctrl+Q") helpMenu = QMenu("&Help", self) aboutAction = helpMenu.addAction("&About") self.menuBar().addMenu(fileMenu) self.menuBar().addSeparator() self.menuBar().addMenu(helpMenu) openAction.triggered.connect(self.chooseImage) self.printAction.triggered.connect(self.printImage) quitAction.triggered.connect(QApplication.instance().quit) aboutAction.triggered.connect(self.showAboutBox) pixelSizeSpinBox.valueChanged.connect(delegate.setPixelSize) pixelSizeSpinBox.valueChanged.connect(self.updateView) controlsLayout = QHBoxLayout() controlsLayout.addWidget(pixelSizeLabel) controlsLayout.addWidget(pixelSizeSpinBox) controlsLayout.addStretch(1) mainLayout = QVBoxLayout() mainLayout.addWidget(self.view) mainLayout.addLayout(controlsLayout) centralWidget.setLayout(mainLayout) self.setCentralWidget(centralWidget) self.setWindowTitle("Pixelator") self.resize(640, 480) def chooseImage(self): fileName, _ = QFileDialog.getOpenFileName(self, "Choose an Image", self.currentPath, '*') if fileName: self.openImage(fileName) def openImage(self, fileName): image = QImage() if image.load(fileName): self.model.setImage(image) if not fileName.startswith(':/'): self.currentPath = fileName self.setWindowTitle("%s - Pixelator" % self.currentPath) self.printAction.setEnabled(True) self.updateView() def printImage(self): if self.model.rowCount(QModelIndex()) * self.model.columnCount(QModelIndex()) > 90000: answer = QMessageBox.question(self, "Large Image Size", "The printed image may be very large. Are you sure that " "you want to print it?", QMessageBox.Yes | QMessageBox.No) if answer == QMessageBox.No: return printer = QPrinter(QPrinter.HighResolution) dlg = QPrintDialog(printer, self) dlg.setWindowTitle("Print Image") if dlg.exec_() != QDialog.Accepted: return painter = QPainter() painter.begin(printer) rows = self.model.rowCount(QModelIndex()) columns = self.model.columnCount(QModelIndex()) sourceWidth = (columns+1) * ItemSize sourceHeight = (rows+1) * ItemSize painter.save() xscale = printer.pageRect().width() / float(sourceWidth) yscale = printer.pageRect().height() / float(sourceHeight) scale = min(xscale, yscale) painter.translate(printer.pageRect().x()+printer.pageRect().width()/2, printer.pageRect().y()+printer.pageRect().height()/2) painter.scale(scale, scale) painter.translate(-sourceWidt/2, -sourceHeight/2) option = QStyleOptionViewItem() parent = QModelIndex() progress = QProgressDialog("Printing...", "Cancel", 0, rows, self) y = ItemSize / 2.0 for row in range(rows): progress.setValue(row) QApplication.processEvents() if progress.wasCanceled(): break x = ItemSize / 2.0 for col in range(columns): option.rect = QRect(x, y, ItemSize, ItemSize) self.view.itemDelegate.paint(painter, option, self.model.index(row, column, parent)) x = x + ItemSize y = y + ItemSize progress.setValue(rows) painter.restore() painter.end() if progress.wasCanceled(): QMessageBox.information(self, "Printing canceled", "The printing process was canceled.", QMessageBox.Cancel) def showAboutBox(self): QMessageBox.about(self, "About the Pixelator example", "This example demonstrates how a standard view and a custom\n" "delegate can be used to produce a specialized " "representation\nof data in a simple custom model.") def updateView(self): self.view.resizeColumnsToContents() self.view.resizeRowsToContents()
class MainWindow(QMainWindow): def __init__(self,system): super(MainWindow, self).__init__() self.system = system fileMenu = QMenu("&Menu", self) dbinitAction = fileMenu.addAction("사용자 정보 초기화") quitAction = fileMenu.addAction("E&xit") quitAction.setShortcut("Ctrl+Q") self.menuBar().addMenu(fileMenu) self.statusBar() dbinitAction.triggered.connect(self.ClickAction_dbinit) quitAction.triggered.connect(QApplication.instance().quit) self.setupModel() self.setupViews() self.readDB() self.setWindowTitle("PyStudy 학습진도창") self.resize(870, 550) def setupModel(self): self.model = QStandardItemModel(3, 2, self) self.model.setHeaderData(0, Qt.Horizontal, "목록") self.model.setHeaderData(1, Qt.Horizontal, "읽기여부") self.model2 = QStandardItemModel(3, 2, self) self.model2.setHeaderData(0, Qt.Horizontal, "학습여부") self.model2.setHeaderData(1, Qt.Horizontal, "개수") def setupViews(self): splitter = QSplitter() self.table = QTableView() self.pieChart = PieView() splitter.addWidget(self.pieChart) splitter.addWidget(self.table) splitter.setStretchFactor(0, 0) splitter.setStretchFactor(1, 0) self.table.setModel(self.model) self.pieChart.setModel(self.model2) self.selectionModel = QItemSelectionModel(self.model2) self.table.setSelectionModel(self.selectionModel) #self.pieChart.setSelectionModel(self.selectionModel) #table.setColumnWidth(0,100) self.setCentralWidget(splitter) self.table.doubleClicked.connect(self.ClickAction_table) def readDB(self): con = sqlite3.connect("mystudy.db") cur = con.cursor() cur.execute("select subject, readcheck from study;") self.model.removeRows(0, self.model.rowCount(QModelIndex()), QModelIndex()) self.model2.removeRows(0, self.model2.rowCount(QModelIndex()), QModelIndex()) row = 0 for line in cur: if line[1] ==1: result = "○" else: result = "X" self.model.insertRows(row, 1, QModelIndex()) self.model.setData(self.model.index(row, 0, QModelIndex()), line[0]) self.model.setData(self.model.index(row, 1, QModelIndex()),result) self.model.setData(self.model.index(row, 1, QModelIndex()), QVariant(Qt.AlignCenter),Qt.TextAlignmentRole) row += 1 cur.execute("select count() from study ;") for line in cur: self.studyTotal =line[0] cur.execute("select count() from study where readcheck=1;") for line in cur: self.studyRead =line[0] #print("총 개수 " ,self.studyTotal ," 학습한개수", self.studyRead ) con.close() row=0 self.model2.insertRows(row, 1, QModelIndex()) self.model2.setData(self.model2.index(row, 0, QModelIndex()),"학습") self.model2.setData(self.model2.index(row, 1, QModelIndex()), float(self.studyRead)) self.model2.setData(self.model2.index(row, 0, QModelIndex()), QColor("#99e600"), Qt.DecorationRole) row=1 self.model2.insertRows(row, 1, QModelIndex()) self.model2.setData(self.model2.index(row, 0, QModelIndex()),"미학습") self.model2.setData(self.model2.index(row, 1, QModelIndex()), float(self.studyTotal-self.studyRead)) self.model2.setData(self.model2.index(row, 0, QModelIndex()), QColor("#8080b3"), Qt.DecorationRole) self.table.setSelectionBehavior(QAbstractItemView.SelectRows) self.table.setSelectionMode(QAbstractItemView.SingleSelection) self.table.setDragEnabled(False) self.table.horizontalHeader().setStretchLastSection(True) self.table.setEditTriggers(QAbstractItemView.NoEditTriggers) self.table.resizeRowsToContents() self.table.resizeColumnsToContents() self.table.setColumnWidth(0,350) #self.statusBar().showMessage("Loaded %s" % path, 2000) def ClickAction_table(self,index): #self.system #index.data() #self.table.selectedIndexes()[0].data() tempstr = self.table.selectedIndexes()[0].data().split() filepath = r"PyStudy_web\\example\\기본예제\\"+tempstr[0]+".html" selectedRowKey = self.table.selectedIndexes()[0].row()+1#mysql 테이블 줄수 차이 #print("click test ",selectedRowKey ) con = sqlite3.connect("mystudy.db") cur = con.cursor() cur.execute("update 'study' set 'readcheck'=1 where key="+str(selectedRowKey)+";") con.commit() con.close() self.setupViews() self.readDB() self.system.sendMessage("/학습창 열기 "+filepath) def ClickAction_dbinit(self,index): con = sqlite3.connect("mystudy.db") cur = con.cursor() cur.execute("update 'study' set 'readcheck'=0 ;") con.commit() con.close() self.setupViews() self.readDB()
class DataGrid(QWidget): def __init__(self): super().__init__() self.setWindowTitle("分页查询例子") self.resize(750,300) # 查询模型 self.queryModel = None # 数据表 self.tableView = None # 总数页文本 self.totalPageLabel = None # 当前页文本 self.currentPageLabel = None # 转到页输入框 self.switchPageLineEdit = None # 前一页按钮 self.prevButton = None # 后一页按钮 self.nextButton = None # 转到页按钮 self.switchPageButton = None # 当前页 self.currentPage = 0 # 总页数 self.totalPage = 0 # 总记录数 self.totalRecrodCount = 0 # 每页显示记录数 self.PageRecordCount = 5 self.initUI() def initUI(self): # 创建窗口 self.createWindow() # 设置表格 self.setTableView() # 信号槽连接 self.prevButton.clicked.connect(self.onPrevButtonClick ) self.nextButton.clicked.connect(self.onNextButtonClick ) self.switchPageButton.clicked.connect(self.onSwitchPageButtonClick ) # 创建数据库 # 创建窗口 def createWindow(self): # 操作布局 operatorLayout = QHBoxLayout() self.prevButton = QPushButton("前一页") self.nextButton = QPushButton("后一页") self.switchPageButton = QPushButton("Go") self.switchPageLineEdit = QLineEdit() self.switchPageLineEdit.setFixedWidth(40) switchPage = QLabel("转到第") page = QLabel("页") operatorLayout.addWidget(self.prevButton) operatorLayout.addWidget(self.nextButton) operatorLayout.addWidget(switchPage) operatorLayout.addWidget(self.switchPageLineEdit) operatorLayout.addWidget(page) operatorLayout.addWidget(self.switchPageButton) operatorLayout.addWidget( QSplitter()) # 状态布局 statusLayout = QHBoxLayout() self.totalPageLabel = QLabel() self.totalPageLabel.setFixedWidth(70) self.currentPageLabel = QLabel() self.currentPageLabel.setFixedWidth(70) self.totalRecordLabel = QLabel() self.totalRecordLabel.setFixedWidth(70) statusLayout.addWidget(self.totalPageLabel) statusLayout.addWidget(self.currentPageLabel) statusLayout.addWidget( QSplitter() ) statusLayout.addWidget(self.totalRecordLabel) # 设置表格属性 self.tableView = QTableView() # 表格宽度的自适应调整 self.tableView.horizontalHeader().setStretchLastSection(True) self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) # 创建界面 mainLayout = QVBoxLayout(self); mainLayout.addLayout(operatorLayout); mainLayout.addWidget(self.tableView); mainLayout.addLayout(statusLayout); self.setLayout(mainLayout) # 设置表格 def setTableView(self): print('*** step2 SetTableView' ) # 声明查询模型 self.queryModel = QSqlQueryModel(self) # 设置当前页 self.currentPage = 1; # 得到总记录数 self.totalRecrodCount = self.getTotalRecordCount() # 得到总页数 self.totalPage = self.getPageCount() # 刷新状态 self.updateStatus() # 设置总页数文本 self.setTotalPageLabel() # 设置总记录数 self.setTotalRecordLabel() # 记录查询 self.recordQuery(0) # 设置模型 self.tableView.setModel(self.queryModel) print('totalRecrodCount=' + str(self.totalRecrodCount) ) print('totalPage=' + str(self.totalPage) ) # 设置表格表头 self.queryModel.setHeaderData(0,Qt.Horizontal,"编号") self.queryModel.setHeaderData(1,Qt.Horizontal,"姓名") self.queryModel.setHeaderData(2,Qt.Horizontal,"性别") self.queryModel.setHeaderData(3,Qt.Horizontal,"年龄") self.queryModel.setHeaderData(4,Qt.Horizontal,"院系") # 得到记录数 def getTotalRecordCount(self): self.queryModel.setQuery("select * from student") rowCount = self.queryModel.rowCount() print('rowCount=' + str(rowCount) ) return rowCount # 得到页数 def getPageCount(self): if self.totalRecrodCount % self.PageRecordCount == 0 : return (self.totalRecrodCount / self.PageRecordCount ) else : return (self.totalRecrodCount / self.PageRecordCount + 1) # 记录查询 def recordQuery(self, limitIndex ): szQuery = ("select * from student limit %d,%d" % ( limitIndex , self.PageRecordCount ) ) print('query sql=' + szQuery ) self.queryModel.setQuery(szQuery) # 刷新状态 def updateStatus(self): szCurrentText = ("当前第%d页" % self.currentPage ) self.currentPageLabel.setText( szCurrentText ) #设置按钮是否可用 if self.currentPage == 1 : self.prevButton.setEnabled( False ) self.nextButton.setEnabled( True ) elif self.currentPage == self.totalPage : self.prevButton.setEnabled( True ) self.nextButton.setEnabled( False ) else : self.prevButton.setEnabled( True ) self.nextButton.setEnabled( True ) # 设置总数页文本 def setTotalPageLabel(self): szPageCountText = ("总共%d页" % self.totalPage ) self.totalPageLabel.setText(szPageCountText) # 设置总总记录数 def setTotalRecordLabel(self): szTotalRecordText = ("共%d条" % self.totalRecrodCount ) print('*** setTotalRecordLabel szTotalRecordText=' + szTotalRecordText ) self.totalRecordLabel.setText(szTotalRecordText) # 前一页按钮按下 def onPrevButtonClick(self): print('*** onPrevButtonClick '); limitIndex = (self.currentPage - 2) * self.PageRecordCount self.recordQuery( limitIndex) self.currentPage -= 1 self.updateStatus() # 后一页按钮按下 def onNextButtonClick(self): print('*** onNextButtonClick '); limitIndex = self.currentPage * self.PageRecordCount self.recordQuery( limitIndex) self.currentPage += 1 self.updateStatus() # 转到页按钮按下 def onSwitchPageButtonClick(self): # 得到输入字符串 szText = self.switchPageLineEdit.text() #数字正则表达式 pattern = re.compile(r'^[-+]?[0-9]+\.[0-9]+$') match = pattern.match(szText) # 判断是否为数字 if not match : QMessageBox.information(self, "提示", "请输入数字" ) return # 是否为空 if szText == '' : QMessageBox.information(self, "提示" , "请输入跳转页面" ) return #得到页数 pageIndex = int(szText) #判断是否有指定页 if pageIndex > self.totalPage or pageIndex < 1 : QMessageBox.information(self, "提示", "没有指定的页面,请重新输入" ) return #得到查询起始行号 limitIndex = (pageIndex-1) * self.PageRecordCount #记录查询 self.recordQuery(limitIndex); #设置当前页 self.currentPage = pageIndex #刷新状态 self.updateStatus();
class SubtitleEditor(SubTab): def __init__(self, filePath, subtitleData, parent = None): name = os.path.split(filePath)[1] super(SubtitleEditor, self).__init__(name, parent) self.__initWidgets() self.__initContextMenu() self._settings = SubSettings() self._filePath = filePath self._movieFilePath = None self._subtitleData = subtitleData self.refreshSubtitles() # Some signals self._subtitleData.fileChanged.connect(self.fileChanged) self._subtitleData.subtitlesAdded.connect(self._subtitlesAdded) self._subtitleData.subtitlesRemoved.connect(self._subtitlesRemoved) self._subtitleData.subtitlesChanged.connect(self._subtitlesChanged) self._model.itemChanged.connect(self._subtitleEdited) self.customContextMenuRequested.connect(self.showContextMenu) def __initWidgets(self): minimalSizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) # List of subtitles subListDelegate = SubListItemDelegate() self._model = QStandardItemModel(0, 3, self) self._model.setHorizontalHeaderLabels([_("Begin"), _("End"), _("Subtitle")]) self._subList = QTableView(self) self._subList.setModel(self._model) self._subList.setItemDelegateForColumn(0, subListDelegate) self._subList.setItemDelegateForColumn(1, subListDelegate) self._subList.horizontalHeader().setSectionResizeMode(2, QHeaderView.Stretch) self._searchBar = SearchBar(self) self._searchBar.hide() # Top toolbar toolbar = QHBoxLayout() toolbar.setAlignment(Qt.AlignLeft) #toolbar.addWidget(someWidget....) toolbar.addStretch(1) # Main layout grid = QGridLayout() grid.setSpacing(10) grid.setContentsMargins(0, 3, 0, 0) grid.addLayout(toolbar, 0, 0, 1, 1) # stretch to the right grid.addWidget(self._subList, 1, 0) grid.addWidget(self._searchBar, 2, 0) self.setLayout(grid) def __initContextMenu(self): self._contextMenu = QMenu(self) self.setContextMenuPolicy(Qt.CustomContextMenu) af = ActionFactory(self) insertSub = af.create(title = _("&Insert subtitle"), icon = "list-add", connection = self.insertNewSubtitle) self._contextMenu.addAction(insertSub) insertSub = af.create(title = _("&Add subtitle"), icon = "list-add", connection = self.addNewSubtitle) self._contextMenu.addAction(insertSub) removeSub = af.create(title = _("&Remove subtitles"), icon = "list-remove", connection = self.removeSelectedSubtitles) self._contextMenu.addAction(removeSub) def _changeRowBackground(self, rowNo, bg): with DisableSignalling(self._model.itemChanged, self._subtitleEdited): for columnNo in range(self._model.columnCount()): item = self._model.item(rowNo, columnNo) item.setBackground(bg) def _changeItemData(self, item, val, role): with DisableSignalling(self._model.itemChanged, self._subtitleEdited): item.setData(val, role) def _handleIncorrectItem(self, item): with DisableSignalling(self._model.itemChanged, self._subtitleEdited): item.setData(False, CustomDataRoles.ErrorFlagRole) bg = item.background() rowNo = item.row() self._changeRowBackground(rowNo, Qt.red) QTimer.singleShot(600, lambda rowNo=rowNo, bg=bg: self._changeRowBackground(rowNo, bg)) def _subtitleEdited(self, item): modelIndex = item.index() column = modelIndex.column() subNo = modelIndex.row() errorFlag = item.data(CustomDataRoles.ErrorFlagRole) if errorFlag is True: self._handleIncorrectItem(item) else: # TODO: timeStart and timeEnd might be displayed in a frame format in a bright future. # Check it and create FrameTime properly in that case. # TODO: Maybe add column numbers to some kind of enum to avoid magic numbers? oldSubtitle = self.subtitles[subNo] newSubtitle = oldSubtitle.clone() if 0 == column: timeStart = item.data(CustomDataRoles.FrameTimeRole) newSubtitle.change(start = timeStart) elif 1 == column: timeEnd = item.data(CustomDataRoles.FrameTimeRole) newSubtitle.change(end = timeEnd) elif 2 == column: newSubtitle.change(text = item.text()) command = ChangeSubtitle(self.filePath, oldSubtitle, newSubtitle, subNo) self._subtitleData.execute(command) def _subtitlesAdded(self, path, subNos): if path != self.filePath: return subtitles = self.subtitles for subNo in subNos: row = createRow(subtitles[subNo]) self._model.insertRow(subNo, row) def _subtitlesRemoved(self, path, subNos): if path != self.filePath: return for subNo in subNos: self._model.removeRow(subNo) def _subtitlesChanged(self, path, subNos): if path != self.filePath: return for subNo in subNos: self.refreshSubtitle(subNo) def _createNewSubtitle(self, data, subNo): fps = data.fps # data is passed to avoid unnecessary copies minFrameTime = FrameTime(fps, frames = 1) # calculate correct minimum subtitle start time if subNo > 0: timeStart = data.subtitles[subNo - 1].end + minFrameTime else: timeStart = FrameTime(fps, frames = 0) # calculate correct maximum subtitle end time if subNo < data.subtitles.size(): try: timeEnd = data.subtitles[subNo].start - minFrameTime except SubException: timeEnd = FrameTime(fps, frames = 0) else: timeEnd = timeStart + FrameTime(fps, frames = 50) # add subtitle to DataModel sub = Subtitle(timeStart, timeEnd, "") command = AddSubtitle(self.filePath, subNo, sub) with DisableSignalling(self._subtitleData.subtitlesAdded, self._subtitlesAdded): self._subtitleData.execute(command) # create subtitle graphical representation in editor sub list row = createRow(sub) self._model.insertRow(subNo, row) index = self._model.index(subNo, 2) self._subList.clearSelection() self._subList.setCurrentIndex(index) self._subList.edit(index) def addNewSubtitle(self): data = self.data subNo = data.subtitles.size() indices = self._subList.selectedIndexes() if len(indices) > 0: rows = [index.row() for index in indices] subNo = max(rows) + 1 self._createNewSubtitle(data, subNo) def insertNewSubtitle(self): data = self.data subNo = 0 indices = self._subList.selectedIndexes() if len(indices) > 0: rows = [index.row() for index in indices] subNo = max(rows) self._createNewSubtitle(data, subNo) def removeSelectedSubtitles(self): indices = self._subList.selectedIndexes() if len(indices) > 0: rows = list(set([index.row() for index in indices])) command = RemoveSubtitles(self.filePath, rows) self._subtitleData.execute(command) if self._model.rowCount() > rows[-1]: self._subList.selectRow(rows[-1]) else: self._subList.selectRow(self._model.rowCount() - 1) def highlight(self): self._searchBar.show() self._searchBar.highlight() def showContextMenu(self): self._contextMenu.exec(QCursor.pos()) def changeInputEncoding(self, encoding): data = self._subtitleData.data(self.filePath) if encoding != data.inputEncoding: try: data.encode(encoding) except UnicodeDecodeError: message = QMessageBox( QMessageBox.Warning, _("Decoding error"), _("Cannot decode subtitles to '%s' encoding.\nPlease try different encoding.") % encoding, QMessageBox.Ok, self ) message.exec() except LookupError: message = QMessageBox(QMessageBox.Warning, _("Unknown encoding"), _("Unknown encoding: '%s'") % encoding, QMessageBox.Ok, self ) message.exec() else: # TODO: outputEncoding command = ChangeData(self.filePath, data, _("Input encoding: %s") % encoding) self._subtitleData.execute(command) def changeOutputEncoding(self, encoding): data = self._subtitleData.data(self.filePath) if encoding != data.outputEncoding: data.outputEncoding = encoding command = ChangeData(self.filePath, data, _("Output encoding: %s") % encoding) self._subtitleData.execute(command) def changeSubFormat(self, fmt): data = self._subtitleData.data(self.filePath) if data.outputFormat != fmt: data.outputFormat = fmt command = ChangeData(self.filePath, data) self._subtitleData.execute(command) def changeFps(self, fps): data = self.data if data.fps != fps: data.subtitles.changeFps(fps) data.fps = fps command = ChangeData(self.filePath, data, _("FPS: %s") % fps) self._subtitleData.execute(command) def changeVideoPath(self, path): data = self.data if data.videoPath != path: data.videoPath = path command = ChangeData(self.filePath, data, _("Video path: %s") % path) self._subtitleData.execute(command) def offset(self, seconds): data = self.data fps = data.subtitles.fps if fps is None: log.error(_("No FPS for '%s' (empty subtitles)." % self.filePath)) return ft = FrameTime(data.subtitles.fps, seconds=seconds) data.subtitles.offset(ft) command = ChangeData(self.filePath, data, _("Offset by: %s") % ft.toStr()) self._subtitleData.execute(command) def detectFps(self): data = self.data if data.videoPath is not None: fpsInfo = File.detectFpsFromMovie(data.videoPath) if data.videoPath != fpsInfo.videoPath or data.fps != fpsInfo.fps: data.videoPath = fpsInfo.videoPath data.subtitles.changeFps(fpsInfo.fps) data.fps = fpsInfo.fps command = ChangeData(self.filePath, data, _("Detected FPS: %s") % data.fps) self._subtitleData.execute(command) def fileChanged(self, filePath): if filePath == self._filePath: self.refreshSubtitles() def refreshSubtitle(self, subNo): sub = self.subtitles[subNo] self._model.removeRow(subNo) self._model.insertRow(subNo, createRow(sub)) def refreshSubtitles(self): self._model.removeRows(0, self._model.rowCount()) for sub in self.subtitles: self._model.appendRow(createRow(sub)) def updateTab(self): self.refreshSubtitles() def selectedSubtitles(self): rows = self.selectedRows() subtitleList = [self.subtitles[row] for row in rows] return subtitleList def selectedRows(self): indices = self._subList.selectedIndexes() # unique list rows = list(set([index.row() for index in indices])) rows.sort() return rows def selectRow(self, row): self._subList.selectRow(row) @property def filePath(self): return self._filePath @property def movieFilePath(self): return self._movieFilePath @property def data(self): return self._subtitleData.data(self.filePath) @property def subtitles(self): return self.data.subtitles @property def history(self): return self._subtitleData.history(self.filePath) @property def inputEncoding(self): return self.data.inputEncoding @property def outputEncoding(self): return self.data.outputEncoding @property def outputFormat(self): return self.data.outputFormat
def initUI(self): #ReplaceModel ReplaceModel=QStandardItemModel() ReplaceModel.setColumnCount(3) ReplaceModel.setHorizontalHeaderLabels(["Найти","Заменить на","Настройки"]) #/ReplaceModel #replaceTable replaceTable = QTableView(self) #replaceTable.setToolTip("Таблица поиска и замены,\nдобавьте строку и заполните текст для поиска и замены,\nвы также можете выбрать индивидуальные опции поиска для данной строки") #replaceTable.horizontalHeader().setToolTip("Найти - Текст для поиска\nЗаменить - Текст замены\nЗн. - Подстановочные знаки\nЦв. - Выделение цветом\nЖ - Выделение жирным шрифтом\nН - Изменять надписи\nWA - Изменять объкты WordArt") replaceTable.setModel(ReplaceModel) replaceTable.horizontalHeader().setSectionResizeMode(1, QHeaderView.Stretch) replaceTable.horizontalHeader().setSectionResizeMode(2, QHeaderView.ResizeToContents) replaceTable.horizontalHeader().setSectionResizeMode(3, QHeaderView.ResizeToContents) """replaceTable.horizontalHeader().setSectionResizeMode(4, QHeaderView.ResizeToContents) replaceTable.horizontalHeader().setSectionResizeMode(5, QHeaderView.ResizeToContents) replaceTable.horizontalHeader().setSectionResizeMode(6, QHeaderView.ResizeToContents)""" replaceTable.horizontalHeader().resizeSection(0,500) replaceTable.setItemDelegateForColumn(0,PlainTextEditDelegate(replaceTable)) replaceTable.setItemDelegateForColumn(1,PlainTextEditDelegate(replaceTable)) #btnDeleg=ButtonDelegate(replaceTable) #btnDeleg.clicked.connect(self.setItemOpt) #replaceTable.clicked.connect(self.setItemOpt) #replaceTable.setItemDelegateForColumn(2,btnDeleg) #replaceTable.setItemDelegateForColumn(6,CheckBoxDelegate(replaceTable)) #/replaceTable #buttonBox sklonPadejBtn=QPushButton("Просклонять") addRowBtn=QPushButton("Добавить строку") delRowBtn=QPushButton("Удалить строку") clearTable=QPushButton("Очистить") buttonBox = QDialogButtonBox(Qt.Horizontal) buttonBox.addButton(sklonPadejBtn, QDialogButtonBox.ActionRole) buttonBox.addButton(addRowBtn, QDialogButtonBox.ActionRole) buttonBox.addButton(delRowBtn, QDialogButtonBox.ActionRole) buttonBox.addButton(clearTable, QDialogButtonBox.ActionRole) #/buttonBox #mainLayout mainLayout = QVBoxLayout() mainLayout.setContentsMargins(0,0,0,0) self.optionWdgt=Options() mainLayout.setMenuBar(self.optionWdgt) mainLayout.addWidget(replaceTable) mainLayout.addWidget(buttonBox) #/mainLayout #self self.setLayout(mainLayout) self.ReplaceModel=ReplaceModel self.replaceTable=replaceTable #/self #connections sklonPadejBtn.clicked.connect(self.addSklonenie) addRowBtn.clicked.connect(self.addRow) delRowBtn.clicked.connect(self.delRow) clearTable.clicked.connect(self.clearReplaceTable) ReplaceModel.itemChanged.connect(self.ChangeReplaceList)
class FilterableTable(SQLTable): """a filterable Table Widget that displays content of an SQLite table; for individual widgets, subclass and overwrite the create_model method; add_color_proxy should be an (INT allele_status-column, INT lab_status-column) tuple """ def __init__(self, log, mydb = ": memory :", add_color_proxy = False, header_dic = None): super().__init__(log, mydb) self.add_color_proxy = add_color_proxy self.header_dic = header_dic self.create_model() self.fill_UI() self.create_filter_model() self.update_filterbox() def fill_UI(self): """sets up the layout """ self.log.debug("\t- Setting up the table...") self.table = QTableView() self.table.setContextMenuPolicy(Qt.CustomContextMenu) self.header = self.table.horizontalHeader() # table header self.header.setSectionResizeMode(QHeaderView.ResizeToContents) self.table.setSelectionBehavior(QAbstractItemView.SelectRows) self.table.setAlternatingRowColors(True) # self.header.sectionClicked.connect(self.on_header_sectionClicked) mode = QAbstractItemView.SingleSelection self.table.setSelectionMode(mode) self.grid.addWidget(self.table, 2, 0, 10, 10) self.filter_lbl = QLabel("Filter:", self) self.grid.addWidget(self.filter_lbl, 1, 2) self.filter_entry = QLineEdit(self) self.grid.addWidget(self.filter_entry, 1, 3) self.filter_entry.textChanged.connect(self.on_filter_entry_textChanged) self.filter_text = "" self.filter_cb = QComboBox(self) self.grid.addWidget(self.filter_cb, 1, 4) self.filter_cb.currentIndexChanged.connect(self.on_filter_cb_IndexChanged) self.filter_btn = QPushButton("Filter!", self) self.grid.addWidget(self.filter_btn, 1, 5) self.filter_btn.clicked.connect(self.on_filter_btn_clicked) self.unfilter_btn = QPushButton("Remove Filter", self) self.grid.addWidget(self.unfilter_btn, 1, 6) self.unfilter_btn.clicked.connect(self.on_actionAll_triggered) self.log.debug("\t=> Done!") def update_filterbox(self): """fills the filter-combobox with the header values after the model has been created and set """ column_num = self.model.columnCount() if self.header_dic: columns = [self.header_dic[i] for i in self.header_dic] else: columns = [self.proxy.headerData(i, Qt.Horizontal) for i in range(column_num)] self.filter_cb.addItems(columns) def create_filter_model(self): """creates the filter-proxy-model on top of self.model """ self.log.debug("Creating filter model...") self.proxy = QSortFilterProxyModel(self) if self.add_color_proxy: (allele_status_column, lab_status_column) = self.add_color_proxy self.log.debug("adding color filter to columns {} and {}".format(allele_status_column, lab_status_column)) self.color_proxy = ColorProxyModel(self, allele_status_column, lab_status_column) self.color_proxy.setSourceModel(self.model) self.proxy.setSourceModel(self.color_proxy) else: self.proxy.setSourceModel(self.model) self.table.setSortingEnabled(True) self.table.setModel(self.proxy) def on_filter_cb_IndexChanged(self, index): """restricts RegEx filter to selected column """ self.log.debug("Combobox: colum {} selected".format(index)) self.proxy.setFilterKeyColumn(index) def on_filter_entry_textChanged(self, text): """stores content of filter_entry as self.text """ self.log.debug("filter text: '{}'".format(text)) self.filter_text = text def on_filter_btn_clicked(self): """activates RegEx filter to current content of filter_entry and filter_cb """ column = self.filter_cb.currentIndex() self.log.debug("Filtering column {} for '{}'".format(column, self.filter_text)) self.proxy.setFilterKeyColumn(column) search = QRegExp(self.filter_text, Qt.CaseInsensitive, QRegExp.RegExp) self.proxy.setFilterRegExp(search) def on_header_sectionClicked(self, logicalIndex): """opens a dialog to choose between all unique values for this column, or revert to 'All' """ self.log.debug("Header clicked: column {}".format(logicalIndex)) self.logicalIndex = logicalIndex menuValues = QMenu(self) self.signalMapper = QSignalMapper(self) self.filter_cb.setCurrentIndex(self.logicalIndex) self.filter_cb.blockSignals(True) self.proxy.setFilterKeyColumn(self.logicalIndex) valuesUnique = [str(self.model.index(row, self.logicalIndex).data()) for row in range(self.model.rowCount()) ] actionAll = QAction("All", self) actionAll.triggered.connect(self.on_actionAll_triggered) menuValues.addAction(actionAll) menuValues.addSeparator() for actionNumber, actionName in enumerate(sorted(list(set(valuesUnique)))): action = QAction(actionName, self) self.signalMapper.setMapping(action, actionNumber) action.triggered.connect(self.signalMapper.map) menuValues.addAction(action) self.signalMapper.mapped.connect(self.on_signalMapper_mapped) headerPos = self.table.mapToGlobal(self.header.pos()) posY = headerPos.y() + self.header.height() posX = headerPos.x() + self.header.sectionViewportPosition(self.logicalIndex) menuValues.exec_(QPoint(posX, posY)) def on_actionAll_triggered(self): """reverts table to unfiltered state """ self.log.debug("Unfiltering...") filterString = QRegExp("", Qt.CaseInsensitive, QRegExp.RegExp) self.proxy.setFilterRegExp(filterString) self.filter_entry.setText("") def on_signalMapper_mapped(self, i): """filters current column to mapping text """ text = self.signalMapper.mapping(i).text() self.log.debug("Filtering column {} to '{}'".format(self.logicalIndex, text)) filterString = QRegExp(text, Qt.CaseSensitive, QRegExp.FixedString) self.proxy.setFilterRegExp(filterString)
def rowCount(self, parent): return 2 def columnCount(self, parent): return 3 def data(self, index, role): if role == Qt.DisplayRole: return "({},{})".format(index.row(), index.column()) return QVariant() if __name__ == '__main__': app = QApplication(sys.argv) table_view = QTableView() my_model = MyModel(None) table_view.setModel(my_model) table_view.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) # <- https://stackoverflow.com/q/17535563 table_view.show() # The mainloop of the application. The event handling starts from this point. # The exec_() method has an underscore. It is because the exec is a Python keyword. And thus, exec_() was used instead. exit_code = app.exec_() # The sys.exit() method ensures a clean exit. # The environment will be informed, how the application ended. sys.exit(exit_code)