Qt:如何连接“DialogClass1”的 QPushButton 来杀死“Class2”中的 QProcess?
Posted
技术标签:
【中文标题】Qt:如何连接“DialogClass1”的 QPushButton 来杀死“Class2”中的 QProcess?【英文标题】:Qt: How to connect a QPushButton of a "DialogClass1" to kill a QProcess in a "Class2"? 【发布时间】:2012-04-01 22:13:56 【问题描述】:我有代码:
void Processmethod()
QDialog *ProcessMessage = new QDialog;
// HOW TO CONNECT THE DIALOGS PUSHBUTTON TO KILL THE PROCESS called in processmethodONE() ?
Ui::DialogProcessMessage Dialog; //polymorphy
Dialog.setupUi(ProcessMessage);
ProcessMessage->setModal(true);
ProcessMessage->setAttribute(Qt::WA_DeleteOnClose);
ProcessMessage->show();
processmethodONE();
void processmethodONE()
QString ProcessCommand = "w8 " + blablubli";
Prozess.setWorkingDirectory(Path); //QProcess "Prozess" is globaly defined
Prozess.setStandardOutputFile(Path); //in my class
QEventLoop loop;
connect(&Prozess, SIGNAL(error(QProcess::ProcessError)), &loop, SLOT(quit()));
connect(&Prozess, SIGNAL(finished(int, QProcess::ExitStatus)), &loop, SLOT(quit()));
Prozess.start(ProcessCommand);
loop.exec();
QProcess::ExitStatus Status = Prozess.exitStatus();
if (Status == 0)
std::cout <<"Exit-Status: " << Status << " File created!" << std::endl;
else
std::cout << "Exit-Status: " << Status << " Error-Code: " << Prozess.error() << "Process failed!" << std::endl;
我想要做的是通过其中一个对话框按钮来杀死 QProcess“Prozess”。 “Ui::DialogProcessMessage”类无法编辑/指定,因为它是由 QtDesigner Ui-File 直接构建的类,因此在使用 QtDesigner 编辑 Ui-File 时将被覆盖。我该如何处理?问候
【问题讨论】:
避免本地事件循环。否则你将进入一个痛苦的世界。本地事件循环会导致各种重入问题(因为在执行时可能会发生任意事件,例如,有人可能会在循环仍在执行时触发 ProcessMethod() 和 processMethodOne()),最好通过不使用本地事件循环来避免这些问题。跨度> 我会让主 GUI 被对话框阻止,所以在进程运行时没有人会触发任何东西,除了中止进程是可能的。所以进入本地事件循环应该不是问题。:) @FrankOsterfeld:OP 从他的另一个问题中得到了使用本地事件循环的建议:***.com/questions/9956304/…。我个人也不同意这种做法。我认为它应该在通过信号完成时发出通知。 有什么优势?我尝试使用带有connect(&Prozess, SIGNAL(finished(int, QProcess::ExitStatus)), this, (SLOT(processmethodTWO)));
的 QProcess finished() 信号来启动以下方法,但它不起作用。你知道我的代码有什么问题吗?
Streight:您的连接线建议您在堆栈上创建 Prozess。如果你这样做,它将在方法结束时被销毁,即立即被销毁,因为没有阻塞的本地事件循环。尝试使 QProcess 成为局部成员变量 QProcess* m_prozess。
【参考方案1】:
执行此操作后:
Dialog.setupUi(ProcessMessage);
...ProcessMessage
现在拥有在Ui::DialogProcessMessage
中设计的所有小部件。您可以通过名称访问所有项目。
connect(ProcessMessage->pushButton, SIGNAL(clicked()), &loop, SLOT(quit()));
由于我实际上使用的是 PyQt,所以我可能对如何称呼孩子 ->
或 .
有误。但我相信你明白了。
通常你会从一开始就设计你的类来继承 Ui 类,这样你所要做的就是在你的构造函数中说setupUi(this)
。
目前,您的 processOne 函数似乎没有对对话框的引用,因此您可能必须将其作为 arg 传递。或者更早将其直接连接到进程:
connect(ProcessMessage->pushButton, SIGNAL(clicked()), &Prozess, SLOT(kill()));
【讨论】:
“通常你会从一开始就设计你的类来继承 Ui 类,所以你所要做的就是在你的构造函数中说 setupUi(this) 。”并非如此,如今的常见模式是将 UI 对象作为小部件的成员。遵循组合优于继承规则。 我现在尝试在Dialog.setupUi(ProcessMessage);
之后使用您建议的连接方法。使用 connect(ProcessMessage->pushButton, SIGNAL(clicked()), &Prozess, SLOT(kill()));
时出现错误:Form.cpp: In member function 'int subclassGUI Processmethod() ": Form.cpp: 5152:29: error: class QDialog has no member named 'pushButton' make: *** [Form.o] Error 1
,使用 connect(ProcessMessage->pushButton, SIGNAL(clicked()), &loop, SLOT(quit()));
时出现相同的错误加上 Form.cpp: 5151:80: error: 'loop' was not declared in this scope
这对我来说是合乎逻辑的。有什么想法吗?
是的,你不能按照我输入的内容进行操作。您需要尝试将其应用于您自己的代码。从你的 UI 设计中你自己的 QPushButton 是什么?我只是随机选择了pushButton
。另外,就像我说的那样,您可能必须执行第二个示例,因为您的 QEventLoop 对象与对话框不在同一范围内。它基本上就是您设置事物的方式。
@FrankOsterfeld:这在哪里被称为新的通用模式?
大声笑,我肯定用了自己的 pushButtons 名称而不是“pushButton”——我知道这只是为了举例。问题是编译器显然没有找到我的“pushButton”->似乎他甚至没有在我自己的 Ui::DialogProcessMessage 类中搜索,只是在 QDialog 类中。可能是错的,但在我看来就是这样。【参考方案2】:
解决办法就是使用
connect(Dialog.pushButtonAbort, SIGNAL(clicked()), &Prozess, SLOT(kill()));
可能是这样,因为在这种情况下Dialog是“主要对象”,而对象“ProcessMessage”只是用来指定它。从 QDeveloper 论坛得到这个。
感谢支持人员。
【讨论】:
信号应该读成SIGNAL(clicked())
吗?很高兴您找到了解决方案!以上是关于Qt:如何连接“DialogClass1”的 QPushButton 来杀死“Class2”中的 QProcess?的主要内容,如果未能解决你的问题,请参考以下文章