我想实现以下非常小的项目,即用户应该输入产品名称,Python应该在数据库中搜索并在pyqt6桌面应用程序中显示查询结果,为此我已经实现了以下基本GUI形式:
这里用户输入产品,然后单击按钮,结果将显示在空白处,即:
QTextEdit()
,最有趣的部分是这个功能:
def return_product_info(self):
input_text =self.inputField.text()
df = pd.read_sql_query('''SELECT * FROM "foreign_products" where "product" = '{}'
'''.format( input_text), con=engine)
print(df.head())
self.output.setText(df)
引擎部分被隐藏(它工作正常),唯一有趣的部分是:
self.output.setText(df)
如何我可以将 df 放入 QTextEdit() 中吗?我做了一些研究,发现我可以基于此链接使用
QTableView
:
QTableView
但是我如何将所有这些连接到一个项目中?这是应用程序的主要代码
class MyApp(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Database Search")
self.setWindowIcon(QIcon("db.jpg"))
self.resize(500,500)
layout =QVBoxLayout()
self.setLayout(layout)
self.inputField =QLineEdit()
self.button =QPushButton("click me")
self.button.clicked.connect(self.return_product_info)
self.output =QTextEdit()
layout.addWidget(self.inputField)
layout.addWidget(self.button)
layout.addWidget(self.output)
这显示在控制台上,但我想在按钮下方的文本编辑器中(“单击我”),请帮助我如何做到这一点
你不能直接将一个pandas DataFrame放入
QTextEdit
中。
QTextEdit
是为显示纯文本设计的,而不是像DataFrame这样结构化的数据。
你有几个选项可以实现你想要的结果:
1. 使用 QTableView:
这是展示表格数据的最佳方式。你需要创建一个
QTableView
,然后使用
QAbstractTableModel
的子类来连接你的 DataFrame 和表格视图。
以下是修改后的代码:
import sys
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QLineEdit, QPushButton, QTableView
from PyQt6.QtGui import QIcon
from PyQt6.QtCore import Qt
import pandas as pd
from pandas.core.frame import DataFrame
# 替换为你的数据库连接
engine = ...
class PandasModel(QtCore.QAbstractTableModel):
def __init__(self, df = DataFrame(), parent=None):
QtCore.QAbstractTableModel.__init__(self, parent=parent)
self._df = df
def rowCount(self, parent=QModelIndex()):
return len(self._df.index)
def columnCount(self, parent=QModelIndex()):
return len(self._df.columns)
def data(self, index, role=Qt.ItemDataRole.DisplayRole):
if index.isValid():
if role == Qt.ItemDataRole.DisplayRole:
return str(self._df.iloc[index.row(), index.column()])
return None
def headerData(self, section, orientation, role=Qt.ItemDataRole.DisplayRole):
if role != Qt.ItemDataRole.DisplayRole:
return None
if orientation == Qt.Orientation.Horizontal:
try:
return str(self._df.columns.tolist()[section])
except (IndexError, ):
return None
elif orientation == Qt.Orientation.Vertical:
try:
# return self.headerList[section]
return str(self._df.index[section])
except (IndexError, ):
return None
class MyApp(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Database Search")
self.setWindowIcon(QIcon("db.jpg"))
self.resize(500,500)
layout =QVBoxLayout()
self.setLayout(layout)
self.inputField =QLineEdit()
self.button =QPushButton("click me")
self.button.clicked.connect(self.return_product_info)
self.table_view = QTableView()
layout.addWidget(self.inputField)
layout.addWidget(self.button)
layout.addWidget(self.table_view)
def return_product_info(self):
input_text = self.inputField.text()
df = pd.read_sql_query(
'''SELECT * FROM "foreign_products" where "product" = '{}' '''.format(
input_text), con=engine)
model = PandasModel(df)
self.table_view.setModel(model)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MyApp()
window.show()
sys.exit(app.exec())
2. 将 DataFrame 格式化为字符串并显示在 QTextEdit 中:
这不是理想的解决方案,但如果你只需要显示数据而不是进行交互,则可以使用。 你可以使用 pandas 的
to_string()
或
to_html()
方法将 DataFrame 转换为字符串,然后使用
setText()
将其设置到
QTextEdit
中。
以下是修改后的代码:
import sys
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QLineEdit, QPushButton, QTextEdit
from PyQt6.QtGui import QIcon
import pandas as pd
# 替换为你的数据库连接
engine = ...
class MyApp(QWidget):
def __init__(self):
# ... (其他代码相同) ...
def return_product_info(self):
input_text = self.inputField.text()
df = pd.read_sql_query(
'''SELECT * FROM "foreign_products" where "product" = '{}' '''.format(
input_text), con=engine)
# 将 DataFrame 转换为字符串并显示在 QTextEdit 中
self.output.setText(df.to_string())
if __name__ == '__main__':
# ... (其他代码相同) ...
请记住,使用
to_html()
方法可以获得更美观的输出,但需要设置
QTextEdit
以正确呈现 HTML。