鱼C论坛

 找回密码
 立即注册
楼主: 凊风

[已解决]QPlainTextEdit问题求教3~~

[复制链接]
 楼主| 发表于 2024-3-19 17:00:59 | 显示全部楼层
FishC 发表于 2024-3-19 17:00
非常抱歉,之前的代码中依然存在错误。对于QComboBox控件,可以使用addItem()方法逐个添加选项,而不是 ...

源列仍然没有数据
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-19 17:01:10 | 显示全部楼层
凊风 发表于 2024-03-19 17:00
源列仍然没有数据


非常抱歉,前面提供的代码可能依然存在问题。请尝试以下修正后的代码:
def load_columns(self, workbook_path, sheet_name):
    if not workbook_path or not sheet_name:
        return
    
    workbook = openpyxl.load_workbook(filename=workbook_path)
    sheet = workbook[sheet_name]  # 获取指定的工作表
    
    column_names = [column[0].value for column in sheet.iter_cols(min_row=1, max_row=1)]
    
    self.source_col_combo.clear()
    self.dest_col_combo.clear()
    
    for column_name in column_names:
        self.source_col_combo.addItem(column_name)
        self.dest_col_combo.addItem(column_name)

在这个修正后的代码中,我们使用了`sheet.iter_cols()`方法来获取第一行的所有列数据。同时,对于每一列中的数据,我们取索引为0的单元格值,以确保只获取了列名。还请确保在调用`load_columns()`方法时传入了正确的`workbook_path`和`sheet_name`参数。

如果问题仍然存在,请提供更多相关代码、错误信息或上下文,以便我更好地帮助您。谢谢!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-3-19 17:10:41 | 显示全部楼层
FishC 发表于 2024-3-19 17:01
非常抱歉,前面提供的代码可能依然存在问题。请尝试以下修正后的代码:

源列 下拉框仍然没有数据,点不动
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-19 17:11:01 | 显示全部楼层
凊风 发表于 2024-03-19 17:10
源列 下拉框仍然没有数据,点不动


非常抱歉,可能是我之前的回答有些问题。根据你提供的信息,我假设你使用的是Qt的QComboBox来展示下拉框。

首先,请确保你已经正确引入了必要的模块,例如`from PySide6.QtWidgets import QComboBox`。

然后,请检查以下几点:

1. 请确认`source_col_combo`对象是一个有效的QComboBox。
2. 请确保在调用`load_columns()`方法之前,已经正确设置了`workbook_path`和`sheet_name`。
3. 确认`workbook`和`sheet`对象已经正确加载并获得了想要获取的数据。

在你的代码中使用`sheet.iter_cols()`这个方法时,检查一下返回的列是否为空。

另外,可以尝试将生成下拉框选项的代码放在主线程中,并确保在界面初始化之前执行,以确保正确初始化下拉框选项。

如果问题仍然存在,请提供更多相关代码以及其他上下文,以便我更好地帮助你解决问题。谢谢!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-3-19 17:13:46 | 显示全部楼层
FishC 发表于 2024-3-19 17:11
非常抱歉,可能是我之前的回答有些问题。根据你提供的信息,我假设你使用的是Qt的QComboBox来展示下拉 ...

from PySide6.QtWidgets import QApplication, QFileDialog, QMessageBox, QPlainTextEdit, QLineEdit, QLabel, QVBoxLayout, QHBoxLayout, QWidget, QPushButton, QComboBox
from PySide6.QtGui import QTextCharFormat, QTextCursor, QColor
import openpyxl

