質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
TableView

TableView(UITableView)とは、リスト形式で表示するコントロールで、ほとんどのアプリに使用されています。画面を「行」に分けて管理し、一般的には各行をタップした際に詳細画面に移動します。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

1回答

1514閲覧

PyQt テーブル表の列フィルタ追加について

goki_gottan

総合スコア168

TableView

TableView(UITableView)とは、リスト形式で表示するコントロールで、ほとんどのアプリに使用されています。画面を「行」に分けて管理し、一般的には各行をタップした際に詳細画面に移動します。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2022/06/07 00:38

現在、QtWidgetsを使用して、データベースから引っ張ってきたデータをGUI表示しております。

表に起こすアルゴリズムは、以下のようにPandasを使用してDataFrameからDictに直して、setDataしております。

class TableView(QTableWidget): def __init__(self, data, *args): QTableWidget.__init__(self, *args) self.data = data print(data) self.setData() def setData(self): horHeaders = [] for n, key in enumerate(self.data.keys()): horHeaders.append(key) for m, item in enumerate(self.data[key]): newitem = QTableWidgetItem(str(item)) self.setItem(m, n, newitem)    #horHeaders こちらは、列ラベルに使用 self.setHorizontalHeaderLabels(horHeaders)

問題となっているのは、列フィルタにするための参考サイト
https://stackfinder.jp.net/questions/14068823/how-to-create-filters-for-qtableview-in-pyqt
こちらが、QtGui.QStandardItemを使用しており、

for rowName in range(3) * 5: self.model.invisibleRootItem().appendRow( [ QtGui.QStandardItem("row {0} col {1}".format(rowName, column)) for column in range(3) ] )

と、自身の作成したコードから参考サイトのQtGui.QStandardItemへの移行ができず困っております。

また、自身のコードでは、表をMainWindowとは別に、TableViewを追加してそこにデータを入れるようにしております。
しかし、参考サイトではTableViewを使用しておらず、そこのやりとりもうまくいっておりません。
要は、TableViewで列フィルタできないか検討しておりましたが、できなかったため、参考サイトのようにMainWindowに表を作成しようと思ったのですが、そちらですと今度はQtGui.QStandardItemの移行に手間取っている状態です。

1,TableViewで列フィルタかける方法はないか
2,Dictデータ(DataFrameからDictに変換した2次元データ)から self.model.invisibleRootItem().appendRowへデータ移行できないか
ご教示ください。

自身の作成したコードは以下です

