def test_removeColumns(self, qtbot, dataModel2): widget = DataTableWidget() qtbot.addWidget(widget) widget.show() widget.setViewModel(dataModel2) df = dataModel2.dataFrame().copy() buttons = widget.findChildren(QtGui.QToolButton) for btn in buttons: if btn.isEnabled: qtbot.mouseClick(btn, QtCore.Qt.LeftButton) break for btn in buttons: if btn.objectName() == 'removecolumnbutton': qtbot.mouseClick(btn, QtCore.Qt.LeftButton) dlg = widget.findChildren(QtGui.QDialog)[-1] listview = dlg.findChildren(QtGui.QListView)[-1] listview.selectAll() dlg_buttons = dlg.findChildren(QtGui.QPushButton) for b in dlg_buttons: if b.text() == 'OK': qtbot.mouseClick(b, QtCore.Qt.LeftButton) break assert widget.view().model().columnCount() == 0
def test_click_each_button(self, qtbot, dataModel): widget = DataTableWidget() qtbot.addWidget(widget) widget.show() widget.setViewModel(dataModel) buttons = widget.findChildren(QtGui.QToolButton) for btn in buttons: if btn.isEnabled: qtbot.mouseClick(btn, QtCore.Qt.LeftButton) break for btn in buttons: if btn.objectName() == 'editbutton': continue if btn.objectName() in ['addcolumnbutton', 'removecolumnbutton']: qtbot.mouseClick(btn, QtCore.Qt.LeftButton) dlg = widget.findChildren(QtGui.QDialog)[-1] dlg_buttons = dlg.findChildren(QtGui.QPushButton) for b in dlg_buttons: if b.text() == 'Cancel': qtbot.mouseClick(b, QtCore.Qt.LeftButton) break else: qtbot.mouseClick(btn, QtCore.Qt.LeftButton)
class ResultWindow(QWidget): def __init__(self): super(self.__class__, self).__init__() self.setup_ui() def setup_ui(self): self.setWindowTitle("查詢結果") self.setFont(PyQt5.QtGui.QFont("Times New Roman", 11)) self.buttonCopy = QPushButton("複製查詢結果 (Ctrl+C)") self.buttonCopy.clicked.connect(self.copy) self.labelInfo = QLabel("") self.shortcut = QShortcut(PyQt5.QtGui.QKeySequence("Ctrl+C"), self) self.shortcut.activated.connect(self.copy) self.formLayout = QFormLayout() self.formLayout.addRow(self.buttonCopy, self.labelInfo) self.widget = DataTableWidget() self.widget.setButtonsVisible(False) self.widget.setMinimumSize(600, 600) self.vbox = QVBoxLayout() self.vbox.addLayout(self.formLayout) self.vbox.addWidget(self.widget) self.setLayout(self.vbox) def update(self, data): self.df = data self.labelInfo.setText("") self.model = DataFrameModel() self.widget.resize(self.widget.sizeHint()) self.widget.show() self.widget.setViewModel(self.model) self.model.setDataFrame(data) def copy(self): count = 0 indexes = self.widget.tableView.selectionModel().selectedRows() if len(indexes) > 0: rows = [index.row() for index in indexes] count = len(indexes) else: rows = [i for i in range(self.widget.tableView.model().rowCount())] count = self.widget.tableView.model().rowCount() s = '' for i in rows: r = self.df.iloc[[i]] for v in r.values[0].astype(str): s += (v + '\t') s = s[:-1] + '\n' pyperclip.copy(s[:-1]) self.labelInfo.setText(str(count) + " 筆資料已複製至剪貼簿")
def test_addColumn(self, qtbot, dataModel): widget = DataTableWidget() qtbot.addWidget(widget) widget.show() widget.setViewModel(dataModel) buttons = widget.findChildren(QtGui.QToolButton) for btn in buttons: if btn.isEnabled: qtbot.mouseClick(btn, QtCore.Qt.LeftButton) break columns = [] addButton = None for btn in buttons: if btn.objectName == 'addcolumnbutton': addbutton = btn qtbot.mouseClick(btn, QtCore.Qt.LeftButton) dlg = widget.findChildren(QtGui.QDialog)[-1] dlg_buttons = dlg.findChildren(QtGui.QPushButton) comboBox = dlg.findChildren(QtGui.QComboBox)[-1] for i in range(comboBox.count()): columns.append(comboBox.itemText(i)) for b in dlg_buttons: if b.text() == 'Cancel': qtbot.mouseClick(b, QtCore.Qt.LeftButton) break break columnCountBeforeInsert = widget.view().model().columnCount() for index, column in enumerate(columns): qtbot.mouseClick(addbutton, QtCore.Qt.LeftButton) dlg = widget.findChildren(QtGui.QDialog)[-1] textedits = dlg.findChildren(QtGui.QLineEdit) qtbot.keyClicks(textedits[0], column) comboBox = dlg.findChildren(QtGui.QComboBox)[-1] comboBox.setCurrentIndex(index) dlg_buttons = dlg.findChildren(QtGui.QPushButton) for b in dlg_buttons: if b.text() == 'OK': qtbot.mouseClick(b, QtCore.Qt.LeftButton) break assert widget.view().model().columnCount( ) == columnCountBeforeInsert + 1 + index
class Ui_Mine5(object): def click1(self): self.form.close() Form1 = QtWidgets.QMainWindow() self.ui = Mine.Ui_Mine() self.ui.setupUi(Form1) Form1.show() def setupUi(self, Mine5): Mine5.setObjectName("Mine5") Mine5.resize(1259, 879) Mine5.setStyleSheet("border-image: url(:/M11.jpg);") Mine5.setWindowFlags(Qt.FramelessWindowHint) self.form = Mine5 self.centralwidget = QtWidgets.QWidget(Mine5) self.centralwidget.setObjectName("centralwidget") self.pushButton = QtWidgets.QPushButton(self.centralwidget) self.pushButton.setGeometry(QtCore.QRect(20, -10, 861, 101)) self.pushButton.setStyleSheet("border-image: url(:/M16.jpg);\n" "font: 14pt \"华文新魏\";") self.pushButton.setObjectName("pushButton") self.label_2 = QtWidgets.QLabel(self.centralwidget) self.label_2.setGeometry(QtCore.QRect(890, 0, 361, 81)) self.label_2.setStyleSheet("\n" "border-image: url(:/M10.jpg);") self.label_2.setObjectName("label_2") self.pandastablewidget = DataTableWidget(self.centralwidget) self.pandastablewidget.setGeometry(QtCore.QRect(-10, 90, 1251, 741)) self.pandastablewidget.setStyleSheet("border-image: url(:/M8.png);") self.pandastablewidget.setObjectName("pandastablewidget") self.model = DataFrameModel() self.pandastablewidget.setViewModel(self.model) self.model.setDataFrame(db) Mine5.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(Mine5) self.menubar.setGeometry(QtCore.QRect(0, 0, 1259, 26)) self.menubar.setObjectName("menubar") Mine5.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(Mine5) self.statusbar.setObjectName("statusbar") Mine5.setStatusBar(self.statusbar) self.retranslateUi(Mine5) self.pushButton.clicked.connect(self.click1) QtCore.QMetaObject.connectSlotsByName(Mine5) def retranslateUi(self, Mine5): _translate = QtCore.QCoreApplication.translate Mine5.setWindowTitle(_translate("Mine5", "欢迎使用喵眼!")) self.pushButton.setText(_translate("Mine5", "返回")) self.label_2.setText(_translate("Mine5", "TextLabel"))
def test_setModel(self, qtbot, dataModel): widget = DataTableWidget() qtbot.addWidget(widget) widget.show() widget.setViewModel(dataModel) assert widget.view().model() is not None assert widget.view().model() == dataModel buttons = widget.findChildren(QtGui.QToolButton) for btn in buttons: if btn.isEnabled: qtbot.mouseClick(btn, QtCore.Qt.LeftButton) assert widget.view().model().editable qtbot.mouseClick(btn, QtCore.Qt.LeftButton) assert not widget.view().model().editable break
class TestWidget(QtGui.QWidget): def __init__(self, parent=None): super(TestWidget, self).__init__(parent) #FIXME: Make resize adapt to users screen. self.resize(1680, 756) self.move(0, 0) self.df = pandas.DataFrame() self.dataModel = None # init the data view's self.dataTableView = DataTableWidget(self) # self.dataTableView.setSortingEnabled(True) # self.dataTableView.setAlternatingRowColors(True) self.dataListView = QtGui.QListView(self) self.dataListView.setAlternatingRowColors(True) self.dataComboBox = QtGui.QComboBox(self) # make combobox to choose the model column for dataComboBox and dataListView self.chooseColumnComboBox = QtGui.QComboBox(self) self.buttonCsvData = QtGui.QPushButton("load csv data") self.buttonRandomData = QtGui.QPushButton("load random data") importDialog = CSVImportDialog(self) importDialog.load.connect(self.updateModel) self.buttonCsvData.clicked.connect(lambda: importDialog.show()) self.buttonRandomData.clicked.connect(lambda: self.setDataFrame( getRandomData(rows=100, columns=100) )) self.exportDialog = CSVExportDialog(self) self.buttonCSVExport = QtGui.QPushButton("export to csv") self.buttonCSVExport.clicked.connect(self._exportModel) self.buttonLayout = QtGui.QHBoxLayout() self.buttonLayout.addWidget(self.buttonCsvData) self.buttonLayout.addWidget(self.buttonCSVExport) self.buttonLayout.addWidget(self.buttonRandomData) self.mainLayout = QtGui.QVBoxLayout() self.setLayout(self.mainLayout) self.mainLayout.addLayout(self.buttonLayout) self.mainLayout.addWidget(self.dataTableView) self.spinbox = QtGui.QSpinBox() self.mainLayout.addWidget(self.spinbox) self.spinbox.setMaximum(99999999999) self.spinbox.setValue(99999999999) self.rightLayout = QtGui.QVBoxLayout() self.chooseColumLayout = QtGui.QHBoxLayout() self.mainLayout.addLayout(self.rightLayout) self.rightLayout.addLayout(self.chooseColumLayout) self.chooseColumLayout.addWidget(QtGui.QLabel("Choose column:")) self.chooseColumLayout.addWidget(self.chooseColumnComboBox) self.rightLayout.addWidget(self.dataListView) self.rightLayout.addWidget(self.dataComboBox) self.tableViewColumnDtypes = QtGui.QTableView(self) self.rightLayout.addWidget(QtGui.QLabel('dtypes')) self.rightLayout.addWidget(self.tableViewColumnDtypes) self.buttonGoToColumn = QtGui.QPushButton("go to column") self.rightLayout.addWidget(self.buttonGoToColumn) self.buttonGoToColumn.clicked.connect(self.goToColumn) self.buttonSetFilter = QtGui.QPushButton("set filter") self.rightLayout.addWidget(self.buttonSetFilter) self.buttonSetFilter.clicked.connect(self.setFilter) self.buttonClearFilter = QtGui.QPushButton("clear filter") self.rightLayout.addWidget(self.buttonClearFilter) self.buttonClearFilter.clicked.connect(self.clearFilter) self.lineEditFilterCondition = QtGui.QLineEdit("freeSearch('am')") self.rightLayout.addWidget(self.lineEditFilterCondition) self.chooseColumnComboBox.currentIndexChanged.connect(self.setModelColumn) self.dataListView.mouseReleaseEvent = self.mouseReleaseEvent self.dropLineEdit = DropLineEdit("drop data from table here", self) self.rightLayout.addWidget(self.dropLineEdit) self.dropWidget = ComplexDropWidget(self) self.dropWidget.dropRecieved.connect(self.processDataDrops) self.rightLayout.addWidget(self.dropWidget) @Slot('QMimeData') def processDataDrops(self, mimeData): """if you have more complicated stuff to do and you want to match some models, might be possible like that""" mimeDataPayload = mimeData.data() if isinstance(mimeDataPayload, PandasCellPayload): if self.dataModel is not None: if hex(id(self.dataModel)) == mimeDataPayload.parentId: self.dropWidget.setText("complex stuff done after drop event. {0}".format(mimeDataPayload.column)) def setDataFrame(self, dataFrame): self.df = dataFrame dataModel = DataFrameModel() dataModel.setDataFrame(self.df) self.dataModel = dataModel self.dataListView.setModel(dataModel) self.dataTableView.setViewModel(dataModel) self.dataComboBox.setModel(dataModel) # self.dataTableView.resizeColumnsToContents() # create a simple item model for our choosing combobox columnModel = QtGui.QStandardItemModel() for column in self.df.columns: columnModel.appendRow(QtGui.QStandardItem(column)) self.chooseColumnComboBox.setModel(columnModel) self.tableViewColumnDtypes.setModel(dataModel.columnDtypeModel()) self.tableViewColumnDtypes.horizontalHeader().setDefaultSectionSize(200) self.tableViewColumnDtypes.setItemDelegateForColumn(1, DtypeComboDelegate(self.tableViewColumnDtypes)) dataModel.changingDtypeFailed.connect(self.changeColumnValue) @Slot() def _exportModel(self): model = self.dataTableView.view().model() self.exportDialog.setExportModel(model) self.exportDialog.show() @Slot('QAbstractItemModel') def updateModel(self, model): self.dataModel = model self.dataListView.setModel(model) self.dataTableView.setViewModel(model) self.dataComboBox.setModel(model) self.tableViewColumnDtypes.setModel(model.columnDtypeModel()) def setModelColumn(self, index): self.dataListView.setModelColumn(index) self.dataComboBox.setModelColumn(index) def goToColumn(self): print("go to column 7") index = self.dataTableView.view().model().index(7, 0) self.dataTableView.view().setCurrentIndex(index) def changeColumnValue(self, columnName, index, dtype): print("failed to change", columnName, "to", dtype) print(index.data(), index.isValid()) self.dataTableView.view().setCurrentIndex(index) def setFilter(self): #filterIndex = eval(self.lineEditFilterCondition.text()) search = DataSearch("Test", self.lineEditFilterCondition.text()) self.dataTableView.view().model().setFilter(search) #raise NotImplementedError def clearFilter(self): self.dataTableView.view().model().clearFilter()
from qtpandas.models.DataFrameModel import DataFrameModel from qtpandas.views.DataTableView import DataTableWidget # from qtpandas.views._ui import icons_rc sys.excepthook = excepthook # 設定PyQt的異常鉤子,基本上在本例沒什麼作用 # 建立一個空的模型,該模型用來儲存與處理資料 model = DataFrameModel() # 建立一個應用程式顯示表格 app = QtGui.QApplication([]) widget = DataTableWidget() # 建立一個空的表格,用來呈現資料 widget.resize(500, 300) # 調整Widget的大小 widget.show() # 讓表格繫結模型,也就是呈現模型的內容 widget.setViewModel(model) # 建立測試資料 data = { 'A': [10, 11, 12], 'B': [20, 21, 22], 'C': ['Peter Pan', 'Cpt. Hook', 'Tinkerbell'] } df = pandas.DataFrame(data) # 下面兩列用來測試委託是否成立 df['A'] = df['A'].astype(numpy.int8) # A欄資料格式變成整數 df['B'] = df['B'].astype(numpy.float16) # B欄資料格式變成浮點數 # 在模型中填入資料df model.setDataFrame(df)
class Main: def __init__(self): """ 初始化主界面 """ self.ui = loadUi("UI/main.ui") self.ui.setWindowTitle("聚类系统") self.DataHelper = None self.ui.btn_choose_data.clicked.connect(self.choose_path) self.ui.btn_set_parameter.clicked.connect(self.set_parameter) self.ui.btn_spin.addItems( ["KMeans", "GMM", "DBSCAN", "OPTICS","BIRCH", "MeanShift", "CLIQUE"]) self.ui.btn_run.clicked.connect(self.run) self.cluster = ClusterHelper() self.ui.btn_show_image.clicked.connect(self.show_image) def show_image(self): """ 展示聚类结果 """ try: self.cluster.imshow() except: QMessageBox.about(self.ui, "展示失败", "请先训练你的聚类器") def choose_path(self): """ 选择数据集 """ file_name = QtWidgets.QFileDialog.getOpenFileName( self.ui, "请选择你要打开数据的名字", "./data/", "Csv files(*.csv)") file_name = file_name[0] self.DataHelper = DataHelper(file_name) name = file_name.split("/")[-1] self.ui.ldata_name.setText(name) self.show_information() self.show_data() def show_information(self): """ 显示数据集的基本信息 """ self.ui.ldata_shape.setText(str(self.DataHelper.shape)) self.ui.ldata_class.setText(str(self.DataHelper.class_)) def set_parameter(self): """ 设置分类器 """ currentText = self.ui.btn_spin.currentText() self.newWindow = SecondWindow(algorithm=currentText) self.newWindow.btn_yes.clicked.connect(self.get_parameter) self.newWindow.show() def get_parameter(self): """ 获得参数信息 """ self.newWindow.window_exit() self.ui.tmessage_show.setText(self.newWindow.message) currentText = self.ui.btn_spin.currentText() param_dict = [eval(line.split(":")[1]) for line in self.newWindow.message.split("\n")[1:-1]] self.cluster.set_Cluster(currentText, param_dict) def show_data(self): """ 展示读取进来的数据 """ self.widget = DataTableWidget(self.ui) model = DataFrameModel() model.setDataFrame(self.DataHelper.data) self.widget.setViewModel(model) self.widget.move(30, 200) self.widget.resize(350, 350) self.widget.show() def run(self): """ 运行聚类算法 """ if(self.DataHelper == None): QMessageBox.about(self.ui, "运行失败", "请选择你的数据集") elif(self.cluster.cluster == None): QMessageBox.about(self.ui, "运行失败", "请初始化你的聚类器") else: self.cluster.fit(self.DataHelper.data) score = self.cluster.get_score() text = "" for item in score.items(): text += item[0] + str(item[1]) + "\n" self.ui.t_ans.setText(text)
from qtpandas.models.DataFrameModel import DataFrameModel from qtpandas.views.DataTableView import DataTableWidget # from qtpandas.views._ui import icons_rc sys.excepthook = excepthook # 设置PyQt的异常钩子,在本例中基本没什么用 # 创建一个空的模型,该模型用于存储与处理数据 model = DataFrameModel() # 创建一个应用用于显示表格 app = QtGui.QApplication([]) widget = DataTableWidget() # 创建一个空的表格,主要用来呈现数据 widget.resize(500, 300) # 调整Widget的大小 widget.show() # 让表格绑定模型,也就是让表格呈现模型的内容 widget.setViewModel(model) # 创建测试数据 data = { 'A': [10, 11, 12], 'B': [20, 21, 22], 'C': ['Peter Pan', 'Cpt. Hook', 'Tinkerbell'] } df = pandas.DataFrame(data) # 下面两列用来测试委托是否成立 df['A'] = df['A'].astype(numpy.int8) # A列数据格式变成整型 df['B'] = df['B'].astype(numpy.float16) # B列数据格式变成浮点型 # 在模型中填入数据df model.setDataFrame(df)