class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('Excel文件内容转换')
        self.resize(500, 300)
        self.layout = QVBoxLayout()

        # 工作簿选择按钮和标签
        self.workbook_btn = QPushButton('选择工作簿')
        self.workbook_label = QLabel('工作簿:')

        # 工作表选择框
        self.sheet_label = QLabel('工作表:')
        self.sheet_combo = QComboBox()

        # 转换列选择框
        self.source_col_label = QLabel('源列:')
        self.source_col_combo = QComboBox()
        self.dest_col_label = QLabel('目标列:')
        self.dest_col_combo = QComboBox()

        # 单元格格式选择框
        self.cell_format_label = QLabel('单元格格式:')
        self.cell_format_combo = QComboBox()

        # 转换按钮
        self.convert_btn = QPushButton('转换')

        # 添加控件到布局中
        self.layout.addWidget(self.workbook_btn)
        self.layout.addWidget(self.workbook_label)
        self.layout.addWidget(self.sheet_label)
        self.layout.addWidget(self.sheet_combo)
        self.layout.addWidget(self.source_col_label)
        self.layout.addWidget(self.source_col_combo)
        self.layout.addWidget(self.dest_col_label)
        self.layout.addWidget(self.dest_col_combo)
        self.layout.addWidget(self.cell_format_label)
        self.layout.addWidget(self.cell_format_combo)
        self.layout.addWidget(self.convert_btn)

        self.setLayout(self.layout)

        # 绑定按钮点击事件
        self.workbook_btn.clicked.connect(self.select_workbook)
        self.convert_btn.clicked.connect(self.convert)

    def select_workbook(self):
        file_dialog = QFileDialog()
        workbook_path, _ = file_dialog.getOpenFileName(self, '选择工作簿')
        self.workbook_label.setText(f'工作簿: {workbook_path}')
        self.load_sheets(workbook_path)

    def load_sheets(self, workbook_path):
        if not workbook_path:
            return
        workbook = openpyxl.load_workbook(filename=workbook_path)
        sheets = workbook.sheetnames
        self.sheet_combo.clear()
        self.sheet_combo.addItems(sheets)

    def load_columns(self, workbook_path, sheet_name):
        if not workbook_path or not sheet_name:
            return

        workbook = openpyxl.load_workbook(filename=workbook_path)
        sheet = workbook[sheet_name]  # 获取指定的工作表

        column_names = [column[0].value for column in sheet.iter_cols(min_row=1, max_row=1)]
        print(column_names)

        self.source_col_combo.clear()
        self.dest_col_combo.clear()

        for column_name in column_names:
            self.source_col_combo.addItem(column_name)
            self.dest_col_combo.addItem(column_name)

    def convert(self):
        workbook_path = self.workbook_label.text().split(': ')[1]
        sheet_name = self.sheet_combo.currentText()
        source_col = self.source_col_combo.currentText()
        dest_col = self.dest_col_combo.currentText()
        cell_format = self.cell_format_combo.currentText()

        # 打开工作簿
        try:
            workbook = openpyxl.load_workbook(filename=workbook_path)
        except Exception as e:
            QMessageBox.warning(self, '错误', f'打开工作簿失败:{str(e)}')
            return

        # 获取源列和目标列的索引
        try:
            source_col_index = self.get_column_index(source_col)
            dest_col_index = self.get_column_index(dest_col)
        except ValueError as e:
            QMessageBox.warning(self, '错误', str(e))
            return

        # 获取活动的工作表
        sheet = workbook[sheet_name]

        # 遍历行并转换格式
        for row in sheet.iter_rows(min_row=2, values_only=True):
            source_value = row[source_col_index - 1]

            # 执行转换操作,这里只是一个示例,你可以根据需要进行修改
            dest_value = str(source_value).upper()

            # 将转换结果写入目标列
            sheet.cell(row=row[0].row, column=dest_col_index).value = dest_value

            # 设置单元格格式
            cell = sheet.cell(row=row[0].row, column=dest_col_index)
            cell.number_format = cell_format

        # 保存转换后的文件
        try:
            workbook.save(filename=workbook_path)
        except Exception as e:
            QMessageBox.warning(self, '错误', f'保存工作簿失败:{str(e)}')
            return

        # 清空下拉框选择
        self.sheet_combo.clear()
        self.source_col_combo.clear()
        self.dest_col_combo.clear()
        self.cell_format_combo.clear()

        # 询问用户是否继续转换
        reply = QMessageBox.question(
            self, '询问', '是否继续转换?', QMessageBox.Yes | QMessageBox.No
        )
        if reply == QMessageBox.No:
            QApplication.quit()

    def get_column_index(self, column_name):
        if not column_name.isalpha():
            raise ValueError('列名必须由字母组成')

        index = 0
        for char in column_name:
            index = index * 26 + ord(char.upper()) - ord('A') + 1

        return index

app = QApplication([])
window = MainWindow()
window.show()
app.exec()

现在的问题是: 源列combo没有数据,点不动
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-19 17:14:10 | 显示全部楼层
凊风 发表于 2024-03-19 17:13
from PySide6.QtWidgets import QApplication, QFileD ...