from PyQt5.QtWidgets import * from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget, QAction, QTableWidget,QTableWidgetItem,QVBoxLayout,QCheckBox,QHBoxLayout,QPushButton from PyQt5.QtGui import QIcon from PyQt5 import QtGui from PyQt5.QtCore import pyqtSlot from PyQt5 import QtCore import sys import pandas as pd import sqlite3 import sip global conn z1="〇" r1="〇.db" #テーブル名 table_="ist" conn = sqlite3.connect(z1 + '\\' + r1) c = conn.cursor() sql = "SELECT * FROM " + table_ +";" df=pd.read_sql(sql,conn) num1=len(df.columns) num2=len(df) df=df.fillna("-") data=df.to_dict(orient='list') color_style="QPushButton {background-color: #DCDCDC; height: 30px; color: black; font: 30px; border-radius: 30px;} \ QPushButton:hover {background: #708090} \ QPushButton:pressed {background: #000080}" stylesheet = "::section{color: blue; Background-color:rgb(240,220,220);} ::section:checked{color: black; background-color: blue;}"# \ class TableView(QTableWidget): def __init__(self, data, *args): QTableWidget.__init__(self, *args) self.data = data self.setData() self.resizeColumnsToContents() self.resizeRowsToContents() def setData(self): horHeaders = [] for n, key in enumerate(self.data.keys()): horHeaders.append(key) for m, item in enumerate(self.data[key]): newitem = QTableWidgetItem(str(item)) self.setItem(m, n, newitem) self.setHorizontalHeaderLabels(horHeaders) self.horizontalHeader().setStyleSheet(stylesheet) self.verticalHeader().setStyleSheet(stylesheet) class window(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.table = TableView(data, num2, num1, self) self.button = QPushButton('削除', self) self.button1 = QPushButton('修正', self) self.button2 = QPushButton('更新', self) self.button3 = QPushButton('終了', self) self.button.clicked.connect(self.clickCallback) self.button1.clicked.connect(self.clickCallback1) self.button2.clicked.connect(self.clickCallback3) self.button3.clicked.connect(self.clickCallback2) self.setWindowFlag(QtCore.Qt.WindowCloseButtonHint, False)#閉じるボタン無効化 title = QLabel('Title') author = QLabel('Author') review = QLabel('Table') review1 = QLabel('処理') titleEdit = QLineEdit() authorEdit = QLineEdit() reviewEdit = QTextEdit() # 格子状の配置を作り、各ウィジェットのスペースを空ける grid = QGridLayout() grid.setSpacing(10) # ラベルの位置設定 grid.addWidget(title, 1, 0) # 入力欄の位置設定 grid.addWidget(titleEdit, 1, 1) grid.addWidget(author, 2, 0) grid.addWidget(authorEdit, 2, 1) grid.addWidget(review, 3, 0) self.lineedit = QLineEdit() self.lineedit.setCompleter(completer) grid.addWidget(self.table, 3, 1, 1, 4) #ボタン grid.addWidget(review1, 5, 0) grid.addWidget(self.button, 5, 1,1,1) grid.setColumnStretch(1, 1) grid.addWidget(self.button1, 5, 2,1,1) grid.setColumnStretch(2, 1) grid.addWidget(self.button2, 5, 3,1,1) grid.setColumnStretch(3, 1) grid.addWidget(self.button3, 5, 4,1,1) grid.setColumnStretch(4, 1) self.button.setStyleSheet(color_style) self.button1.setStyleSheet(color_style) self.button2.setStyleSheet(color_style) self.button3.setStyleSheet(color_style) self.table.setStyleSheet("QTableView{gridline-color: black}") self.table.setCurrentItem(None) self.setLayout(grid) self.setGeometry(600, 100, 850, 850) self.setWindowTitle('Review') self.show() def doSomething(self): self.quit() #削除 def clickCallback(self): global df if self.table.currentItem() is None: return self.table.removeRow(self.table.currentItem().row()) df=df.drop(df.index[int(self.table.currentItem().row())]) sq1l = "drop table " + table_ + ";" conn.execute(sq1l) df.to_sql(table_,conn,if_exists='append',index=None) conn.commit() self.table.setCurrentItem(None) self.table.setFocus() #修正 def clickCallback1(self): return #終了 def clickCallback2(self): global conn conn.close() self.close() QApplication.quit() sys.exit(0) return #更新 def clickCallback3(self): df=pd.read_sql(sql,conn) num1=len(df.columns) num2=len(df) df=df.fillna("-") data_=df.to_dict(orient='list') b = list(data_.keys()) c = list(data_.values()) for b_1 in b: for c_1 in range(len(c)): for d_1 in range(len(c[c_1])): data[b_1][d_1] = data_[b_1][d_1] self.table.setData() return def main(): app = QtWidgets.QApplication(sys.argv) ex = window()  ex.show() print("gggg") sys.exit(app.exec_()) if __name__ == '__main__': main()

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

用語を混同されてるようです。
問題の原因は、QTableView の情報を参考にしながら 実際にはQTableWidget を使っている点で、

リンク先の情報を参考にするには、(QTableWidgetを継承した) 自作クラスのTableView ではなく
Qtの提供する QTableView を継承したクラスを作成する必要があります。
(コードは少し複雑になり、Model-View に関する理解が必要です)

質問に掲載の TableView クラスを使う場合は、QTableWidget を継承したクラスなので

TableViewで列フィルタかける方法はないか
TableViewで列フィルタできないか検討しておりましたが

ではなく、調べるべきは QTableWidget でフィルタを書ける方法は~となります。

列によるソートであれば、setSortingEnabled, sortItems メソッド辺り

self.model.invisibleRootItem().appendRowへデータ移行できないか

データの内容は提示されてないので詳細がわかりませんが、
model を利用する場合は基本的に、QTableView を使う必要があります。

まずは、QTableWidget を使うか QTableView にするかの方針を定めましょう。

QTableWidget を採用する場合は、質問の内容は全て見当外れになります。

QTableView を採用する場合は、リンク先の情報が使えるのでそのまま参考にしてください。
⇛ 要点は QTableWidget ではなく、QTableView を使う点
データ規模が少ない、単純な表示のみの場合は QTableWidget で事足りるかもしれませんが、
フィルタやソート機能等が必要だったり、大規模なデータを扱う場合は QTableView が適してます。

View-Model形式を使う利点としては、Qt はデータベース関連の Model も提供しているので、
(利用できる場合は)コードをより簡略化出来る場合もあります。

投稿2022/06/09 04:09

編集2022/06/09 06:12
teamikl

総合スコア8664

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問