我正在为Windows平台开发一个使用Qt 4.6,CMake 2.8和Visual Studio 2008的大型项目.
到构建系统为止,这都是标准的东西:我正在使用CMake的QT4_WRAP_CPP宏从头文件生成moc文件,然后将其链接到add_executable命令中的最终可执行文件.一切都按预期工作.
这种设置的唯一限制是我无法Q_OBJECT在.cpp文件中定义小部件或帮助程序 .对于应该出现在它们使用位置旁边的小型特定于上下文的助手类,这将非常方便.
我试图将整个源文件列表(.h和.cpp)传递给QT4_WRAP_CPP,而不仅仅是头文件,但这不起作用(链接失败,因为一些moc相关的符号是未定义的).
我认为问题是,对于给定的文件对foo.h和foo.cpp,QT4_WRAP_CPP宏将在同一目录中生成相同的moc文件(moc_foo.cxx),显然这意味着第一个文件将被覆盖第二个,结果符号将在链接时丢失.
有没有办法解决或解决这个问题?例如,我试图为表单的foo.cpp添加一个特定的规则
QT4_GENERATE_MOC(directory/foo.cpp directory/foo.moc)
Run Code Online (Sandbox Code Playgroud)
然后添加
#include "foo.moc"
Run Code Online (Sandbox Code Playgroud)
在foo.cpp的末尾.我认为这应该可以工作,但是唉,Visual Studio只允许每个文件一个构建规则,而.cpp文件已经有一个构建规则(编译到目标文件),所以这种方法不起作用,至少使用Visual Studio.
我的另一个想法是创建一个新的宏,比如QT4_WRAP_CPP_WITH_PREFIX,基于QT4_WRAP_CPP(在share/cmake-2.8/Modules/Qt4Macros.cmake中定义),它将采用额外的前缀参数并将此前缀添加到生成的moc中文件.这样,我会调用QT4_WRAP_CPP_WITH_PREFIX两次,一次用于.h文件,一次用于.cpp文件,用不同的前缀.我只是不喜欢这种方法,我会搞乱CMake的Qt支持的内部,而不是使用公共API.
有什么好主意吗?
Cheerz,Franz
由于该QObject文档和许多其他人解释,一个QObject有身份,从而隐藏了它的拷贝构造函数和赋值操作符.
但是,我并非源于QObject其动态属性功能或信号/插槽功能.我只想要反思或访问的能力Foo::staticMetaObject.
class Foo : public QObject {
Q_OBJECT
Q_ENUMS(Color)
public:
enum Color { Blue, Red, Pink };
private:
Color color;
};
Q_DECLARE_METATYPE(Foo::Color)
Run Code Online (Sandbox Code Playgroud)
然后,我无法复制Foo:
Foo a;
Foo b;
a = b;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,允许复制和分配的最佳方法是什么?我是否绝对需要编写复制构造函数和赋值运算符?他们会是什么样子?反思仍然有效吗?
我遇到一些奇怪的行为,其中一个属性可以直接通过访问QObject的property功能,而不是通过JavaScript:
#include <QApplication>
#include <QDebug>
#include <QScriptEngine>
#include <QStringList>
class Item : public QObject
{
Q_OBJECT
public:
Q_PROPERTY(int typeId READ typeId)
Q_PROPERTY(int usesLeft READ usesLeft)
Item() :
mTypeId(0),
mUsesLeft(-1)
{
}
Item(int typeId) :
mTypeId(typeId)
{
if (typeId != 0) {
mUsesLeft = 5;
}
}
Item(const Item &item) :
QObject(0)
{
*this = item;
}
~Item()
{
}
Item& operator=(const Item& rhs)
{
mTypeId = rhs.mTypeId;
mUsesLeft = rhs.mUsesLeft;
return *this;
}
int typeId() const …Run Code Online (Sandbox Code Playgroud) 如果给出类型I的声明不包含Q_OBJECT宏,我有一些有趣的需要显示编译错误.我找到了一种不好的方法.实际上它重复了Qt开发人员做同样伎俩的想法:
template<typename T>
void checkForQObjectMacro()
{
reinterpret_cast<T *>(0)->qt_check_for_QOBJECT_macro(*reinterpret_cast<T *>(0));
}
Run Code Online (Sandbox Code Playgroud)
这很好用,但它确实给出了奇怪的错误信息.我想展示一条可读的消息.一种方法是使用static_assert构造.但我不知道如何实现Q_OBJECT宏存在的静态验证条件.也许有人可以提出一个漂亮的黑客?也非常感谢任何想法.
我使用setProperty函数将动态属性设置为object.
但我想在其他地方检查创建的属性是否存在.
我做了什么:
设置属性时:
QString fileDlg = QFileDialog::getOpenFileName(this, "Open File", "F://","Text Files(*.txt)");
QWidget *widget = new QWidget(this);
QMdiSubWindow *mdiWindows = ui->mdiArea->addSubWindow(widget);
mdiWindows->setProperty("filePath", fileDlg);
Run Code Online (Sandbox Code Playgroud)
检查属性是否存在时:
QMdiSubWindow *activeWindow = ui->mdiArea->activeSubWindow();
if(activeWindow->property("filePath") == true){
// code here
}
Run Code Online (Sandbox Code Playgroud) 我正在编写一个每10 mS发送一个UDP帧的程序.这是我的程序应该如何工作:
我有一个client class:
//Constructor
clientSupervision::clientSupervision()
{
}
void clientSupervision::sendDataUDP(){
//Create a frame and send it
...
}
void clientSupervision::sendDataUDPTimer(int timer){
QTimer *tempsEnvoieTrameSupervision = new QTimer();//Create a timer
tempsEnvoieTrameSupervision->setInterval(timer);//Set the interval
//Mise en place des connections
QObject::connect (tempsEnvoieTrameSupervision,SIGNAL (timeout()),this, SLOT (envoiTrameSupervision())); //Connect the timer to the function
tempsEnvoieTrameSupervision->start();// Start the timer
}
//Call sendDataUDP
void clientSupervision::envoiTrameSupervision(){
std::cout << "Envoi de la trame de supervision";
sendDataUDP();
}
Run Code Online (Sandbox Code Playgroud)
我的头文件clienSupervision.h:
#ifndef CLIENTSUPERVISION_H
#define CLIENTSUPERVISION_H
#include <winsock2.h> // pour les …Run Code Online (Sandbox Code Playgroud) 在这个问题中,我能够适应这种QObject方法
QMetaObject::Connection
QObject::connect(const QObject * sender,
const char * signal,
const QObject * receiver,
const char * method,
Qt::ConnectionType type = Qt::AutoConnection)
Run Code Online (Sandbox Code Playgroud)
转换为接受a QSharedPointer而不是a QObject*作为其第一个参数的变体:
template<class T> QMetaObject::Connection
connect_from_pointer(const QSharedPointer<T> &sender,
const char *signal,
const QObject *receiver,
const char *method,
Qt::ConnectionType type = Qt::AutoConnection)
Run Code Online (Sandbox Code Playgroud)
我想对带有函数指针的版本做同样的事情,
QMetaObject::Connection
QObject::connect(const QObject * sender,
PointerToMemberFunction signal,
const QObject * receiver,
PointerToMemberFunction method,
Qt::ConnectionType type = Qt::AutoConnection)
Run Code Online (Sandbox Code Playgroud)
但我无法弄清楚PointerToMemberFunction它的定义是什么或在哪里定义!这是什么类型的?
我使用Python 3.4与Pyside 1.2.4和PyQt 4.8.7,当我尝试将信号连接到插槽时,它说:
'PySide.QtCore.Signal'对象没有属性'connect'
我正在使用MVC:
模型:
from PySide.QtCore import Signal
class Model(object):
def __init__(self):
self.updateProgress = Signal(int)
Run Code Online (Sandbox Code Playgroud)
控制器:
class Controller(QWidget):
"""
MVC Pattern: Represents the controller class
"""
def __init__(self, parent=None):
super().__init__(parent)
self.model = Model()
self.model.updateProgress.connect(self.setProgress)
Run Code Online (Sandbox Code Playgroud)
当我在Pycharm中查找Class时,通过按住CTRL并单击Signal类,它看起来如下所示:
class Signal(object):
""" Signal """
def __call__(self, *args, **kwargs): # real signature unknown
""" Call self as a function. """
pass
def __getitem__(self, *args, **kwargs): # real signature unknown
""" Return self[key]. """
pass
def __init__(self, *args, **kwargs): # real signature unknown …Run Code Online (Sandbox Code Playgroud) 我想在QObjects不修改其他信号/插槽行为的情况下,一般地和暂时地阻止两者之间的信号,并且不知道它们的上下文.
像QObject :: blockSignals(bool)之类的东西,但只在两个之间起作用QObjects.
也就是说,实现以下SignalBlocker::blockSignals(bool)功能:
class SignalBlocker {
public:
SignalBlocker(QObject *sender, QObject *receiver) :
mSender(sender), mReceiver(receiver) {}
void blockSignals(bool block);
private:
QObject *mSender, *mReceiver;
}
Run Code Online (Sandbox Code Playgroud)
通过断开和重新连接对象是可能的,但首先必须存储信号/时隙列表.似乎自省方法不足够强大来实现这一(我看了看QMetaObject,并QSignalSpy没有成功).
我正在使用Python 3和PyQt5开发一个小型图形应用程序.在我使用的第一台计算机上,只安装了PyQt5,我的代码中的所有内容都很好.但是当我想在我的其他笔记本电脑上运行我的代码时,安装了PyQt4和PyQt5,我收到以下错误:
RuntimeError: the PyQt5.QtCore and PyQt4.QtCore modules both wrap the QObject class
Run Code Online (Sandbox Code Playgroud)
Python解释器将错误定位在从主文件调用的文件"ViewWindow.py"中.
因为我在这台笔记本电脑上有PyQt4和PyQt5,并且因为我无法卸载PyQt4(这太简单了......),我想知道是否有可能强制使用PyQt5.QtCore或其他东西来避免这个问题.我在这台笔记本电脑上的配置:Debian 8,Python3.4,PyQt4和5(没有特殊配置,从Debian repos安装),IDE = Spyder.
我把我的文件有第一线main.py和ViewWindow.py.
# main.py
import sys
import sqlite3
import ViewWindow
from DataWindow import DataWindow
from PyQt5.QtCore import QObject # I tried adding this line, but nothing changed...
from PyQt5.QtWidgets import (QApplication,
QWidget,
QGridLayout,
QHBoxLayout,
QLabel,
QLineEdit,
QPushButton,
QTextEdit,
QVBoxLayout
)
class MainWindow(QWidget):
# Some cool stuff
# ViewWindow.py
import sys
import sqlite3
from PyQt5.QtCore import QObject # same …Run Code Online (Sandbox Code Playgroud) qobject ×10
qt ×8
c++ ×5
python ×2
qtcore ×2
c++11 ×1
cmake ×1
javascript ×1
properties ×1
pyqt4 ×1
pyqt5 ×1
pyside ×1
python-3.x ×1
qt-signals ×1
qt5 ×1
qtscript ×1
signals ×1
slot ×1