根据你提供的代码,我发现在`load_columns()`方法中,你没有调用该方法来加载列数据。因此,你需要在`load_sheets()`方法末尾添加一行代码来调用`load_columns()`方法,以在选择工作表后加载列数据。

将以下代码添加到`load_sheets()`方法的末尾即可:
self.load_columns(workbook_path, sheet_name)

这样,当你选择工作表时,`load_columns()`方法将自动加载列数据到`source_col_combo`和`dest_col_combo`下拉框中。

修改后的`load_sheets()`方法如下所示:
def load_sheets(self, workbook_path):
    if not workbook_path:
        return
    workbook = openpyxl.load_workbook(filename=workbook_path)
    sheets = workbook.sheetnames
    self.sheet_combo.clear()
    self.sheet_combo.addItems(sheets)
    # 加载列数据
    sheet_name = self.sheet_combo.currentText()
    self.load_columns(workbook_path, sheet_name)

请尝试这个修改,并确保在选择工作簿和工作表后,源列下拉框会正确显示列名。如果问题仍然存在,请提供更多相关信息,以便我能进一步帮助你。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-3-19 17:17:26 | 显示全部楼层
FishC 发表于 2024-3-19 17:14
根据你提供的代码,我发现在`load_columns()`方法中,你没有调用该方法来加载列数据。因此,你需要在`l ...

这次能打开源列下拉框了。

但是格式列又打不开了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-19 17:17:48 | 显示全部楼层
凊风 发表于 2024-03-19 17:17
这次能打开源列下拉框了。

但是格式列又打不开了


根据你提供的代码和描述,我发现在`load_columns()`方法中,你没有正确地加载单元格格式数据到`cell_format_combo`下拉框中。你需要在该方法中添加代码来加载可用的单元格格式选项。

你可以使用`openpyxl.styles`模块中的`get_all_builtin_formats()`函数来获取内置的单元格格式列表,然后将它们添加到`cell_format_combo`下拉框中。修改后的`load_columns()`方法如下所示:
def load_columns(self, workbook_path, sheet_name):
    if not workbook_path or not sheet_name:
        return
        
    workbook = openpyxl.load_workbook(filename=workbook_path)
    sheet = workbook[sheet_name]  # 获取指定的工作表
    
    column_names = [column.value for column in sheet.iter_cols(min_row=1, max_row=1)]
    
    self.source_col_combo.clear()
    self.dest_col_combo.clear()
    
    for column_name in column_names:
        self.source_col_combo.addItem(column_name)
        self.dest_col_combo.addItem(column_name)
        
    self.cell_format_combo.clear()
    cell_formats = openpyxl.styles.cell_formats.get_all_builtin_formats()
    self.cell_format_combo.addItems(cell_formats)

这样,当选择工作簿和工作表后,你应该能够在下拉框中看到可用的单元格格式选项了。

请尝试这个修改,并确保在选择工作表后,单元格格式下拉框会正确显示可用的格式选项。如果问题仍然存在,请提供更多相关信息,以便我能进一步帮助你。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-3-19 17:20:49 | 显示全部楼层
FishC 发表于 2024-3-19 17:17
根据你提供的代码和描述,我发现在`load_columns()`方法中,你没有正确地加载单元格格式数据到`cell_fo ...

这样改了后,报错:
Traceback (most recent call last):
  File "D:\PycharmProjects\pythonProject\Xtt_xls\Txt_item.py", line 56, in select_workbook
    self.load_sheets(workbook_path)
  File "D:\PycharmProjects\pythonProject\Xtt_xls\Txt_item.py", line 67, in load_sheets
    self.load_columns(workbook_path, sheet_name)
  File "D:\PycharmProjects\pythonProject\Xtt_xls\Txt_item.py", line 76, in load_columns
    column_names = [column.value for column in sheet.iter_cols(min_row=1, max_row=1)]
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\PycharmProjects\pythonProject\Xtt_xls\Txt_item.py", line 76, in <listcomp>
    column_names = [column.value for column in sheet.iter_cols(min_row=1, max_row=1)]
                    ^^^^^^^^^^^^
AttributeError: 'tuple' object has no attribute 'value'
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-19 17:21:06 | 显示全部楼层
凊风 发表于 2024-03-19 17:20
这样改了后,报错:
Traceback (most recent call la ...


根据错误信息来看,问题出现在`column_names = self.source_col_combo.clear()`这行代码上。报错说'tuple'对象没有'value'属性。这意味着`self.source_col_combo.clear()`这个函数返回的是一个元组,而不是预期的列表。

为了解决这个问题,可以在调用`clear()`函数时将其返回值转换为列表类型。可以使用`list()`函数将元组转换为列表。修改后的代码如下所示:
column_names = list(self.source_col_combo.clear())
self.dest_col_combo.clear()

for column_name in column_names:
    self.source_col_combo.addItem(column_name)
    self.dest_col_combo.addItem(column_name)

请尝试这个修改,并查看是否能够解决报错问题。如果问题仍然存在,请提供完整的错误信息和相关的代码片段,以便我能够更好地帮助你。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-3-19 17:33:36 | 显示全部楼层
FishC 发表于 2024-3-19 17:21
根据错误信息来看,问题出现在`column_names = self.source_col_combo.clear()`这行代码上。报错说'tup ...

请问这段在哪里修改?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-19 17:33:51 | 显示全部楼层
凊风 发表于 2024-03-19 17:33
请问这段在哪里修改?


很抱歉,我之前的回答有误。我犯了个错误,关于清除复选框中的项,QComboBox控件并没有提供clear()方法。所以在这种情况下,我们需要使用其他方式来实现清空复选框中的项。以下是一个示例代码来清空QComboBox中的项:
self.source_col_combo.clear()
self.dest_col_combo.clear()

请确保你的代码中的`self.source_col_combo.clear()`和`self.dest_col_combo.clear()`部分与上述代码一致。希望这次的解答能够帮到你!如果还有其他问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-3-19 17:50:34 | 显示全部楼层
FishC 发表于 2024-3-19 17:33
很抱歉,我之前的回答有误。我犯了个错误,关于清除复选框中的项,QComboBox控件并没有提供clear()方法 ...

from PySide6.QtWidgets import QApplication, QFileDialog, QMessageBox, QPlainTextEdit, QLineEdit, QLabel, QVBoxLayout, QHBoxLayout, QWidget, QPushButton, QComboBox
from PySide6.QtGui import QTextCharFormat, QTextCursor, QColor
import openpyxl

class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('Excel文件内容转换')
        self.resize(500, 300)
        self.layout = QVBoxLayout()

        # 工作簿选择按钮和标签
        self.workbook_btn = QPushButton('选择工作簿')
        self.workbook_label = QLabel('工作簿:')

        # 工作表选择框
        self.sheet_label = QLabel('工作表:')
        self.sheet_combo = QComboBox()

        # 转换列选择框
        self.source_col_label = QLabel('源列:')
        self.source_col_combo = QComboBox()
        self.dest_col_label = QLabel('目标列:')
        self.dest_col_combo = QComboBox()

        # 单元格格式选择框
        self.cell_format_label = QLabel('单元格格式:')
        self.cell_format_combo = QComboBox()

        # 转换按钮
        self.convert_btn = QPushButton('转换')

        # 添加控件到布局中
        self.layout.addWidget(self.workbook_btn)
        self.layout.addWidget(self.workbook_label)
        self.layout.addWidget(self.sheet_label)
        self.layout.addWidget(self.sheet_combo)
        self.layout.addWidget(self.source_col_label)
        self.layout.addWidget(self.source_col_combo)
        self.layout.addWidget(self.dest_col_label)
        self.layout.addWidget(self.dest_col_combo)
        self.layout.addWidget(self.cell_format_label)
        self.layout.addWidget(self.cell_format_combo)
        self.layout.addWidget(self.convert_btn)

        self.setLayout(self.layout)

        # 绑定按钮点击事件
        self.workbook_btn.clicked.connect(self.select_workbook)
        self.convert_btn.clicked.connect(self.convert)

    def select_workbook(self):
        file_dialog = QFileDialog()
        workbook_path, _ = file_dialog.getOpenFileName(self, '选择工作簿')
        self.workbook_label.setText(f'工作簿: {workbook_path}')
        self.load_sheets(workbook_path)

    def load_sheets(self, workbook_path):
        if not workbook_path:
            return
        workbook = openpyxl.load_workbook(filename=workbook_path)
        sheets = workbook.sheetnames
        self.sheet_combo.clear()
        self.sheet_combo.addItems(sheets)
        # 加载列数据
        sheet_name = self.sheet_combo.currentText()
        self.load_columns(workbook_path, sheet_name)

    def load_columns(self, workbook_path, sheet_name):
        if not workbook_path or not sheet_name:
            return
        workbook = openpyxl.load_workbook(filename=workbook_path)
        sheet = workbook[sheet_name]  # 获取指定的工作表

        column_names = [column[0].value for column in sheet.iter_cols(min_row=1, max_row=1)]
        print(column_names)

        self.source_col_combo.clear()
        self.dest_col_combo.clear()

        for column_name in column_names:
            self.source_col_combo.addItem(column_name)
            self.dest_col_combo.addItem(column_name)

    def convert(self):
        workbook_path = self.workbook_label.text().split(': ')[1]
        sheet_name = self.sheet_combo.currentText()
        source_col = self.source_col_combo.currentText()
        dest_col = self.dest_col_combo.currentText()
        cell_format = self.cell_format_combo.currentText()

        # 打开工作簿
        try:
            workbook = openpyxl.load_workbook(filename=workbook_path)
        except Exception as e:
            QMessageBox.warning(self, '错误', f'打开工作簿失败:{str(e)}')
            return

        # 获取源列和目标列的索引
        try:
            source_col_index = self.get_column_index(source_col)
            dest_col_index = self.get_column_index(dest_col)
        except ValueError as e:
            QMessageBox.warning(self, '错误', str(e))
            return

        # 获取活动的工作表
        sheet = workbook[sheet_name]

        # 遍历行并转换格式
        for row in sheet.iter_rows(min_row=2, values_only=True):
            source_value = row[source_col_index - 1]

            # 执行转换操作,这里只是一个示例,你可以根据需要进行修改
            dest_value = str(source_value).upper()

            # 将转换结果写入目标列
            sheet.cell(row=row[0].row, column=dest_col_index).value = dest_value

            # 设置单元格格式
            cell = sheet.cell(row=row[0].row, column=dest_col_index)
            cell.number_format = cell_format

        # 保存转换后的文件
        try:
            workbook.save(filename=workbook_path)
        except Exception as e:
            QMessageBox.warning(self, '错误', f'保存工作簿失败:{str(e)}')
            return

        # 清空下拉框选择
        self.sheet_combo.clear()
        self.source_col_combo.clear()
        self.dest_col_combo.clear()
        self.cell_format_combo.clear()

        # 询问用户是否继续转换
        reply = QMessageBox.question(
            self, '询问', '是否继续转换?', QMessageBox.Yes | QMessageBox.No
        )
        if reply == QMessageBox.No:
            QApplication.quit()

    def get_column_index(self, column_name):
        if not column_name.isalpha():
            raise ValueError('列名必须由字母组成')

        index = 0
        for char in column_name:
            index = index * 26 + ord(char.upper()) - ord('A') + 1

        return index

app = QApplication([])
window = MainWindow()
window.show()
app.exec()

现在的问题是:“单元格格式”下拉框点击没有反应。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-19 17:50:56 | 显示全部楼层
凊风 发表于 2024-03-19 17:50
from PySide6.QtWidgets import QApplication, QFileD ...


在你的代码中,单元格格式下拉框没有绑定到任何方法上,所以点击它没有产生任何反应。为了使下拉框能够响应点击事件,你需要将它的`currentIndexChanged`信号连接到一个处理方法上。在该处理方法中,你可以获取选中的单元格格式,并进行相应的处理。以下是修改后的代码示例:
# 添加到 __init__ 方法中
self.cell_format_combo.currentIndexChanged.connect(self.handle_cell_format_changed)

# 增加一个新的方法 handle_cell_format_changed
def handle_cell_format_changed(self, index):
    cell_format = self.cell_format_combo.currentText()
    # 可以在这里添加处理选中单元格格式的代码

通过将`currentIndexChanged`信号连接到`handle_cell_format_changed`方法,当下拉框的选中项发生变化时,该方法将被触发。在`handle_cell_format_changed`方法中,你可以获取当前选中的单元格格式,并对其进行操作。请根据你的具体需求来完善`handle_cell_format_changed`方法中的代码。

希望这次的解答能够帮到你!如果还有其他问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-26 22:39

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表